BitVector.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2008 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. using System;
  17. namespace FastReport.Barcode.QRCode
  18. {
  19. /* /// <summary> JAVAPORT: This should be combined with BitArray in the future, although that class is not yet
  20. /// dynamically resizeable. This implementation is reasonable but there is a lot of function calling
  21. /// in loops I'd like to get rid of.
  22. ///
  23. /// </summary>
  24. /// <author> satorux@google.com (Satoru Takabayashi) - creator
  25. /// </author>
  26. /// <author> dswitkin@google.com (Daniel Switkin) - ported from C++
  27. /// </author>
  28. /// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
  29. /// </author>*/
  30. internal sealed class BitVector
  31. {
  32. public sbyte[] Array
  33. {
  34. // Callers should not assume that array.length is the exact number of bytes needed to hold
  35. // sizeInBits - it will typically be larger for efficiency.
  36. get
  37. {
  38. return array;
  39. }
  40. }
  41. private int sizeInBits;
  42. private sbyte[] array;
  43. // For efficiency, start out with some room to work.
  44. private const int DEFAULT_SIZE_IN_BYTES = 32;
  45. public BitVector()
  46. {
  47. sizeInBits = 0;
  48. array = new sbyte[DEFAULT_SIZE_IN_BYTES];
  49. }
  50. // Return the bit value at "index".
  51. public int at(int index)
  52. {
  53. if (index < 0 || index >= sizeInBits)
  54. {
  55. throw new System.ArgumentException("Bad index: " + index);
  56. }
  57. int value_Renamed = array[index >> 3] & 0xff;
  58. return (value_Renamed >> (7 - (index & 0x7))) & 1;
  59. }
  60. // Return the number of bits in the bit vector.
  61. public int size()
  62. {
  63. return sizeInBits;
  64. }
  65. // Return the number of bytes in the bit vector.
  66. public int sizeInBytes()
  67. {
  68. return (sizeInBits + 7) >> 3;
  69. }
  70. // Append one bit to the bit vector.
  71. public void appendBit(int bit)
  72. {
  73. if (!(bit == 0 || bit == 1))
  74. {
  75. throw new System.ArgumentException("Bad bit");
  76. }
  77. unchecked
  78. {
  79. int numBitsInLastByte = sizeInBits & 0x7;
  80. // We'll expand array if we don't have bits in the last byte.
  81. if (numBitsInLastByte == 0)
  82. {
  83. appendByte(0);
  84. sizeInBits -= 8;
  85. }
  86. // Modify the last byte.
  87. array[sizeInBits >> 3] |= (sbyte)((bit << (7 - numBitsInLastByte)));
  88. ++sizeInBits;
  89. }
  90. }
  91. // Append "numBits" bits in "value" to the bit vector.
  92. // REQUIRES: 0<= numBits <= 32.
  93. //
  94. // Examples:
  95. // - appendBits(0x00, 1) adds 0.
  96. // - appendBits(0x00, 4) adds 0000.
  97. // - appendBits(0xff, 8) adds 11111111.
  98. public void appendBits(int value_Renamed, int numBits)
  99. {
  100. if (numBits < 0 || numBits > 32)
  101. {
  102. throw new System.ArgumentException("Num bits must be between 0 and 32");
  103. }
  104. int numBitsLeft = numBits;
  105. while (numBitsLeft > 0)
  106. {
  107. // Optimization for byte-oriented appending.
  108. if ((sizeInBits & 0x7) == 0 && numBitsLeft >= 8)
  109. {
  110. int newByte = (value_Renamed >> (numBitsLeft - 8)) & 0xff;
  111. appendByte(newByte);
  112. numBitsLeft -= 8;
  113. }
  114. else
  115. {
  116. int bit = (value_Renamed >> (numBitsLeft - 1)) & 1;
  117. appendBit(bit);
  118. --numBitsLeft;
  119. }
  120. }
  121. }
  122. // Append "bits".
  123. public void appendBitVector(BitVector bits)
  124. {
  125. int size = bits.size();
  126. for (int i = 0; i < size; ++i)
  127. {
  128. appendBit(bits.at(i));
  129. }
  130. }
  131. // Modify the bit vector by XOR'ing with "other"
  132. public void xor(BitVector other)
  133. {
  134. if (sizeInBits != other.size())
  135. {
  136. throw new System.ArgumentException("BitVector sizes don't match");
  137. }
  138. int sizeInBytes = (sizeInBits + 7) >> 3;
  139. for (int i = 0; i < sizeInBytes; ++i)
  140. {
  141. // The last byte could be incomplete (i.e. not have 8 bits in
  142. // it) but there is no problem since 0 XOR 0 == 0.
  143. array[i] ^= other.array[i];
  144. }
  145. }
  146. // Add a new byte to the end, possibly reallocating and doubling the size of the array if we've
  147. // run out of room.
  148. private void appendByte(int value_Renamed)
  149. {
  150. unchecked
  151. {
  152. if ((sizeInBits >> 3) == array.Length)
  153. {
  154. sbyte[] newArray = new sbyte[(array.Length << 1)];
  155. // Redivivus.in Java to c# Porting update
  156. // 30/01/2010
  157. // added namespace system
  158. System.Array.Copy(array, 0, newArray, 0, array.Length);
  159. array = newArray;
  160. }
  161. array[sizeInBits >> 3] = (sbyte)value_Renamed;
  162. sizeInBits += 8;
  163. }
  164. }
  165. }
  166. }