1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * The Apache Software License, Version 1.1 7 * 8 * 9 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 10 * reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * 3. The end-user documentation included with the redistribution, 25 * if any, must include the following acknowledgment: 26 * "This product includes software developed by the 27 * Apache Software Foundation (http://www.apache.org/)." 28 * Alternately, this acknowledgment may appear in the software itself, 29 * if and wherever such third-party acknowledgments normally appear. 30 * 31 * 4. The names "Xerces" and "Apache Software Foundation" must 32 * not be used to endorse or promote products derived from this 33 * software without prior written permission. For written 34 * permission, please contact apache@apache.org. 35 * 36 * 5. Products derived from this software may not be called "Apache", 37 * nor may "Apache" appear in their name, without prior written 38 * permission of the Apache Software Foundation. 39 * 40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 42 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 43 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 47 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 48 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This software consists of voluntary contributions made by many 55 * individuals on behalf of the Apache Software Foundation and was 56 * originally based on software copyright (c) 1999, International 57 * Business Machines, Inc., http://www.apache.org. For more 58 * information on the Apache Software Foundation, please see 59 * <http://www.apache.org/>. 60 */ 61 62 package com.sun.org.apache.xerces.internal.impl.dtd.models; 63 64 65 /** 66 * This class is a very simple bitset class. The DFA content model code needs 67 * to support a bit set, but the java BitSet class is way, way overkill. Our 68 * bitset never needs to be expanded after creation, hash itself, etc... 69 * 70 * Since the vast majority of content models will never require more than 64 71 * bits, and since allocation of anything in Java is expensive, this class 72 * provides a hybrid implementation that uses two ints for instances that use 73 * 64 bits or fewer. It has a byte array reference member which will only be 74 * used if more than 64 bits are required. 75 * 76 * Note that the code that uses this class will never perform operations 77 * on sets of different sizes, so that check does not have to be made here. 78 * 79 * @xerces.internal 80 * 81 */ 82 // made this class public so it can be accessed by 83 // the XS content models from the schema package -neilg. 84 public class CMStateSet 85 { 86 // ------------------------------------------------------------------- 87 // Constructors 88 // ------------------------------------------------------------------- 89 public CMStateSet(int bitCount) 90 { 91 // Store the required bit count and insure its legal 92 fBitCount = bitCount; 93 if (fBitCount < 0) 94 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 95 96 // 97 // See if we need to allocate the byte array or whether we can live 98 // within the 64 bit high performance scheme. 99 // 100 if (fBitCount > 64) 101 { 102 fByteCount = fBitCount / 8; 103 if (fBitCount % 8 != 0) 104 fByteCount++; 105 fByteArray = new byte[fByteCount]; 106 } 107 108 // Init all the bits to zero 109 zeroBits(); 110 } 111 112 113 // ------------------------------------------------------------------- 114 // Public inherited methods 115 // ------------------------------------------------------------------- 116 public String toString() 117 { 118 StringBuffer strRet = new StringBuffer(); 119 try 120 { 121 strRet.append("{"); 122 for (int index = 0; index < fBitCount; index++) 123 { 124 if (getBit(index)) 125 strRet.append(" " + index); 126 } 127 strRet.append(" }"); 128 } 129 130 catch(RuntimeException exToCatch) 131 { 132 // 133 // We know this won't happen but we have to catch it to avoid it 134 // having to be in our 'throws' list. 135 // 136 } 137 return strRet.toString(); 138 } 139 140 141 // ------------------------------------------------------------------- 142 // Package final methods 143 // ------------------------------------------------------------------- 144 // the XS content models from the schema package -neilg. 145 public final void intersection(CMStateSet setToAnd) 146 { 147 if (fBitCount < 65) 148 { 149 fBits1 &= setToAnd.fBits1; 150 fBits2 &= setToAnd.fBits2; 151 } 152 else 153 { 154 for (int index = fByteCount - 1; index >= 0; index--) 155 fByteArray[index] &= setToAnd.fByteArray[index]; 156 } 157 } 158 159 public final boolean getBit(int bitToGet) 160 { 161 if (bitToGet >= fBitCount) 162 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 163 164 if (fBitCount < 65) 165 { 166 final int mask = (0x1 << (bitToGet % 32)); 167 if (bitToGet < 32) 168 return (fBits1 & mask) != 0; 169 else 170 return (fBits2 & mask) != 0; 171 } 172 else 173 { 174 // Create the mask and byte values 175 final byte mask = (byte)(0x1 << (bitToGet % 8)); 176 final int ofs = bitToGet >> 3; 177 178 // And access the right bit and byte 179 return ((fByteArray[ofs] & mask) != 0); 180 } 181 } 182 183 public final boolean isEmpty() 184 { 185 if (fBitCount < 65) 186 { 187 return ((fBits1 == 0) && (fBits2 == 0)); 188 } 189 else 190 { 191 for (int index = fByteCount - 1; index >= 0; index--) 192 { 193 if (fByteArray[index] != 0) 194 return false; 195 } 196 } 197 return true; 198 } 199 200 final boolean isSameSet(CMStateSet setToCompare) 201 { 202 if (fBitCount != setToCompare.fBitCount) 203 return false; 204 205 if (fBitCount < 65) 206 { 207 return ((fBits1 == setToCompare.fBits1) 208 && (fBits2 == setToCompare.fBits2)); 209 } 210 211 for (int index = fByteCount - 1; index >= 0; index--) 212 { 213 if (fByteArray[index] != setToCompare.fByteArray[index]) 214 return false; 215 } 216 return true; 217 } 218 219 // the XS content models from the schema package -neilg. 220 public final void union(CMStateSet setToOr) 221 { 222 if (fBitCount < 65) 223 { 224 fBits1 |= setToOr.fBits1; 225 fBits2 |= setToOr.fBits2; 226 } 227 else 228 { 229 for (int index = fByteCount - 1; index >= 0; index--) 230 fByteArray[index] |= setToOr.fByteArray[index]; 231 } 232 } 233 234 public final void setBit(int bitToSet) 235 { 236 if (bitToSet >= fBitCount) 237 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 238 239 if (fBitCount < 65) 240 { 241 final int mask = (0x1 << (bitToSet % 32)); 242 if (bitToSet < 32) 243 { 244 fBits1 &= ~mask; 245 fBits1 |= mask; 246 } 247 else 248 { 249 fBits2 &= ~mask; 250 fBits2 |= mask; 251 } 252 } 253 else 254 { 255 // Create the mask and byte values 256 final byte mask = (byte)(0x1 << (bitToSet % 8)); 257 final int ofs = bitToSet >> 3; 258 259 // And access the right bit and byte 260 fByteArray[ofs] &= ~mask; 261 fByteArray[ofs] |= mask; 262 } 263 } 264 265 // the XS content models from the schema package -neilg. 266 public final void setTo(CMStateSet srcSet) 267 { 268 // They have to be the same size 269 if (fBitCount != srcSet.fBitCount) 270 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 271 272 if (fBitCount < 65) 273 { 274 fBits1 = srcSet.fBits1; 275 fBits2 = srcSet.fBits2; 276 } 277 else 278 { 279 for (int index = fByteCount - 1; index >= 0; index--) 280 fByteArray[index] = srcSet.fByteArray[index]; 281 } 282 } 283 284 // had to make this method public so it could be accessed from 285 // schema package - neilg. 286 public final void zeroBits() 287 { 288 if (fBitCount < 65) 289 { 290 fBits1 = 0; 291 fBits2 = 0; 292 } 293 else 294 { 295 for (int index = fByteCount - 1; index >= 0; index--) 296 fByteArray[index] = 0; 297 } 298 } 299 300 301 // ------------------------------------------------------------------- 302 // Private data members 303 // 304 // fBitCount 305 // The count of bits that the outside world wants to support, 306 // so its the max bit index plus one. 307 // 308 // fByteCount 309 // If the bit count is > 64, then we use the fByteArray member to 310 // store the bits, and this indicates its size in bytes. Otherwise 311 // its value is meaningless. 312 // 313 // fBits1 314 // fBits2 315 // When the bit count is < 64 (very common), these hold the bits. 316 // Otherwise, the fByteArray member holds htem. 317 // ------------------------------------------------------------------- 318 int fBitCount; 319 int fByteCount; 320 int fBits1; 321 int fBits2; 322 byte[] fByteArray; 323 /* Optimization(Jan, 2001) */ 324 public boolean equals(Object o) { 325 if (!(o instanceof CMStateSet)) return false; 326 return isSameSet((CMStateSet)o); 327 } 328 329 public int hashCode() { 330 if (fBitCount < 65) 331 { 332 return fBits1+ fBits2 * 31; 333 } 334 else 335 { 336 int hash = 0; 337 for (int index = fByteCount - 1; index >= 0; index--) 338 hash = fByteArray[index] + hash * 31; 339 return hash; 340 } 341 } 342 /* Optimization(Jan, 2001) */ 343 };