8937eb401ca8c71e918aaa7d511bb91e29e1b778
[zxing.git] / cpp / core / src / common / BitArray.cpp
1 /*
2  *  BitArray.cpp
3  *  zxing
4  *
5  *  Created by Christian Brunschen on 09/05/2008.
6  *  Copyright 2008 Google UK. All rights reserved.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include "BitArray.h"
22 #include <iostream>
23
24 using namespace std;
25
26 namespace common {
27   static unsigned int logDigits(unsigned digits) {
28     unsigned log = 0;
29     unsigned val = 1;
30     while (val < digits) {
31       log++;
32       val <<= 1;
33     }
34     return log;
35   }
36   const unsigned int BitArray::bitsPerWord_ = 
37     numeric_limits<unsigned int>::digits;
38   const unsigned int BitArray::logBits_ = logDigits(bitsPerWord_);
39   const unsigned int BitArray::bitsMask_ = (1 << logBits_) - 1;
40   size_t BitArray::wordsForBits(size_t bits) {
41     int arraySize = bits >> logBits_;
42     if (bits - (arraySize << logBits_) != 0) {
43       arraySize++;
44     }
45     return arraySize;
46   }
47   BitArray::BitArray() { 
48     cout << "hey! don't use this BitArrayConstructor!\n";
49   }
50   
51   BitArray::BitArray(size_t size) : size_(size), bits_(wordsForBits(size)) { 
52   }
53   BitArray::~BitArray() { }
54   size_t BitArray::getSize() { 
55     return size_; 
56   }
57   bool BitArray::get(size_t i) {
58     return (bits_[i >> logBits_] & (1 << (i & bitsMask_))) != 0; 
59   }
60   void BitArray::set(size_t i) {
61     bits_[i >> logBits_] |= 1 << (i & bitsMask_);
62   }
63   void BitArray::setBulk(size_t i, unsigned int newBits) {
64     bits_[i >> logBits_] = newBits;
65   }
66   void BitArray::clear() {
67     size_t max = bits_.size();
68     for (size_t i = 0; i < max; i++) {
69       bits_[i] = 0;
70     }
71   }
72   bool BitArray::isRange(size_t start, size_t end, bool value) {
73     if (end < start) {
74       throw new IllegalArgumentException("end must be after start");
75     }
76     if (end == start) {
77       return true;
78     }
79     // treat the 'end' as inclusive, rather than exclusive
80     end--;
81     size_t firstWord = start >> logBits_;
82     size_t lastWord = end >> logBits_;
83     for (size_t i = firstWord; i <= lastWord; i++) {
84       size_t firstBit = i > firstWord ? 0 : start & bitsMask_;
85       size_t lastBit = i < lastWord ? logBits_ : end & bitsMask_;
86       unsigned int mask;
87       if (firstBit == 0 && lastBit == logBits_) {
88         mask = numeric_limits<unsigned int>::max();
89       } else {
90         mask = 0;
91         for (size_t j = firstBit; j <= lastBit; j++) {
92           mask |= 1 << j;
93         }
94       }
95       if (value) {
96         if ((bits_[i] & mask) != mask) {
97           return false;
98         }
99       } else {
100         if ((bits_[i] & mask) != 0) {
101           return false;
102         }
103       }
104     }
105     return true;
106   }
107   valarray<unsigned int>& BitArray::getBitArray() {
108     return bits_;
109   }
110   void BitArray::reverse() {
111     unsigned int allBits = numeric_limits<unsigned int>::max();
112     size_t max = bits_.size();
113     for (size_t i = 0; i < max; i++) {
114       bits_[i] = bits_[i] ^ allBits;
115     }
116   }
117 }