You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

BitArray.cs 4.6 kB

10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright 2007 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 ZXing.Common
  18. {
  19. /// <summary>
  20. /// A simple, fast array of bits, represented compactly by an array of ints internally.
  21. /// </summary>
  22. /// <author>Sean Owen</author>
  23. public sealed class BitArray
  24. {
  25. private int[] bits;
  26. private int size;
  27. public int Size
  28. {
  29. get
  30. {
  31. return size;
  32. }
  33. }
  34. public int SizeInBytes
  35. {
  36. get
  37. {
  38. return (size + 7) >> 3;
  39. }
  40. }
  41. public bool this[int i]
  42. {
  43. get
  44. {
  45. return (bits[i >> 5] & (1 << (i & 0x1F))) != 0;
  46. }
  47. }
  48. public BitArray()
  49. {
  50. this.size = 0;
  51. this.bits = new int[1];
  52. }
  53. private void ensureCapacity(int size)
  54. {
  55. if (size > bits.Length << 5)
  56. {
  57. int[] newBits = makeArray(size);
  58. System.Array.Copy(bits, 0, newBits, 0, bits.Length);
  59. bits = newBits;
  60. }
  61. }
  62. /// <summary>
  63. /// Appends the bit.
  64. /// </summary>
  65. /// <param name="bit">The bit.</param>
  66. public void appendBit(bool bit)
  67. {
  68. ensureCapacity(size + 1);
  69. if (bit)
  70. {
  71. bits[size >> 5] |= 1 << (size & 0x1F);
  72. }
  73. size++;
  74. }
  75. /// <summary>
  76. /// Appends the least-significant bits, from value, in order from most-significant to
  77. /// least-significant. For example, appending 6 bits from 0x000001E will append the bits
  78. /// 0, 1, 1, 1, 1, 0 in that order.
  79. /// </summary>
  80. /// <param name="value"><see cref="int"/> containing bits to append</param>
  81. /// <param name="numBits">bits from value to append</param>
  82. public void appendBits(int value, int numBits)
  83. {
  84. if (numBits < 0 || numBits > 32)
  85. {
  86. throw new ArgumentException("Num bits must be between 0 and 32");
  87. }
  88. ensureCapacity(size + numBits);
  89. for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--)
  90. {
  91. appendBit(((value >> (numBitsLeft - 1)) & 0x01) == 1);
  92. }
  93. }
  94. public void appendBitArray(BitArray other)
  95. {
  96. int otherSize = other.size;
  97. ensureCapacity(size + otherSize);
  98. for (int i = 0; i < otherSize; i++)
  99. {
  100. appendBit(other[i]);
  101. }
  102. }
  103. public void xor(BitArray other)
  104. {
  105. if (bits.Length != other.bits.Length)
  106. {
  107. throw new ArgumentException("Sizes don't match");
  108. }
  109. for (int i = 0; i < bits.Length; i++)
  110. {
  111. // The last byte could be incomplete (i.e. not have 8 bits in
  112. // it) but there is no problem since 0 XOR 0 == 0.
  113. bits[i] ^= other.bits[i];
  114. }
  115. }
  116. /// <summary>
  117. /// Toes the bytes.
  118. /// </summary>
  119. /// <param name="bitOffset">first bit to start writing</param>
  120. /// <param name="array">array to write into. Bytes are written most-significant byte first. This is the opposite
  121. /// of the internal representation, which is exposed by BitArray</param>
  122. /// <param name="offset">position in array to start writing</param>
  123. /// <param name="numBytes">how many bytes to write</param>
  124. public void toBytes(int bitOffset, byte[] array, int offset, int numBytes)
  125. {
  126. for (int i = 0; i < numBytes; i++)
  127. {
  128. int theByte = 0;
  129. for (int j = 0; j < 8; j++)
  130. {
  131. if (this[bitOffset])
  132. {
  133. theByte |= 1 << (7 - j);
  134. }
  135. bitOffset++;
  136. }
  137. array[offset + i] = (byte)theByte;
  138. }
  139. }
  140. private static int[] makeArray(int size)
  141. {
  142. return new int[(size + 31) >> 5];
  143. }
  144. }
  145. }