1 /***
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.codehaus.activemq.util;
19
20 import java.io.DataInput;
21 import java.io.DataOutput;
22 import java.io.IOException;
23
24 /***
25 * Simple BitArray to enable setting multiple boolean values efficently Used instead of BitSet because BitSet does not
26 * allow for efficent serialization.
27 * Will store up to 64 boolean values
28 *
29 * @version $Revision: 1.3 $
30 */
31 public class BitArray {
32 static final int LONG_SIZE = 64;
33 static final int INT_SIZE = 32;
34 static final int SHORT_SIZE = 16;
35 static final int BYTE_SIZE = 8;
36 private static final long[] BIT_VALUES = {0x0000000000000001L, 0x0000000000000002L, 0x0000000000000004L,
37 0x0000000000000008L, 0x0000000000000010L, 0x0000000000000020L, 0x0000000000000040L, 0x0000000000000080L,
38 0x0000000000000100L, 0x0000000000000200L, 0x0000000000000400L, 0x0000000000000800L, 0x0000000000001000L,
39 0x0000000000002000L, 0x0000000000004000L, 0x0000000000008000L, 0x0000000000010000L, 0x0000000000020000L,
40 0x0000000000040000L, 0x0000000000080000L, 0x0000000000100000L, 0x0000000000200000L, 0x0000000000400000L,
41 0x0000000000800000L, 0x0000000001000000L, 0x0000000002000000L, 0x0000000004000000L, 0x0000000008000000L,
42 0x0000000010000000L, 0x0000000020000000L, 0x0000000040000000L, 0x0000000080000000L, 0x0000000100000000L,
43 0x0000000200000000L, 0x0000000400000000L, 0x0000000800000000L, 0x0000001000000000L, 0x0000002000000000L,
44 0x0000004000000000L, 0x0000008000000000L, 0x0000010000000000L, 0x0000020000000000L, 0x0000040000000000L,
45 0x0000080000000000L, 0x0000100000000000L, 0x0000200000000000L, 0x0000400000000000L, 0x0000800000000000L,
46 0x0001000000000000L, 0x0002000000000000L, 0x0004000000000000L, 0x0008000000000000L, 0x0010000000000000L,
47 0x0020000000000000L, 0x0040000000000000L, 0x0080000000000000L, 0x0100000000000000L, 0x0200000000000000L,
48 0x0400000000000000L, 0x0800000000000000L, 0x1000000000000000L, 0x2000000000000000L, 0x4000000000000000L,
49 0x8000000000000000L};
50 private long bits;
51 private int length;
52
53 /***
54 * @return the length of bits set
55 */
56 public int length() {
57 return length;
58 }
59
60 /***
61 * @return the long containing the bits
62 */
63 public long getBits() {
64 return bits;
65 }
66
67 /***
68 * set the boolean value at the index
69 *
70 * @param index
71 * @param flag
72 * @return the old value held at this index
73 */
74 public boolean set(int index, boolean flag) {
75 length = Math.max(length, index + 1);
76 boolean oldValue = (bits & BIT_VALUES[index]) != 0;
77 if (flag) {
78 bits |= BIT_VALUES[index];
79 }
80 else if (oldValue) {
81 bits &= ~(BIT_VALUES[index]);
82 }
83 return oldValue;
84 }
85
86 /***
87 * @param index
88 * @return the boolean value at this index
89 */
90 public boolean get(int index) {
91 return (bits & BIT_VALUES[index]) != 0;
92 }
93
94 /***
95 * write the bits to an output stream
96 *
97 * @param dataOut
98 * @throws IOException
99 */
100 public void writeToStream(DataOutput dataOut) throws IOException {
101 dataOut.writeByte(length);
102 if (length <= BYTE_SIZE) {
103 dataOut.writeByte((int) bits);
104 }
105 else if (length <= SHORT_SIZE) {
106 dataOut.writeShort((short) bits);
107 }
108 else if (length <= INT_SIZE) {
109 dataOut.writeInt((int) bits);
110 }
111 else {
112 dataOut.writeLong(bits);
113 }
114 }
115
116 /***
117 * read the bits from an input stream
118 *
119 * @param dataIn
120 * @throws IOException
121 */
122 public void readFromStream(DataInput dataIn) throws IOException {
123 length = dataIn.readByte();
124 if (length <= BYTE_SIZE) {
125 bits = (long) dataIn.readByte();
126 }
127 else if (length <= SHORT_SIZE) {
128 bits = (long) dataIn.readShort();
129 }
130 else if (length <= INT_SIZE) {
131 bits = (int) dataIn.readInt();
132 }
133 else {
134 bits = dataIn.readLong();
135 }
136 }
137 }