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