summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/skip2/go-qrcode/bitset
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/skip2/go-qrcode/bitset')
-rw-r--r--vendor/github.com/skip2/go-qrcode/bitset/bitset.go273
1 files changed, 273 insertions, 0 deletions
diff --git a/vendor/github.com/skip2/go-qrcode/bitset/bitset.go b/vendor/github.com/skip2/go-qrcode/bitset/bitset.go
new file mode 100644
index 00000000..fba3bf4d
--- /dev/null
+++ b/vendor/github.com/skip2/go-qrcode/bitset/bitset.go
@@ -0,0 +1,273 @@
+// go-qrcode
+// Copyright 2014 Tom Harwood
+
+// Package bitset implements an append only bit array.
+//
+// To create a Bitset and append some bits:
+// // Bitset Contents
+// b := bitset.New() // {}
+// b.AppendBools(true, true, false) // {1, 1, 0}
+// b.AppendBools(true) // {1, 1, 0, 1}
+// b.AppendValue(0x02, 4) // {1, 1, 0, 1, 0, 0, 1, 0}
+//
+// To read values:
+//
+// len := b.Len() // 8
+// v := b.At(0) // 1
+// v = b.At(1) // 1
+// v = b.At(2) // 0
+// v = b.At(8) // 0
+package bitset
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+)
+
+const (
+ b0 = false
+ b1 = true
+)
+
+// Bitset stores an array of bits.
+type Bitset struct {
+ // The number of bits stored.
+ numBits int
+
+ // Storage for individual bits.
+ bits []byte
+}
+
+// New returns an initialised Bitset with optional initial bits v.
+func New(v ...bool) *Bitset {
+ b := &Bitset{numBits: 0, bits: make([]byte, 0)}
+ b.AppendBools(v...)
+
+ return b
+}
+
+// Clone returns a copy.
+func Clone(from *Bitset) *Bitset {
+ return &Bitset{numBits: from.numBits, bits: from.bits[:]}
+}
+
+// Substr returns a substring, consisting of the bits from indexes start to end.
+func (b *Bitset) Substr(start int, end int) *Bitset {
+ if start > end || end > b.numBits {
+ log.Panicf("Out of range start=%d end=%d numBits=%d", start, end, b.numBits)
+ }
+
+ result := New()
+ result.ensureCapacity(end - start)
+
+ for i := start; i < end; i++ {
+ if b.At(i) {
+ result.bits[result.numBits/8] |= 0x80 >> uint(result.numBits%8)
+ }
+ result.numBits++
+ }
+
+ return result
+}
+
+// NewFromBase2String constructs and returns a Bitset from a string. The string
+// consists of '1', '0' or ' ' characters, e.g. "1010 0101". The '1' and '0'
+// characters represent true/false bits respectively, and ' ' characters are
+// ignored.
+//
+// The function panics if the input string contains other characters.
+func NewFromBase2String(b2string string) *Bitset {
+ b := &Bitset{numBits: 0, bits: make([]byte, 0)}
+
+ for _, c := range b2string {
+ switch c {
+ case '1':
+ b.AppendBools(true)
+ case '0':
+ b.AppendBools(false)
+ case ' ':
+ default:
+ log.Panicf("Invalid char %c in NewFromBase2String", c)
+ }
+ }
+
+ return b
+}
+
+// AppendBytes appends a list of whole bytes.
+func (b *Bitset) AppendBytes(data []byte) {
+ for _, d := range data {
+ b.AppendByte(d, 8)
+ }
+}
+
+// AppendByte appends the numBits least significant bits from value.
+func (b *Bitset) AppendByte(value byte, numBits int) {
+ b.ensureCapacity(numBits)
+
+ if numBits > 8 {
+ log.Panicf("numBits %d out of range 0-8", numBits)
+ }
+
+ for i := numBits - 1; i >= 0; i-- {
+ if value&(1<<uint(i)) != 0 {
+ b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
+ }
+
+ b.numBits++
+ }
+}
+
+// AppendUint32 appends the numBits least significant bits from value.
+func (b *Bitset) AppendUint32(value uint32, numBits int) {
+ b.ensureCapacity(numBits)
+
+ if numBits > 32 {
+ log.Panicf("numBits %d out of range 0-32", numBits)
+ }
+
+ for i := numBits - 1; i >= 0; i-- {
+ if value&(1<<uint(i)) != 0 {
+ b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
+ }
+
+ b.numBits++
+ }
+}
+
+// ensureCapacity ensures the Bitset can store an additional |numBits|.
+//
+// The underlying array is expanded if necessary. To prevent frequent
+// reallocation, expanding the underlying array at least doubles its capacity.
+func (b *Bitset) ensureCapacity(numBits int) {
+ numBits += b.numBits
+
+ newNumBytes := numBits / 8
+ if numBits%8 != 0 {
+ newNumBytes++
+ }
+
+ if len(b.bits) >= newNumBytes {
+ return
+ }
+
+ b.bits = append(b.bits, make([]byte, newNumBytes+2*len(b.bits))...)
+}
+
+// Append bits copied from |other|.
+//
+// The new length is b.Len() + other.Len().
+func (b *Bitset) Append(other *Bitset) {
+ b.ensureCapacity(other.numBits)
+
+ for i := 0; i < other.numBits; i++ {
+ if other.At(i) {
+ b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
+ }
+ b.numBits++
+ }
+}
+
+// AppendBools appends bits to the Bitset.
+func (b *Bitset) AppendBools(bits ...bool) {
+ b.ensureCapacity(len(bits))
+
+ for _, v := range bits {
+ if v {
+ b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)
+ }
+ b.numBits++
+ }
+}
+
+// AppendNumBools appends num bits of value value.
+func (b *Bitset) AppendNumBools(num int, value bool) {
+ for i := 0; i < num; i++ {
+ b.AppendBools(value)
+ }
+}
+
+// String returns a human readable representation of the Bitset's contents.
+func (b *Bitset) String() string {
+ var bitString string
+ for i := 0; i < b.numBits; i++ {
+ if (i % 8) == 0 {
+ bitString += " "
+ }
+
+ if (b.bits[i/8] & (0x80 >> byte(i%8))) != 0 {
+ bitString += "1"
+ } else {
+ bitString += "0"
+ }
+ }
+
+ return fmt.Sprintf("numBits=%d, bits=%s", b.numBits, bitString)
+}
+
+// Len returns the length of the Bitset in bits.
+func (b *Bitset) Len() int {
+ return b.numBits
+}
+
+// Bits returns the contents of the Bitset.
+func (b *Bitset) Bits() []bool {
+ result := make([]bool, b.numBits)
+
+ var i int
+ for i = 0; i < b.numBits; i++ {
+ result[i] = (b.bits[i/8] & (0x80 >> byte(i%8))) != 0
+ }
+
+ return result
+}
+
+// At returns the value of the bit at |index|.
+func (b *Bitset) At(index int) bool {
+ if index >= b.numBits {
+ log.Panicf("Index %d out of range", index)
+ }
+
+ return (b.bits[index/8] & (0x80 >> byte(index%8))) != 0
+}
+
+// Equals returns true if the Bitset equals other.
+func (b *Bitset) Equals(other *Bitset) bool {
+ if b.numBits != other.numBits {
+ return false
+ }
+
+ if !bytes.Equal(b.bits[0:b.numBits/8], other.bits[0:b.numBits/8]) {
+ return false
+ }
+
+ for i := 8 * (b.numBits / 8); i < b.numBits; i++ {
+ a := (b.bits[i/8] & (0x80 >> byte(i%8)))
+ b := (other.bits[i/8] & (0x80 >> byte(i%8)))
+
+ if a != b {
+ return false
+ }
+ }
+
+ return true
+}
+
+// ByteAt returns a byte consisting of upto 8 bits starting at index.
+func (b *Bitset) ByteAt(index int) byte {
+ if index < 0 || index >= b.numBits {
+ log.Panicf("Index %d out of range", index)
+ }
+
+ var result byte
+
+ for i := index; i < index+8 && i < b.numBits; i++ {
+ result <<= 1
+ if b.At(i) {
+ result |= 1
+ }
+ }
+
+ return result
+}