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

ZXBitArray.m 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright 2012 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. #import "ZXBitArray.h"
  17. #import "ZXByteArray.h"
  18. #import "ZXIntArray.h"
  19. @interface ZXBitArray ()
  20. @property (nonatomic, assign) int32_t *bits;
  21. @property (nonatomic, assign) int bitsLength;
  22. @property (nonatomic, assign) int size;
  23. @end
  24. @implementation ZXBitArray
  25. - (id)init {
  26. if (self = [super init]) {
  27. _size = 0;
  28. _bits = (int32_t *)calloc(1, sizeof(int32_t));
  29. _bitsLength = 1;
  30. }
  31. return self;
  32. }
  33. // For testing only
  34. - (id)initWithBits:(ZXIntArray *)bits size:(int)size {
  35. if (self = [self initWithSize:size]) {
  36. _bits = bits.array;
  37. _bits = (int32_t *)malloc(bits.length * sizeof(int32_t));
  38. memcpy(_bits, bits.array, bits.length * sizeof(int32_t));
  39. _bitsLength = bits.length;
  40. }
  41. return self;
  42. }
  43. - (id)initWithSize:(int)size {
  44. if (self = [super init]) {
  45. _size = size;
  46. _bitsLength = (size + 31) / 32;
  47. _bits = (int32_t *)calloc(_bitsLength, sizeof(int32_t));
  48. }
  49. return self;
  50. }
  51. - (void)dealloc {
  52. if (_bits != NULL) {
  53. free(_bits);
  54. _bits = NULL;
  55. }
  56. }
  57. - (int)sizeInBytes {
  58. return (self.size + 7) / 8;
  59. }
  60. - (void)ensureCapacity:(int)size {
  61. if (size > self.bitsLength * 32) {
  62. int newBitsLength = (size + 31) / 32;
  63. self.bits = realloc(self.bits, newBitsLength * sizeof(int32_t));
  64. memset(self.bits + self.bitsLength, 0, (newBitsLength - self.bitsLength) * sizeof(int32_t));
  65. self.bitsLength = newBitsLength;
  66. }
  67. }
  68. - (BOOL)get:(int)i {
  69. return (_bits[i / 32] & (1 << (i & 0x1F))) != 0;
  70. }
  71. - (void)set:(int)i {
  72. _bits[i / 32] |= 1 << (i & 0x1F);
  73. }
  74. - (void)flip:(int)i {
  75. _bits[i / 32] ^= 1 << (i & 0x1F);
  76. }
  77. - (int)nextSet:(int)from {
  78. if (from >= self.size) {
  79. return self.size;
  80. }
  81. int bitsOffset = from / 32;
  82. int32_t currentBits = self.bits[bitsOffset];
  83. // mask off lesser bits first
  84. currentBits &= ~((1 << (from & 0x1F)) - 1);
  85. while (currentBits == 0) {
  86. if (++bitsOffset == self.bitsLength) {
  87. return self.size;
  88. }
  89. currentBits = self.bits[bitsOffset];
  90. }
  91. int result = (bitsOffset * 32) + [self numberOfTrailingZeros:currentBits];
  92. return result > self.size ? self.size : result;
  93. }
  94. - (int)nextUnset:(int)from {
  95. if (from >= self.size) {
  96. return self.size;
  97. }
  98. int bitsOffset = from / 32;
  99. int32_t currentBits = ~self.bits[bitsOffset];
  100. // mask off lesser bits first
  101. currentBits &= ~((1 << (from & 0x1F)) - 1);
  102. while (currentBits == 0) {
  103. if (++bitsOffset == self.bitsLength) {
  104. return self.size;
  105. }
  106. currentBits = ~self.bits[bitsOffset];
  107. }
  108. int result = (bitsOffset * 32) + [self numberOfTrailingZeros:currentBits];
  109. return result > self.size ? self.size : result;
  110. }
  111. - (void)setBulk:(int)i newBits:(int32_t)newBits {
  112. _bits[i / 32] = newBits;
  113. }
  114. - (void)setRange:(int)start end:(int)end {
  115. if (end < start) {
  116. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil];
  117. }
  118. if (end == start) {
  119. return;
  120. }
  121. end--; // will be easier to treat this as the last actually set bit -- inclusive
  122. int firstInt = start / 32;
  123. int lastInt = end / 32;
  124. for (int i = firstInt; i <= lastInt; i++) {
  125. int firstBit = i > firstInt ? 0 : start & 0x1F;
  126. int lastBit = i < lastInt ? 31 : end & 0x1F;
  127. int32_t mask;
  128. if (lastBit > 31) {
  129. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil];
  130. }
  131. if (firstBit == 0 && lastBit == 31) {
  132. mask = -1;
  133. } else {
  134. mask = 0;
  135. for (int j = firstBit; j <= lastBit; j++) {
  136. mask |= 1 << j;
  137. }
  138. }
  139. _bits[i] |= mask;
  140. }
  141. }
  142. - (void)clear {
  143. memset(self.bits, 0, self.bitsLength * sizeof(int32_t));
  144. }
  145. - (BOOL)isRange:(int)start end:(int)end value:(BOOL)value {
  146. if (end < start) {
  147. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil];
  148. }
  149. if (end == start) {
  150. return YES; // empty range matches
  151. }
  152. end--; // will be easier to treat this as the last actually set bit -- inclusive
  153. int firstInt = start / 32;
  154. int lastInt = end / 32;
  155. for (int i = firstInt; i <= lastInt; i++) {
  156. int firstBit = i > firstInt ? 0 : start & 0x1F;
  157. int lastBit = i < lastInt ? 31 : end & 0x1F;
  158. int32_t mask;
  159. if (lastBit > 31) {
  160. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil];
  161. }
  162. if (firstBit == 0 && lastBit == 31) {
  163. mask = -1;
  164. } else {
  165. mask = 0;
  166. for (int j = firstBit; j <= lastBit; j++) {
  167. mask |= 1 << j;
  168. }
  169. }
  170. // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
  171. // equals the mask, or we're looking for 0s and the masked portion is not all 0s
  172. if ((_bits[i] & mask) != (value ? mask : 0)) {
  173. return NO;
  174. }
  175. }
  176. return YES;
  177. }
  178. - (void)appendBit:(BOOL)bit {
  179. [self ensureCapacity:self.size + 1];
  180. if (bit) {
  181. self.bits[self.size / 32] |= 1 << (self.size & 0x1F);
  182. }
  183. self.size++;
  184. }
  185. - (void)appendBits:(int32_t)value numBits:(int)numBits {
  186. if (numBits < 0 || numBits > 32) {
  187. @throw [NSException exceptionWithName:NSInvalidArgumentException
  188. reason:@"Num bits must be between 0 and 32"
  189. userInfo:nil];
  190. }
  191. [self ensureCapacity:self.size + numBits];
  192. for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) {
  193. [self appendBit:((value >> (numBitsLeft - 1)) & 0x01) == 1];
  194. }
  195. }
  196. - (void)appendBitArray:(ZXBitArray *)other {
  197. int otherSize = [other size];
  198. [self ensureCapacity:self.size + otherSize];
  199. for (int i = 0; i < otherSize; i++) {
  200. [self appendBit:[other get:i]];
  201. }
  202. }
  203. - (void)xor:(ZXBitArray *)other {
  204. if (self.bitsLength != other.bitsLength) {
  205. @throw [NSException exceptionWithName:NSInvalidArgumentException
  206. reason:@"Sizes don't match"
  207. userInfo:nil];
  208. }
  209. for (int i = 0; i < self.bitsLength; i++) {
  210. // The last byte could be incomplete (i.e. not have 8 bits in
  211. // it) but there is no problem since 0 XOR 0 == 0.
  212. self.bits[i] ^= other.bits[i];
  213. }
  214. }
  215. - (void)toBytes:(int)bitOffset array:(ZXByteArray *)array offset:(int)offset numBytes:(int)numBytes {
  216. for (int i = 0; i < numBytes; i++) {
  217. int32_t theByte = 0;
  218. for (int j = 0; j < 8; j++) {
  219. if ([self get:bitOffset]) {
  220. theByte |= 1 << (7 - j);
  221. }
  222. bitOffset++;
  223. }
  224. array.array[offset + i] = (int8_t) theByte;
  225. }
  226. }
  227. - (ZXIntArray *)bitArray {
  228. ZXIntArray *array = [[ZXIntArray alloc] initWithLength:self.bitsLength];
  229. memcpy(array.array, self.bits, array.length * sizeof(int32_t));
  230. return array;
  231. }
  232. - (BOOL)isEqual:(id)o {
  233. if (![o isKindOfClass:[ZXBitArray class]]) {
  234. return NO;
  235. }
  236. ZXBitArray *other = (ZXBitArray *)o;
  237. return self.size == other.size && memcmp(self.bits, other.bits, self.bitsLength) != 0;
  238. }
  239. - (NSUInteger)hash {
  240. return 31 * self.size;
  241. }
  242. - (void)reverse {
  243. int32_t *newBits = (int32_t *)calloc(self.bitsLength, sizeof(int32_t));
  244. int size = self.size;
  245. // reverse all int's first
  246. int len = ((size-1) / 32);
  247. int oldBitsLen = len + 1;
  248. for (int i = 0; i < oldBitsLen; i++) {
  249. long x = (long) self.bits[i];
  250. x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1);
  251. x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2);
  252. x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4);
  253. x = ((x >> 8) & 0x00ff00ffL) | ((x & 0x00ff00ffL) << 8);
  254. x = ((x >> 16) & 0x0000ffffL) | ((x & 0x0000ffffL) << 16);
  255. newBits[len - i] = (int32_t) x;
  256. }
  257. // now correct the int's if the bit size isn't a multiple of 32
  258. if (size != oldBitsLen * 32) {
  259. int leftOffset = oldBitsLen * 32 - size;
  260. int mask = 1;
  261. for (int i = 0; i < 31 - leftOffset; i++) {
  262. mask = (mask << 1) | 1;
  263. }
  264. int32_t currentInt = (newBits[0] >> leftOffset) & mask;
  265. for (int i = 1; i < oldBitsLen; i++) {
  266. int32_t nextInt = newBits[i];
  267. currentInt |= nextInt << (32 - leftOffset);
  268. newBits[i - 1] = currentInt;
  269. currentInt = (nextInt >> leftOffset) & mask;
  270. }
  271. newBits[oldBitsLen - 1] = currentInt;
  272. }
  273. if (self.bits != NULL) {
  274. free(self.bits);
  275. }
  276. self.bits = newBits;
  277. }
  278. - (NSString *)description {
  279. NSMutableString *result = [NSMutableString string];
  280. for (int i = 0; i < self.size; i++) {
  281. if ((i & 0x07) == 0) {
  282. [result appendString:@" "];
  283. }
  284. [result appendString:[self get:i] ? @"X" : @"."];
  285. }
  286. return result;
  287. }
  288. // Ported from OpenJDK Integer.numberOfTrailingZeros implementation
  289. - (int32_t)numberOfTrailingZeros:(int32_t)i {
  290. int32_t y;
  291. if (i == 0) return 32;
  292. int32_t n = 31;
  293. y = i <<16; if (y != 0) { n = n -16; i = y; }
  294. y = i << 8; if (y != 0) { n = n - 8; i = y; }
  295. y = i << 4; if (y != 0) { n = n - 4; i = y; }
  296. y = i << 2; if (y != 0) { n = n - 2; i = y; }
  297. return n - (int32_t)((uint32_t)(i << 1) >> 31);
  298. }
  299. - (id)copyWithZone:(NSZone *)zone {
  300. ZXBitArray *copy = [[ZXBitArray allocWithZone:zone] initWithSize:self.size];
  301. memcpy(copy.bits, self.bits, self.size * sizeof(int32_t));
  302. return copy;
  303. }
  304. @end