Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / util / BitArray.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.util;
19
20 import java.util.Arrays;
21 import java.util.BitSet;
22
23 /**
24  * Faster version of BitSet for fixed size.
25  */
26 public class BitArray {
27   public final int length;
28   final byte[] data;
29   
30   public BitArray(int len) {
31     length = len;
32     data = new byte[(len + 7) >> 3];
33   }
34
35   public void fromBitSet(BitSet in) {
36     int max = Math.min(data.length, (in.length() + 7) >> 3);
37     int i;
38     for (i = 0; i < max; i++) {
39       int j = i << 3;
40       data[i] = (byte)
41         ((in.get(j + 0) ? 1 : 0) |
42          (in.get(j + 1) ? 2 : 0) |
43          (in.get(j + 2) ? 4 : 0) |
44          (in.get(j + 3) ? 8 : 0) |
45          (in.get(j + 4) ? 16 : 0) |
46          (in.get(j + 5) ? 32 : 0) |
47          (in.get(j + 6) ? 64 : 0) |
48          (in.get(j + 7) ? 128 : 0));
49     }
50     Arrays.fill(data, max, data.length, (byte) 0);
51   }
52
53   public final void set(int idx, boolean val) {
54     if (idx >= length) throw new ArrayIndexOutOfBoundsException("" + idx + " >= " + length);
55     if (val) {
56       data[idx >> 3] |= (1 << (idx & 7));
57     } else {
58       data[idx >> 3] &= ~(1 << (idx & 7));
59     }
60   }
61
62   public final void set(int idx, int val) {
63     set(idx, val != 0);
64   }
65   
66   public final void set(int idx) {
67     if (idx >= length) throw new ArrayIndexOutOfBoundsException("" + idx + " >= " + length);
68     data[idx >> 3] |= (1 << (idx & 7));
69   }
70
71   public final void clear(int idx) {
72     if (idx >= length) throw new ArrayIndexOutOfBoundsException("" + idx + " >= " + length);
73     data[idx >> 3] &= ~(1 << (idx & 7));
74   }
75
76   public final void setAll() {
77     Arrays.fill(data, (byte) 0xff);
78     cleanup();
79   }
80
81   public final void clearAll() {
82     Arrays.fill(data, (byte) 0);
83   }
84   
85   public final void invert() {
86     int i;
87     for (i = 0; i < data.length; i++) {
88       data[i] = (byte) ~ data[i];
89     }
90     cleanup();
91   }
92   
93   // to keep all unused bits at 0
94   final void cleanup() {
95     if ((length & 7) != 0) {
96       int idx = data.length - 1;
97       data[idx] &= ~(0xff << (length & 7));
98     }
99   }
100   
101   public final boolean get(int idx) {
102     int a = idx >> 3;
103     return a < data.length && a >= 0 && (data[a] & (1 << (idx & 7))) != 0;
104   }
105   
106   @Override
107   public int hashCode() {
108     return Arrays.hashCode(data);
109   }
110   
111   @Override
112   public boolean equals(Object o) {
113     if (this == o) return true;
114     if (! (o instanceof BitArray)) return false;
115     byte[] thatData = ((BitArray)o).data;
116     byte[] thisData = this.data;
117     return Arrays.equals(thisData, thatData);
118   }
119   
120   public static final BitArray empty = new BitArray(0);
121 }