1 module barcode.qr.util; 2 3 // std.bitmanip.BitArray store bits in other order 4 5 struct BitBuffer 6 { 7 ubyte[] data; 8 int length; 9 10 alias getBytes = data; 11 12 pure @safe: 13 void appendBits(long val, int len) 14 { 15 auto nlen = length + len; 16 reserve(nlen); 17 for (int i = len - 1; i >= 0; i--, length++) 18 data[length>>3] |= ((val >> i) & 1) << (7-(length&7)); 19 } 20 21 void reserve(int nlen) 22 { 23 if (nlen > data.length * 8) 24 data.length += (nlen - data.length * 8 + 7) / 8; 25 } 26 27 void appendData(const(ubyte)[] arr, int len) 28 { 29 auto nlen = length + len; 30 reserve(nlen); 31 for (int i = 0; i < len; i++, length++) 32 { 33 int bit = (arr[i >> 3] >> (7-(i&7))) & 1; 34 data[length>>3] |= bit << (7-(length & 7)); 35 } 36 } 37 38 bool opIndex(size_t i) const 39 { return cast(bool)((data[i>>3] >> (7-(i&7))) & 1); } 40 41 void opIndexAssign(int val, size_t i) 42 { 43 auto bit = cast(bool)val; 44 data[i>>3] |= bit << (7-(i&7)); 45 } 46 } 47 48 @safe 49 unittest 50 { 51 BitBuffer arr; 52 arr.appendBits(0b101101, 4); 53 assert (arr.length == 4); 54 assert (arr[0] == true); 55 assert (arr[1] == true); 56 assert (arr[2] == false); 57 assert (arr[3] == true); 58 arr.appendBits(0b101, 3); 59 assert (arr.length == 7); 60 assert (arr[4] == true); 61 assert (arr[5] == false); 62 assert (arr[6] == true); 63 64 arr[5] = 1; 65 assert (arr[5] == true); 66 }