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