001 /** 002 * 003 * Copyright 2004 Protique Ltd 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 **/ 018 package org.activemq.util; 019 020 import java.io.DataInput; 021 import java.io.DataOutput; 022 import java.io.IOException; 023 024 /** 025 * Simple BitArray to enable setting multiple boolean values efficently Used instead of BitSet because BitSet does not 026 * allow for efficent serialization. 027 * Will store up to 64 boolean values 028 * 029 * @version $Revision: 1.1.1.1 $ 030 */ 031 public class BitArray { 032 static final int LONG_SIZE = 64; 033 static final int INT_SIZE = 32; 034 static final int SHORT_SIZE = 16; 035 static final int BYTE_SIZE = 8; 036 private static final long[] BIT_VALUES = {0x0000000000000001L, 0x0000000000000002L, 0x0000000000000004L, 037 0x0000000000000008L, 0x0000000000000010L, 0x0000000000000020L, 0x0000000000000040L, 0x0000000000000080L, 038 0x0000000000000100L, 0x0000000000000200L, 0x0000000000000400L, 0x0000000000000800L, 0x0000000000001000L, 039 0x0000000000002000L, 0x0000000000004000L, 0x0000000000008000L, 0x0000000000010000L, 0x0000000000020000L, 040 0x0000000000040000L, 0x0000000000080000L, 0x0000000000100000L, 0x0000000000200000L, 0x0000000000400000L, 041 0x0000000000800000L, 0x0000000001000000L, 0x0000000002000000L, 0x0000000004000000L, 0x0000000008000000L, 042 0x0000000010000000L, 0x0000000020000000L, 0x0000000040000000L, 0x0000000080000000L, 0x0000000100000000L, 043 0x0000000200000000L, 0x0000000400000000L, 0x0000000800000000L, 0x0000001000000000L, 0x0000002000000000L, 044 0x0000004000000000L, 0x0000008000000000L, 0x0000010000000000L, 0x0000020000000000L, 0x0000040000000000L, 045 0x0000080000000000L, 0x0000100000000000L, 0x0000200000000000L, 0x0000400000000000L, 0x0000800000000000L, 046 0x0001000000000000L, 0x0002000000000000L, 0x0004000000000000L, 0x0008000000000000L, 0x0010000000000000L, 047 0x0020000000000000L, 0x0040000000000000L, 0x0080000000000000L, 0x0100000000000000L, 0x0200000000000000L, 048 0x0400000000000000L, 0x0800000000000000L, 0x1000000000000000L, 0x2000000000000000L, 0x4000000000000000L, 049 0x8000000000000000L}; 050 private long bits; 051 private int length; 052 053 /** 054 * @return the length of bits set 055 */ 056 public int length() { 057 return length; 058 } 059 060 /** 061 * @return the long containing the bits 062 */ 063 public long getBits() { 064 return bits; 065 } 066 067 /** 068 * set the boolean value at the index 069 * 070 * @param index 071 * @param flag 072 * @return the old value held at this index 073 */ 074 public boolean set(int index, boolean flag) { 075 length = Math.max(length, index + 1); 076 boolean oldValue = (bits & BIT_VALUES[index]) != 0; 077 if (flag) { 078 bits |= BIT_VALUES[index]; 079 } 080 else if (oldValue) { 081 bits &= ~(BIT_VALUES[index]); 082 } 083 return oldValue; 084 } 085 086 /** 087 * @param index 088 * @return the boolean value at this index 089 */ 090 public boolean get(int index) { 091 return (bits & BIT_VALUES[index]) != 0; 092 } 093 094 /** 095 * reset all the bit values to false 096 */ 097 public void reset(){ 098 bits = 0; 099 } 100 101 /** 102 * reset all the bits to the value supplied 103 * @param bits 104 */ 105 public void reset(long bits){ 106 this.bits = bits; 107 } 108 109 /** 110 * write the bits to an output stream 111 * 112 * @param dataOut 113 * @throws IOException 114 */ 115 public void writeToStream(DataOutput dataOut) throws IOException { 116 dataOut.writeByte(length); 117 if (length <= BYTE_SIZE) { 118 dataOut.writeByte((int) bits); 119 } 120 else if (length <= SHORT_SIZE) { 121 dataOut.writeShort((short) bits); 122 } 123 else if (length <= INT_SIZE) { 124 dataOut.writeInt((int) bits); 125 } 126 else { 127 dataOut.writeLong(bits); 128 } 129 } 130 131 /** 132 * read the bits from an input stream 133 * 134 * @param dataIn 135 * @throws IOException 136 */ 137 public void readFromStream(DataInput dataIn) throws IOException { 138 length = dataIn.readByte(); 139 if (length <= BYTE_SIZE) { 140 bits = (long) dataIn.readByte(); 141 } 142 else if (length <= SHORT_SIZE) { 143 bits = (long) dataIn.readShort(); 144 } 145 else if (length <= INT_SIZE) { 146 bits = (int) dataIn.readInt(); 147 } 148 else { 149 bits = dataIn.readLong(); 150 } 151 } 152 }