Simplified/deoptimized C++ code to use string search instead of lookup table for alphanumeric mode encoding. Also tightened the error checking in QrSegment::makeAlphanumeric(). As a side effect this now makes text encoding correct on non-ASCII systems (e.g. EBCDIC).

This commit is contained in:
Project Nayuki 2017-05-08 06:10:56 +00:00
parent 50c1a6b8af
commit 106e31d9c7
2 changed files with 8 additions and 13 deletions

View File

@ -23,6 +23,7 @@
#include <climits>
#include <cstddef>
#include <cstring>
#include "BitBuffer.hpp"
#include "QrSegment.hpp"
@ -91,10 +92,10 @@ QrSegment QrSegment::makeAlphanumeric(const char *text) {
int accumCount = 0;
int charCount = 0;
for (; *text != '\0'; text++, charCount++) {
char c = *text;
if (c < ' ' || c > 'Z')
const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text);
if (temp == nullptr)
throw "String contains unencodable characters in alphanumeric mode";
accumData = accumData * 45 + ALPHANUMERIC_ENCODING_TABLE[c - ' '];
accumData = accumData * 45 + (temp - ALPHANUMERIC_CHARSET);
accumCount++;
if (accumCount == 2) {
bb.appendBits(accumData, 11);
@ -157,8 +158,7 @@ int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
bool QrSegment::isAlphanumeric(const char *text) {
for (; *text != '\0'; text++) {
char c = *text;
if (c < ' ' || c > 'Z' || ALPHANUMERIC_ENCODING_TABLE[c - ' '] == -1)
if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr)
return false;
}
return true;
@ -175,11 +175,6 @@ bool QrSegment::isNumeric(const char *text) {
}
const int8_t QrSegment::ALPHANUMERIC_ENCODING_TABLE[59] = {
// SP, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, // ASCII codes 32 to 64
36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, -1, // Array indices 0 to 32
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // Array indices 33 to 58
// A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, // ASCII codes 65 to 90
};
const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
}

View File

@ -150,8 +150,8 @@ class QrSegment final {
/*---- Private constant ----*/
/* Maps shifted ASCII codes to alphanumeric mode character codes. */
private: static const int8_t ALPHANUMERIC_ENCODING_TABLE[59];
/* The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string. */
private: static const char *ALPHANUMERIC_CHARSET;
};