From 106e31d9c7f2a9d6a894248844a7d514ad567ddc Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Mon, 8 May 2017 06:10:56 +0000 Subject: [PATCH] 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). --- cpp/QrSegment.cpp | 17 ++++++----------- cpp/QrSegment.hpp | 4 ++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/cpp/QrSegment.cpp b/cpp/QrSegment.cpp index 0070f48..b2cec89 100644 --- a/cpp/QrSegment.cpp +++ b/cpp/QrSegment.cpp @@ -23,6 +23,7 @@ #include #include +#include #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 &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 $%*+-./:"; } diff --git a/cpp/QrSegment.hpp b/cpp/QrSegment.hpp index e1b7455..65a416f 100644 --- a/cpp/QrSegment.hpp +++ b/cpp/QrSegment.hpp @@ -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; };