1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xerces.internal.impl.dtd.models; 23 24 25/** 26 * This class is a very simple bitset class. The DFA content model code needs 27 * to support a bit set, but the java BitSet class is way, way overkill. Our 28 * bitset never needs to be expanded after creation, hash itself, etc... 29 * 30 * Since the vast majority of content models will never require more than 64 31 * bits, and since allocation of anything in Java is expensive, this class 32 * provides a hybrid implementation that uses two ints for instances that use 33 * 64 bits or fewer. It has a byte array reference member which will only be 34 * used if more than 64 bits are required. 35 * 36 * Note that the code that uses this class will never perform operations 37 * on sets of different sizes, so that check does not have to be made here. 38 * 39 * @xerces.internal 40 * 41 */ 42// made this class public so it can be accessed by 43// the XS content models from the schema package -neilg. 44public class CMStateSet 45{ 46 // ------------------------------------------------------------------- 47 // Constructors 48 // ------------------------------------------------------------------- 49 public CMStateSet(int bitCount) 50 { 51 // Store the required bit count and insure its legal 52 fBitCount = bitCount; 53 if (fBitCount < 0) 54 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 55 56 // 57 // See if we need to allocate the byte array or whether we can live 58 // within the 64 bit high performance scheme. 59 // 60 if (fBitCount > 64) 61 { 62 fByteCount = fBitCount / 8; 63 if (fBitCount % 8 != 0) 64 fByteCount++; 65 fByteArray = new byte[fByteCount]; 66 } 67 68 // Init all the bits to zero 69 zeroBits(); 70 } 71 72 73 // ------------------------------------------------------------------- 74 // Public inherited methods 75 // ------------------------------------------------------------------- 76 public String toString() 77 { 78 StringBuffer strRet = new StringBuffer(); 79 try 80 { 81 strRet.append("{"); 82 for (int index = 0; index < fBitCount; index++) 83 { 84 if (getBit(index)) 85 strRet.append(" " + index); 86 } 87 strRet.append(" }"); 88 } 89 90 catch(RuntimeException exToCatch) 91 { 92 // 93 // We know this won't happen but we have to catch it to avoid it 94 // having to be in our 'throws' list. 95 // 96 } 97 return strRet.toString(); 98 } 99 100 101 // ------------------------------------------------------------------- 102 // Package final methods 103 // ------------------------------------------------------------------- 104// the XS content models from the schema package -neilg. 105 public final void intersection(CMStateSet setToAnd) 106 { 107 if (fBitCount < 65) 108 { 109 fBits1 &= setToAnd.fBits1; 110 fBits2 &= setToAnd.fBits2; 111 } 112 else 113 { 114 for (int index = fByteCount - 1; index >= 0; index--) 115 fByteArray[index] &= setToAnd.fByteArray[index]; 116 } 117 } 118 119 public final boolean getBit(int bitToGet) 120 { 121 if (bitToGet >= fBitCount) 122 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 123 124 if (fBitCount < 65) 125 { 126 final int mask = (0x1 << (bitToGet % 32)); 127 if (bitToGet < 32) 128 return (fBits1 & mask) != 0; 129 else 130 return (fBits2 & mask) != 0; 131 } 132 else 133 { 134 // Create the mask and byte values 135 final byte mask = (byte)(0x1 << (bitToGet % 8)); 136 final int ofs = bitToGet >> 3; 137 138 // And access the right bit and byte 139 return ((fByteArray[ofs] & mask) != 0); 140 } 141 } 142 143 public final boolean isEmpty() 144 { 145 if (fBitCount < 65) 146 { 147 return ((fBits1 == 0) && (fBits2 == 0)); 148 } 149 else 150 { 151 for (int index = fByteCount - 1; index >= 0; index--) 152 { 153 if (fByteArray[index] != 0) 154 return false; 155 } 156 } 157 return true; 158 } 159 160 final boolean isSameSet(CMStateSet setToCompare) 161 { 162 if (fBitCount != setToCompare.fBitCount) 163 return false; 164 165 if (fBitCount < 65) 166 { 167 return ((fBits1 == setToCompare.fBits1) 168 && (fBits2 == setToCompare.fBits2)); 169 } 170 171 for (int index = fByteCount - 1; index >= 0; index--) 172 { 173 if (fByteArray[index] != setToCompare.fByteArray[index]) 174 return false; 175 } 176 return true; 177 } 178 179// the XS content models from the schema package -neilg. 180 public final void union(CMStateSet setToOr) 181 { 182 if (fBitCount < 65) 183 { 184 fBits1 |= setToOr.fBits1; 185 fBits2 |= setToOr.fBits2; 186 } 187 else 188 { 189 for (int index = fByteCount - 1; index >= 0; index--) 190 fByteArray[index] |= setToOr.fByteArray[index]; 191 } 192 } 193 194 public final void setBit(int bitToSet) 195 { 196 if (bitToSet >= fBitCount) 197 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 198 199 if (fBitCount < 65) 200 { 201 final int mask = (0x1 << (bitToSet % 32)); 202 if (bitToSet < 32) 203 { 204 fBits1 &= ~mask; 205 fBits1 |= mask; 206 } 207 else 208 { 209 fBits2 &= ~mask; 210 fBits2 |= mask; 211 } 212 } 213 else 214 { 215 // Create the mask and byte values 216 final byte mask = (byte)(0x1 << (bitToSet % 8)); 217 final int ofs = bitToSet >> 3; 218 219 // And access the right bit and byte 220 fByteArray[ofs] &= ~mask; 221 fByteArray[ofs] |= mask; 222 } 223 } 224 225// the XS content models from the schema package -neilg. 226 public final void setTo(CMStateSet srcSet) 227 { 228 // They have to be the same size 229 if (fBitCount != srcSet.fBitCount) 230 throw new RuntimeException("ImplementationMessages.VAL_CMSI"); 231 232 if (fBitCount < 65) 233 { 234 fBits1 = srcSet.fBits1; 235 fBits2 = srcSet.fBits2; 236 } 237 else 238 { 239 for (int index = fByteCount - 1; index >= 0; index--) 240 fByteArray[index] = srcSet.fByteArray[index]; 241 } 242 } 243 244 // had to make this method public so it could be accessed from 245 // schema package - neilg. 246 public final void zeroBits() 247 { 248 if (fBitCount < 65) 249 { 250 fBits1 = 0; 251 fBits2 = 0; 252 } 253 else 254 { 255 for (int index = fByteCount - 1; index >= 0; index--) 256 fByteArray[index] = 0; 257 } 258 } 259 260 261 // ------------------------------------------------------------------- 262 // Private data members 263 // 264 // fBitCount 265 // The count of bits that the outside world wants to support, 266 // so its the max bit index plus one. 267 // 268 // fByteCount 269 // If the bit count is > 64, then we use the fByteArray member to 270 // store the bits, and this indicates its size in bytes. Otherwise 271 // its value is meaningless. 272 // 273 // fBits1 274 // fBits2 275 // When the bit count is < 64 (very common), these hold the bits. 276 // Otherwise, the fByteArray member holds htem. 277 // ------------------------------------------------------------------- 278 int fBitCount; 279 int fByteCount; 280 int fBits1; 281 int fBits2; 282 byte[] fByteArray; 283 /* Optimization(Jan, 2001) */ 284 public boolean equals(Object o) { 285 if (!(o instanceof CMStateSet)) return false; 286 return isSameSet((CMStateSet)o); 287 } 288 289 public int hashCode() { 290 if (fBitCount < 65) 291 { 292 return fBits1+ fBits2 * 31; 293 } 294 else 295 { 296 int hash = 0; 297 for (int index = fByteCount - 1; index >= 0; index--) 298 hash = fByteArray[index] + hash * 31; 299 return hash; 300 } 301 } 302 /* Optimization(Jan, 2001) */ 303}; 304