Moved QrCode.encodeTextToSegment() to QrSegment.makeSegments() and changed the function's code somewhat, in all language versions; updated JavaScript demo script to handle new semantics.
This commit is contained in:
parent
1b2a554121
commit
ca7e7a60a7
|
@ -43,27 +43,11 @@ const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::HIGH (3, 2);
|
|||
|
||||
|
||||
qrcodegen::QrCode qrcodegen::QrCode::encodeText(const char *text, const Ecc &ecl) {
|
||||
std::vector<QrSegment> segs;
|
||||
segs.push_back(encodeTextToSegment(text));
|
||||
std::vector<QrSegment> segs(QrSegment::makeSegments(text));
|
||||
return encodeSegments(segs, ecl);
|
||||
}
|
||||
|
||||
|
||||
qrcodegen::QrSegment qrcodegen::QrCode::encodeTextToSegment(const char *text) {
|
||||
// Select the most efficient segment encoding automatically
|
||||
if (QrSegment::isNumeric(text))
|
||||
return QrSegment::makeNumeric(text);
|
||||
else if (QrSegment::isAlphanumeric(text))
|
||||
return QrSegment::makeAlphanumeric(text);
|
||||
else {
|
||||
std::vector<uint8_t> bytes;
|
||||
for (; *text != '\0'; text++)
|
||||
bytes.push_back(static_cast<uint8_t>(*text));
|
||||
return QrSegment::makeBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qrcodegen::QrCode qrcodegen::QrCode::encodeBinary(const std::vector<uint8_t> &data, const Ecc &ecl) {
|
||||
std::vector<QrSegment> segs;
|
||||
segs.push_back(QrSegment::makeBytes(data));
|
||||
|
|
|
@ -74,12 +74,6 @@ public:
|
|||
static QrCode encodeText(const char *text, const Ecc &ecl);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a QR segment representing the given Unicode text string.
|
||||
*/
|
||||
static QrSegment encodeTextToSegment(const char *text);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the given binary data string at the given error correction level.
|
||||
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||
|
|
|
@ -100,6 +100,24 @@ qrcodegen::QrSegment qrcodegen::QrSegment::makeAlphanumeric(const char *text) {
|
|||
}
|
||||
|
||||
|
||||
std::vector<qrcodegen::QrSegment> qrcodegen::QrSegment::makeSegments(const char *text) {
|
||||
// Select the most efficient segment encoding automatically
|
||||
std::vector<QrSegment> result;
|
||||
if (*text == '\0'); // Leave the vector empty
|
||||
else if (QrSegment::isNumeric(text))
|
||||
result.push_back(QrSegment::makeNumeric(text));
|
||||
else if (QrSegment::isAlphanumeric(text))
|
||||
result.push_back(QrSegment::makeAlphanumeric(text));
|
||||
else {
|
||||
std::vector<uint8_t> bytes;
|
||||
for (; *text != '\0'; text++)
|
||||
bytes.push_back(static_cast<uint8_t>(*text));
|
||||
result.push_back(QrSegment::makeBytes(bytes));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
qrcodegen::QrSegment::QrSegment(const Mode &md, int numCh, const std::vector<uint8_t> &b, int bitLen) :
|
||||
mode(md),
|
||||
numChars(numCh),
|
||||
|
|
|
@ -103,6 +103,13 @@ public:
|
|||
static QrSegment makeAlphanumeric(const char *text);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a list of zero or more segments to represent the given text string.
|
||||
* The result may use various segment modes and switch modes to optimize the length of the bit stream.
|
||||
*/
|
||||
static std::vector<QrSegment> makeSegments(const char *text);
|
||||
|
||||
|
||||
/*---- Static helper functions ----*/
|
||||
public:
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
package io.nayuki.qrcodegen;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -53,27 +52,8 @@ public final class QrCode {
|
|||
public static QrCode encodeText(String text, Ecc ecl) {
|
||||
if (text == null || ecl == null)
|
||||
throw new NullPointerException();
|
||||
QrSegment seg = encodeTextToSegment(text);
|
||||
return encodeSegments(Arrays.asList(seg), ecl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a QR segment representing the specified Unicode text string.
|
||||
* @param text the text to be encoded, which can be any Unicode string
|
||||
* @return a QR segment containing the text
|
||||
* @throws NullPointerException if the text is {@code null}
|
||||
*/
|
||||
public static QrSegment encodeTextToSegment(String text) {
|
||||
if (text == null)
|
||||
throw new NullPointerException();
|
||||
// Select the most efficient segment encoding automatically
|
||||
if (QrSegment.NUMERIC_REGEX.matcher(text).matches())
|
||||
return QrSegment.makeNumeric(text);
|
||||
else if (QrSegment.ALPHANUMERIC_REGEX.matcher(text).matches())
|
||||
return QrSegment.makeAlphanumeric(text);
|
||||
else
|
||||
return QrSegment.makeBytes(text.getBytes(StandardCharsets.UTF_8));
|
||||
List<QrSegment> segs = QrSegment.makeSegments(text);
|
||||
return encodeSegments(segs, ecl);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,10 @@
|
|||
|
||||
package io.nayuki.qrcodegen;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
|
@ -104,6 +107,31 @@ public final class QrSegment {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new mutable list of zero or more segments to represent the specified Unicode text string.
|
||||
* The result may use various segment modes and switch modes to optimize the length of the bit stream.
|
||||
* @param text the text to be encoded, which can be any Unicode string
|
||||
* @return a list of segments containing the text
|
||||
* @throws NullPointerException if the text is {@code null}
|
||||
*/
|
||||
public static List<QrSegment> makeSegments(String text) {
|
||||
if (text == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
// Select the most efficient segment encoding automatically
|
||||
if (text.equals(""))
|
||||
return new ArrayList<>();
|
||||
QrSegment seg;
|
||||
if (NUMERIC_REGEX.matcher(text).matches())
|
||||
seg = makeNumeric(text);
|
||||
else if (ALPHANUMERIC_REGEX.matcher(text).matches())
|
||||
seg = makeAlphanumeric(text);
|
||||
else
|
||||
seg = makeBytes(text.getBytes(StandardCharsets.UTF_8));
|
||||
return Arrays.asList(seg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---- Instance fields ----*/
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ function redrawQrCode() {
|
|||
|
||||
// Get text and compute QR Code
|
||||
var text = document.getElementById("text-input").value;
|
||||
var qr = qrcodegen.encodeText(text, ecl);
|
||||
var segs = qrcodegen.QrSegment.makeSegments(text);
|
||||
var qr = qrcodegen.encodeSegments(segs, ecl);
|
||||
|
||||
// Get scale and border
|
||||
var scale = parseInt(document.getElementById("scale-input").value, 10);
|
||||
|
@ -67,18 +68,27 @@ function redrawQrCode() {
|
|||
stats += "mask pattern = " + qr.getMask() + ", ";
|
||||
stats += "character count = " + countUnicodeChars(text) + ",\n";
|
||||
stats += "encoding mode = ";
|
||||
var seg = qrcodegen.encodeTextToSegment(text);
|
||||
if (seg.getMode() == qrcodegen.QrSegment.Mode.NUMERIC)
|
||||
stats += "numeric";
|
||||
else if (seg.getMode() == qrcodegen.QrSegment.Mode.ALPHANUMERIC)
|
||||
stats += "alphanumeric";
|
||||
else if (seg.getMode() == qrcodegen.QrSegment.Mode.BYTE)
|
||||
stats += "byte";
|
||||
else if (seg.getMode() == qrcodegen.QrSegment.Mode.BYTE)
|
||||
stats += "kanji";
|
||||
else
|
||||
stats += "unknown";
|
||||
stats += ", data bits = " + (4 + seg.getMode().numCharCountBits(qr.getVersion()) + seg.getBits().length) + ".";
|
||||
if (segs.length == 0)
|
||||
stats += "none";
|
||||
else if (segs.length == 1) {
|
||||
var mode = segs[0].getMode();
|
||||
if (mode == qrcodegen.QrSegment.Mode.NUMERIC)
|
||||
stats += "numeric";
|
||||
else if (mode == qrcodegen.QrSegment.Mode.ALPHANUMERIC)
|
||||
stats += "alphanumeric";
|
||||
else if (mode == qrcodegen.QrSegment.Mode.BYTE)
|
||||
stats += "byte";
|
||||
else if (mode == qrcodegen.QrSegment.Mode.BYTE)
|
||||
stats += "kanji";
|
||||
else
|
||||
stats += "unknown";
|
||||
} else
|
||||
stats += "multiple";
|
||||
var databits = 0;
|
||||
segs.forEach(function(seg) {
|
||||
databits += 4 + seg.getMode().numCharCountBits(qr.getVersion()) + seg.getBits().length;
|
||||
});
|
||||
stats += ", data bits = " + databits + ".";
|
||||
var elem = document.getElementById("statistics-output");
|
||||
while (elem.firstChild != null)
|
||||
elem.removeChild(elem.firstChild);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
/*
|
||||
* Module "qrcodegen". Public members inside this namespace:
|
||||
* - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeTextToSegment(str text) -> QrSegment
|
||||
* - Function encodeBinary(list<int> data, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl) -> QrCode
|
||||
* - Class QrCode:
|
||||
|
@ -48,6 +47,7 @@
|
|||
* - Function makeBytes(list<int> data) -> QrSegment
|
||||
* - Function makeNumeric(str data) -> QrSegment
|
||||
* - Function makeAlphanumeric(str data) -> QrSegment
|
||||
* - Function makeSegments(str text) -> list<QrSegment>
|
||||
* - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData)
|
||||
* - Method getMode() -> QrSegment.Mode
|
||||
* - Method getNumChars() -> int
|
||||
|
@ -67,22 +67,8 @@ var qrcodegen = new function() {
|
|||
* code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output.
|
||||
*/
|
||||
this.encodeText = function(text, ecl) {
|
||||
var seg = this.encodeTextToSegment(text);
|
||||
return this.encodeSegments([seg], ecl);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a single QR segment representing the given Unicode text string.
|
||||
*/
|
||||
this.encodeTextToSegment = function(text) {
|
||||
// Select the most efficient segment encoding automatically
|
||||
if (QrSegment.NUMERIC_REGEX.test(text))
|
||||
return this.QrSegment.makeNumeric(text);
|
||||
else if (QrSegment.ALPHANUMERIC_REGEX.test(text))
|
||||
return this.QrSegment.makeAlphanumeric(text);
|
||||
else
|
||||
return this.QrSegment.makeBytes(toUtf8ByteArray(text));
|
||||
var segs = this.QrSegment.makeSegments(text);
|
||||
return this.encodeSegments(segs, ecl);
|
||||
};
|
||||
|
||||
|
||||
|
@ -773,6 +759,22 @@ var qrcodegen = new function() {
|
|||
return new this(this.Mode.ALPHANUMERIC, text.length, bb.getBits());
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns a new mutable list of zero or more segments to represent the given Unicode text string.
|
||||
* The result may use various segment modes and switch modes to optimize the length of the bit stream.
|
||||
*/
|
||||
this.QrSegment.makeSegments = function(text) {
|
||||
// Select the most efficient segment encoding automatically
|
||||
if (text == "")
|
||||
return [];
|
||||
else if (QrSegment.NUMERIC_REGEX.test(text))
|
||||
return [this.makeNumeric(text)];
|
||||
else if (QrSegment.ALPHANUMERIC_REGEX.test(text))
|
||||
return [this.makeAlphanumeric(text)];
|
||||
else
|
||||
return [this.makeBytes(toUtf8ByteArray(text))];
|
||||
};
|
||||
|
||||
/*-- Constants --*/
|
||||
|
||||
var QrSegment = {}; // Private object to assign properties to
|
||||
|
|
|
@ -28,7 +28,6 @@ import itertools, re, sys
|
|||
"""
|
||||
Public members inside this module "qrcodegen":
|
||||
- Function encode_text(str text, QrCode.Ecc ecl) -> QrCode
|
||||
- Function encode_text_to_segment(str text) -> QrSegment
|
||||
- Function encode_binary(bytes data, QrCode.Ecc ecl) -> QrCode
|
||||
- Function encode_segments(list<QrSegment> segs, QrCode.Ecc ecl) -> QrCode
|
||||
- Class QrCode:
|
||||
|
@ -47,6 +46,7 @@ Public members inside this module "qrcodegen":
|
|||
- Function make_bytes(bytes data) -> QrSegment
|
||||
- Function make_numeric(str digits) -> QrSegment
|
||||
- Function make_alphanumeric(str text) -> QrSegment
|
||||
- Function make_segments(str text) -> list<QrSegment>
|
||||
- Constructor QrSegment(QrSegment.Mode mode, int numch, list<int> bitdata)
|
||||
- Method get_mode() -> QrSegment.Mode
|
||||
- Method get_num_chars() -> int
|
||||
|
@ -64,21 +64,8 @@ def encode_text(text, ecl):
|
|||
"""Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
|
||||
As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
|
||||
code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output."""
|
||||
seg = encode_text_to_segment(text)
|
||||
return encode_segments([seg], ecl)
|
||||
|
||||
|
||||
def encode_text_to_segment(text):
|
||||
"""Returns a QR segment representing the given Unicode text string."""
|
||||
if not isinstance(text, str) and (sys.version_info[0] >= 3 or not isinstance(text, unicode)):
|
||||
raise TypeError("Text string expected")
|
||||
# Select the most efficient segment encoding automatically
|
||||
if QrSegment.NUMERIC_REGEX.match(text) is not None:
|
||||
return QrSegment.make_numeric(text)
|
||||
elif QrSegment.ALPHANUMERIC_REGEX.match(text) is not None:
|
||||
return QrSegment.make_alphanumeric(text)
|
||||
else:
|
||||
return QrSegment.make_bytes(text.encode("UTF-8"))
|
||||
segs = QrSegment.make_segments(text)
|
||||
return encode_segments(segs, ecl)
|
||||
|
||||
|
||||
def encode_binary(data, ecl):
|
||||
|
@ -659,6 +646,24 @@ class QrSegment(object):
|
|||
return QrSegment(QrSegment.Mode.ALPHANUMERIC, len(text), bb.get_bits())
|
||||
|
||||
|
||||
@staticmethod
|
||||
def make_segments(text):
|
||||
"""Returns a new mutable list of zero or more segments to represent the given Unicode text string.
|
||||
The result may use various segment modes and switch modes to optimize the length of the bit stream."""
|
||||
if not isinstance(text, str) and (sys.version_info[0] >= 3 or not isinstance(text, unicode)):
|
||||
raise TypeError("Text string expected")
|
||||
|
||||
# Select the most efficient segment encoding automatically
|
||||
if text == "":
|
||||
return []
|
||||
elif QrSegment.NUMERIC_REGEX.match(text) is not None:
|
||||
return [QrSegment.make_numeric(text)]
|
||||
elif QrSegment.ALPHANUMERIC_REGEX.match(text) is not None:
|
||||
return [QrSegment.make_alphanumeric(text)]
|
||||
else:
|
||||
return [QrSegment.make_bytes(text.encode("UTF-8"))]
|
||||
|
||||
|
||||
# -- Constructor --
|
||||
|
||||
def __init__(self, mode, numch, bitdata):
|
||||
|
|
Loading…
Reference in New Issue