extensions/net.sf.basedb.otp/trunk/src/io/nayuki/qrcodegen/BitBuffer.java

Code
Comments
Other
Rev Date Author Line
4850 14 Jun 18 nicklas 1 /* 
4850 14 Jun 18 nicklas 2  * QR Code generator library (Java)
4850 14 Jun 18 nicklas 3  * 
4850 14 Jun 18 nicklas 4  * Copyright (c) Project Nayuki. (MIT License)
4850 14 Jun 18 nicklas 5  * https://www.nayuki.io/page/qr-code-generator-library
4850 14 Jun 18 nicklas 6  * 
4850 14 Jun 18 nicklas 7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
4850 14 Jun 18 nicklas 8  * this software and associated documentation files (the "Software"), to deal in
4850 14 Jun 18 nicklas 9  * the Software without restriction, including without limitation the rights to
4850 14 Jun 18 nicklas 10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
4850 14 Jun 18 nicklas 11  * the Software, and to permit persons to whom the Software is furnished to do so,
4850 14 Jun 18 nicklas 12  * subject to the following conditions:
4850 14 Jun 18 nicklas 13  * - The above copyright notice and this permission notice shall be included in
4850 14 Jun 18 nicklas 14  *   all copies or substantial portions of the Software.
4850 14 Jun 18 nicklas 15  * - The Software is provided "as is", without warranty of any kind, express or
4850 14 Jun 18 nicklas 16  *   implied, including but not limited to the warranties of merchantability,
4850 14 Jun 18 nicklas 17  *   fitness for a particular purpose and noninfringement. In no event shall the
4850 14 Jun 18 nicklas 18  *   authors or copyright holders be liable for any claim, damages or other
4850 14 Jun 18 nicklas 19  *   liability, whether in an action of contract, tort or otherwise, arising from,
4850 14 Jun 18 nicklas 20  *   out of or in connection with the Software or the use or other dealings in the
4850 14 Jun 18 nicklas 21  *   Software.
4850 14 Jun 18 nicklas 22  */
4850 14 Jun 18 nicklas 23
4850 14 Jun 18 nicklas 24 package io.nayuki.qrcodegen;
4850 14 Jun 18 nicklas 25
4850 14 Jun 18 nicklas 26 import java.util.BitSet;
4850 14 Jun 18 nicklas 27 import java.util.Objects;
4850 14 Jun 18 nicklas 28
4850 14 Jun 18 nicklas 29
4850 14 Jun 18 nicklas 30 /**
4850 14 Jun 18 nicklas 31  * An appendable sequence of bits (0's and 1's).
4850 14 Jun 18 nicklas 32  */
4850 14 Jun 18 nicklas 33 public final class BitBuffer implements Cloneable {
4850 14 Jun 18 nicklas 34   
4850 14 Jun 18 nicklas 35   /*---- Fields ----*/
4850 14 Jun 18 nicklas 36   
4850 14 Jun 18 nicklas 37   private BitSet data;
4850 14 Jun 18 nicklas 38   
4850 14 Jun 18 nicklas 39   private int bitLength;
4850 14 Jun 18 nicklas 40   
4850 14 Jun 18 nicklas 41   
4850 14 Jun 18 nicklas 42   
4850 14 Jun 18 nicklas 43   /*---- Constructor ----*/
4850 14 Jun 18 nicklas 44   
4850 14 Jun 18 nicklas 45   /**
4850 14 Jun 18 nicklas 46    * Constructs an empty bit buffer (length 0).
4850 14 Jun 18 nicklas 47    */
4850 14 Jun 18 nicklas 48   public BitBuffer() {
4850 14 Jun 18 nicklas 49     data = new BitSet();
4850 14 Jun 18 nicklas 50     bitLength = 0;
4850 14 Jun 18 nicklas 51   }
4850 14 Jun 18 nicklas 52   
4850 14 Jun 18 nicklas 53   
4850 14 Jun 18 nicklas 54   
4850 14 Jun 18 nicklas 55   /*---- Methods ----*/
4850 14 Jun 18 nicklas 56   
4850 14 Jun 18 nicklas 57   /**
4850 14 Jun 18 nicklas 58    * Returns the length of this sequence, which is a non-negative value.
4850 14 Jun 18 nicklas 59    * @return the length of this sequence
4850 14 Jun 18 nicklas 60    */
4850 14 Jun 18 nicklas 61   public int bitLength() {
4850 14 Jun 18 nicklas 62     return bitLength;
4850 14 Jun 18 nicklas 63   }
4850 14 Jun 18 nicklas 64   
4850 14 Jun 18 nicklas 65   
4850 14 Jun 18 nicklas 66   /**
4850 14 Jun 18 nicklas 67    * Returns the bit at the specified index, yielding 0 or 1.
4850 14 Jun 18 nicklas 68    * @param index the index to get the bit at
4850 14 Jun 18 nicklas 69    * @return the bit at the specified index
4850 14 Jun 18 nicklas 70    * @throws IndexOutOfBoundsException if index < 0 or index ≥ bitLength
4850 14 Jun 18 nicklas 71    */
4850 14 Jun 18 nicklas 72   public int getBit(int index) {
4850 14 Jun 18 nicklas 73     if (index < 0 || index >= bitLength)
4850 14 Jun 18 nicklas 74       throw new IndexOutOfBoundsException();
4850 14 Jun 18 nicklas 75     return data.get(index) ? 1 : 0;
4850 14 Jun 18 nicklas 76   }
4850 14 Jun 18 nicklas 77   
4850 14 Jun 18 nicklas 78   
4850 14 Jun 18 nicklas 79   /**
4850 14 Jun 18 nicklas 80    * Packs this buffer's bits into bytes in big endian,
4850 14 Jun 18 nicklas 81    * padding with '0' bit values, and returns the new array.
4850 14 Jun 18 nicklas 82    * @return this sequence as a new array of bytes (not {@code null})
4850 14 Jun 18 nicklas 83    */
4850 14 Jun 18 nicklas 84   public byte[] getBytes() {
4850 14 Jun 18 nicklas 85     byte[] result = new byte[(bitLength + 7) / 8];
4850 14 Jun 18 nicklas 86     for (int i = 0; i < bitLength; i++)
4850 14 Jun 18 nicklas 87       result[i >>> 3] |= data.get(i) ? 1 << (7 - (i & 7)) : 0;
4850 14 Jun 18 nicklas 88     return result;
4850 14 Jun 18 nicklas 89   }
4850 14 Jun 18 nicklas 90   
4850 14 Jun 18 nicklas 91   
4850 14 Jun 18 nicklas 92   /**
4850 14 Jun 18 nicklas 93    * Appends the specified number of low bits of the specified value
4850 14 Jun 18 nicklas 94    * to this sequence. Requires 0 &le; val &lt; 2<sup>len</sup>.
4850 14 Jun 18 nicklas 95    * @param val the value to append
4850 14 Jun 18 nicklas 96    * @param len the number of low bits in the value to take
4850 14 Jun 18 nicklas 97    */
4850 14 Jun 18 nicklas 98   public void appendBits(int val, int len) {
4850 14 Jun 18 nicklas 99     if (len < 0 || len > 31 || val >>> len != 0)
4850 14 Jun 18 nicklas 100       throw new IllegalArgumentException("Value out of range");
4850 14 Jun 18 nicklas 101     for (int i = len - 1; i >= 0; i--, bitLength++)  // Append bit by bit
4850 14 Jun 18 nicklas 102       data.set(bitLength, QrCode.getBit(val, i));
4850 14 Jun 18 nicklas 103   }
4850 14 Jun 18 nicklas 104   
4850 14 Jun 18 nicklas 105   
4850 14 Jun 18 nicklas 106   /**
4850 14 Jun 18 nicklas 107    * Appends the bit data of the specified segment to this bit buffer.
4850 14 Jun 18 nicklas 108    * @param seg the segment whose data to append (not {@code null})
4850 14 Jun 18 nicklas 109    * @throws NullPointerException if the segment is {@code null}
4850 14 Jun 18 nicklas 110    */
4850 14 Jun 18 nicklas 111   public void appendData(QrSegment seg) {
4850 14 Jun 18 nicklas 112     Objects.requireNonNull(seg);
4850 14 Jun 18 nicklas 113     BitBuffer bb = seg.data;
4850 14 Jun 18 nicklas 114     for (int i = 0; i < bb.bitLength; i++, bitLength++)  // Append bit by bit
4850 14 Jun 18 nicklas 115       data.set(bitLength, bb.data.get(i));
4850 14 Jun 18 nicklas 116   }
4850 14 Jun 18 nicklas 117   
4850 14 Jun 18 nicklas 118   
4850 14 Jun 18 nicklas 119   /**
4850 14 Jun 18 nicklas 120    * Returns a copy of this bit buffer object.
4850 14 Jun 18 nicklas 121    * @return a copy of this bit buffer object
4850 14 Jun 18 nicklas 122    */
4850 14 Jun 18 nicklas 123   @Override
4850 14 Jun 18 nicklas 124   public BitBuffer clone() {
4850 14 Jun 18 nicklas 125     try {
4850 14 Jun 18 nicklas 126       BitBuffer result = (BitBuffer)super.clone();
4850 14 Jun 18 nicklas 127       result.data = (BitSet)result.data.clone();
4850 14 Jun 18 nicklas 128       return result;
4850 14 Jun 18 nicklas 129     } catch (CloneNotSupportedException e) {
4850 14 Jun 18 nicklas 130       throw new AssertionError(e);
4850 14 Jun 18 nicklas 131     }
4850 14 Jun 18 nicklas 132   }
4850 14 Jun 18 nicklas 133   
4850 14 Jun 18 nicklas 134 }