001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: BitString.java,v $ 023 Revision 1.3 2004/05/05 21:22:45 markl 024 Comment header updates. 025 026 Revision 1.2 2004/03/20 06:53:36 markl 027 new class 028 ---------------------------------------------------------------------------- 029*/ 030 031package kiwi.util; 032 033/** 034 * A class representing a string of bits, useful for maintaining a set of flags 035 * in compact form. 036 * 037 * @author Mark Lindner 038 * @since Kiwi 2.0 039 */ 040 041public final class BitString 042 { 043 /** The bit string data. */ 044 protected byte array[]; 045 /** The length of the bit string, in bits. */ 046 protected int length; 047 048 /** Construct a new <code>BitString</code> of the specified length. 049 * 050 * @param length The length. 051 */ 052 053 public BitString(int length) 054 { 055 if(length < 0) 056 throw(new IllegalArgumentException()); 057 058 this.length = length; 059 060 int len = length / 8; 061 if((length % 8) > 0) 062 len++; 063 064 array = new byte[len]; 065 066 clearAll(); 067 } 068 069 /** Construct a new <code>BitString</code> of the specified length, with the 070 * bits initialized to either the on or off position. 071 * 072 * @param length The length. 073 * @param setInitially A flag indicating whether all bits should be initially 074 * set or cleared. 075 */ 076 077 public BitString(int length, boolean setInitially) 078 { 079 this(length); 080 081 if(setInitially) 082 setAll(); 083 } 084 085 /** Get the length of the <code>BitString</code>. */ 086 087 public int getLength() 088 { 089 return(length); 090 } 091 092 /** Clear all of the bits. */ 093 094 public void clearAll() 095 { 096 for(int i = 0; i < array.length; i++) 097 array[i] = 0; 098 } 099 100 /** Set all of the bits. */ 101 102 public void setAll() 103 { 104 for(int i = 0; i < array.length; i++) 105 array[i] = ~0; 106 } 107 108 /** Set the specified bit. 109 * 110 * @param bit The index of the bit to set. 111 * @throws java.lang.IllegalArgumentException If the bit index is out of 112 * range. 113 */ 114 115 public void set(int bit) 116 { 117 if(bit < 0) 118 throw(new IllegalArgumentException()); 119 120 int _byte = bit / 8; 121 int _bit = bit % 8; 122 123 if(_byte >= array.length) 124 throw(new IllegalArgumentException()); 125 126 array[_byte] |= (1 << _bit); 127 } 128 129 /** Test the specified bit. 130 * 131 * @param bit The index of the bit to test. 132 * @return <code>true</code> if the bit is set, <code>false</code> 133 * otherwise. 134 * @throws java.lang.IllegalArgumentException If the bit index is out of 135 * range. 136 */ 137 138 public boolean isSet(int bit) 139 { 140 if(bit < 0) 141 throw(new IllegalArgumentException()); 142 143 int _byte = bit / 8; 144 int _bit = bit % 8; 145 146 if(_byte >= array.length) 147 throw(new IllegalArgumentException()); 148 149 return((array[_byte] & (1 << _bit)) != 0); 150 } 151 152 /** Test the specified bit. 153 * 154 * @param bit The index of the bit to test. 155 * @return <code>true</code> if the bit is cleared, <code>false</code> 156 * otherwise. 157 * @throws java.lang.IllegalArgumentException If the bit index is out of 158 * range. 159 */ 160 161 public boolean isClear(int bit) 162 { 163 return(! isSet(bit)); 164 } 165 166 /** Clear the specified bit. 167 * 168 * @param bit The index of the bit to clear. 169 * @throws java.lang.IllegalArgumentException If the bit index is out of 170 * range. 171 */ 172 173 public void clear(int bit) 174 { 175 if(bit < 0) 176 throw(new IllegalArgumentException()); 177 178 int _byte = bit / 8; 179 int _bit = bit % 8; 180 181 if(_byte >= array.length) 182 throw(new IllegalArgumentException()); 183 184 array[_byte] &= ~(1 << _bit); 185 } 186 187 /** Compare this <code>BitString</code> to another. The method 188 * returns <code>true</code> if the bits that are set in this 189 * <code>BitString</code> are also set in the other 190 * <code>BitString</code>. (This is not a test for equality; to test 191 * if two <code>BitStrings</code> have exactly the same bits set, 192 * use <code>equals()</code>.) 193 * 194 * @param other The <code>BitString</code> to compare against. 195 * @return <code>true</code> for a match, <code>false</code> otherwise. 196 */ 197 198 public boolean compareTo(BitString other) 199 { 200 if(length != other.length) 201 return(false); 202 203 boolean r = false; 204 205 for(int i = 0; i < array.length; i++) 206 { 207 r |= ((array[i] & other.array[i]) != array[i]); 208 } 209 210 return(r); 211 } 212 213 /** Determine if this object is identical to another object. */ 214 215 public boolean equals(Object other) 216 { 217 if(!(other instanceof BitString)) 218 return(false); 219 220 BitString otherbs = (BitString)other; 221 222 if(otherbs.length != length) 223 return(false); 224 225 for(int i = 0; i < length; i++) 226 if(otherbs.array[i] != array[i]) 227 return(false); 228 229 return(true); 230 } 231 232 /** Produce a string representation of the object. */ 233 234 public String toString() 235 { 236 StringBuffer sb = new StringBuffer(); 237 238 int _byte = 0; 239 int _bit = 0; 240 241 for(int i = 0; i < length; i++) 242 { 243 sb.append(((array[_byte] & (1 << _bit)) == 0) ? '0' : '1'); 244 _bit++; 245 if(_bit == 8) 246 { 247 _byte++; 248 _bit = 0; 249 } 250 } 251 252 return(sb.toString()); 253 } 254 255 } 256 257/* end of source file */