From f6e1276b08705c7b353105a106d9934cf5216c13 Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Thu, 17 Aug 2017 20:34:52 +0000 Subject: [PATCH] Updated Java QrSegment fields from array to BitBuffer, changed methods and updated code that depended on this design. --- java/io/nayuki/qrcodegen/BitBuffer.java | 7 ++-- java/io/nayuki/qrcodegen/QrSegment.java | 45 ++++++------------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/java/io/nayuki/qrcodegen/BitBuffer.java b/java/io/nayuki/qrcodegen/BitBuffer.java index fc88a12..9302e67 100644 --- a/java/io/nayuki/qrcodegen/BitBuffer.java +++ b/java/io/nayuki/qrcodegen/BitBuffer.java @@ -87,10 +87,9 @@ public final class BitBuffer implements Cloneable { // Appends the data of the given segment to this bit buffer. public void appendData(QrSegment seg) { Objects.requireNonNull(seg); - for (int i = 0; i < seg.bitLength; i++, bitLength++) { // Append bit by bit - int bit = (seg.getByte(i >>> 3) >>> (7 - (i & 7))) & 1; - data.set(bitLength, bit != 0); - } + BitBuffer bb = seg.data; + for (int i = 0; i < bb.bitLength; i++, bitLength++) // Append bit by bit + data.set(bitLength, bb.data.get(i)); } diff --git a/java/io/nayuki/qrcodegen/QrSegment.java b/java/io/nayuki/qrcodegen/QrSegment.java index 2a7d557..f6fa87e 100644 --- a/java/io/nayuki/qrcodegen/QrSegment.java +++ b/java/io/nayuki/qrcodegen/QrSegment.java @@ -25,7 +25,6 @@ package io.nayuki.qrcodegen; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.regex.Pattern; @@ -162,11 +161,8 @@ public final class QrSegment { /** The length of this segment's unencoded data, measured in characters. Always zero or positive. */ public final int numChars; - /** The bits of this segment packed into a byte array in big endian. Accessed through {@link getByte(int)}. Not {@code null}. */ - private final byte[] data; - - /** The length of this segment's encoded data, measured in bits. Satisfies 0 ≤ {@code bitLength} ≤ {@code data.length} × 8. */ - public final int bitLength; + /** The data bits of this segment. Accessed through {@link getBits()}. Not {@code null}. */ + final BitBuffer data; /*---- Constructor ----*/ @@ -180,43 +176,24 @@ public final class QrSegment { * @throws IllegalArgumentException if the character count is negative */ public QrSegment(Mode md, int numCh, BitBuffer data) { - this(md, numCh, data.getBytes(), data.bitLength()); - } - - - /** - * Creates a new QR Code data segment with the specified parameters and data. - * @param md the mode, which is not {@code null} - * @param numCh the data length in characters, which is non-negative - * @param bitLen the data length in bits, which is non-negative - * @param b the bits packed into bytes, which is not {@code null} - * @throws NullPointerException if the mode or array is {@code null} - * @throws IllegalArgumentException if the character count or bit length are negative or invalid - */ - public QrSegment(Mode md, int numCh, byte[] b, int bitLen) { Objects.requireNonNull(md); - Objects.requireNonNull(b); - if (numCh < 0 || bitLen < 0 || bitLen > b.length * 8L) + Objects.requireNonNull(data); + if (numCh < 0) throw new IllegalArgumentException("Invalid value"); mode = md; numChars = numCh; - data = Arrays.copyOf(b, (bitLen + 7) / 8); // Trim to precise length and also make defensive copy - bitLength = bitLen; + this.data = data.clone(); // Make defensive copy } - /*---- Method ----*/ + /*---- Methods ----*/ /** - * Returns the data byte at the specified index. - * @param index the index to retrieve from, satisfying 0 ≤ {@code index} < ceil({@code bitLength} ÷ 8) - * @return the data byte at the specified index - * @throws IndexOutOfBoundsException if the index is out of bounds + * Returns the data bits of this segment. + * @return the data bits of this segment (not {@code null}) */ - public byte getByte(int index) { - if (index < 0 || index > data.length) - throw new IndexOutOfBoundsException(); - return data[index]; + public BitBuffer getBits() { + return data.clone(); // Make defensive copy } @@ -233,7 +210,7 @@ public final class QrSegment { // Fail if segment length value doesn't fit in the length field's bit-width if (seg.numChars >= (1 << ccbits)) return -1; - result += 4L + ccbits + seg.bitLength; + result += 4L + ccbits + seg.data.bitLength(); if (result > Integer.MAX_VALUE) return -1; }