2 * Copyright 2007 ZXing authors
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
18 using com.google.zxing;
\r
19 using com.google.zxing.common;
\r
21 namespace com.google.zxing.qrcode.encoder
\r
23 public sealed class BitVector {
\r
25 private int sizeInBits;
\r
26 private sbyte[] array;
\r
28 // For efficiency, start out with some room to work.
\r
29 private static int DEFAULT_SIZE_IN_BYTES = 32;
\r
31 public BitVector() {
\r
33 array = new sbyte[DEFAULT_SIZE_IN_BYTES];
\r
36 // Return the bit value at "index".
\r
37 public int at(int index) {
\r
38 if (index < 0 || index >= sizeInBits) {
\r
39 throw new ArgumentException("Bad index: " + index);
\r
41 int value = array[index >> 3] & 0xff;
\r
42 return (value >> (7 - (index & 0x7))) & 1;
\r
45 // Return the number of bits in the bit vector.
\r
50 // Return the number of bytes in the bit vector.
\r
51 public int sizeInBytes() {
\r
52 return (sizeInBits + 7) >> 3;
\r
55 // Append one bit to the bit vector.
\r
56 public void appendBit(int bit) {
\r
57 if (!(bit == 0 || bit == 1)) {
\r
58 throw new ArgumentException("Bad bit");
\r
60 int numBitsInLastByte = sizeInBits & 0x7;
\r
61 // We'll expand array if we don't have bits in the last byte.
\r
62 if (numBitsInLastByte == 0) {
\r
66 // Modify the last byte.
\r
67 array[sizeInBits >> 3] |= (sbyte)(bit << (7 - numBitsInLastByte));
\r
71 // Append "numBits" bits in "value" to the bit vector.
\r
72 // REQUIRES: 0<= numBits <= 32.
\r
75 // - appendBits(0x00, 1) adds 0.
\r
76 // - appendBits(0x00, 4) adds 0000.
\r
77 // - appendBits(0xff, 8) adds 11111111.
\r
78 public void appendBits(int value, int numBits) {
\r
79 if (numBits < 0 || numBits > 32) {
\r
80 throw new ArgumentException("Num bits must be between 0 and 32");
\r
82 int numBitsLeft = numBits;
\r
83 while (numBitsLeft > 0) {
\r
84 // Optimization for byte-oriented appending.
\r
85 if ((sizeInBits & 0x7) == 0 && numBitsLeft >= 8) {
\r
86 int newByte = (value >> (numBitsLeft - 8)) & 0xff;
\r
87 appendByte(newByte);
\r
90 int bit = (value >> (numBitsLeft - 1)) & 1;
\r
98 public void appendBitVector(BitVector bits) {
\r
99 int size = bits.size();
\r
100 for (int i = 0; i < size; ++i) {
\r
101 appendBit(bits.at(i));
\r
105 // Modify the bit vector by XOR'ing with "other"
\r
106 public void xor(BitVector other) {
\r
107 if (sizeInBits != other.size()) {
\r
108 throw new ArgumentException("BitVector sizes don't match");
\r
110 int sizeInBytes = (sizeInBits + 7) >> 3;
\r
111 for (int i = 0; i < sizeInBytes; ++i) {
\r
112 // The last byte could be incomplete (i.e. not have 8 bits in
\r
113 // it) but there is no problem since 0 XOR 0 == 0.
\r
114 array[i] ^= other.array[i];
\r
118 // Return String like "01110111" for debugging.
\r
119 public String toString() {
\r
120 StringBuilder result = new StringBuilder(sizeInBits);
\r
121 for (int i = 0; i < sizeInBits; ++i) {
\r
123 result.Append('0');
\r
124 } else if (at(i) == 1) {
\r
125 result.Append('1');
\r
127 throw new ArgumentException("Byte isn't 0 or 1");
\r
130 return result.ToString();
\r
133 // Callers should not assume that array.length is the exact number of bytes needed to hold
\r
134 // sizeInBits - it will typically be larger for efficiency.
\r
135 public sbyte[] getArray() {
\r
139 // Add a new byte to the end, possibly reallocating and doubling the size of the array if we've
\r
140 // run out of room.
\r
141 private void appendByte(int value) {
\r
142 if ((sizeInBits >> 3) == array.Length) {
\r
143 sbyte[] newArray = new sbyte[(array.Length << 1)];
\r
144 System.Array.Copy (array, 0, newArray, 0, array.Length);
\r
147 array[sizeInBits >> 3] = (sbyte) value;
\r