Changed C API functions qrcodegen_encodeText() and qrcodegen_encodeBinary() to return boolean status instead of integer version number, updated runnable programs to work with modified API.

This commit is contained in:
Project Nayuki 2017-04-25 06:15:11 +00:00
parent 767084b80d
commit 546029090c
4 changed files with 48 additions and 40 deletions

View File

@ -53,9 +53,9 @@ static void doBasicDemo() {
// Make and print the QR Code symbol
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version = qrcodegen_encodeText(text, tempBuffer, qrcode, errCorLvl,
bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
@ -65,27 +65,27 @@ static void doVarietyDemo() {
{ // Project Nayuki URL
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
bool ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_3, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
{ // Numeric mode encoding (3.33 bits per digit)
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version = qrcodegen_encodeText("314159265358979323846264338327950288419716939937510", tempBuffer, qrcode,
bool ok = qrcodegen_encodeText("314159265358979323846264338327950288419716939937510", tempBuffer, qrcode,
qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
{ // Alphanumeric mode encoding (5.5 bits per character)
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version = qrcodegen_encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", tempBuffer, qrcode,
bool ok = qrcodegen_encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
@ -93,26 +93,26 @@ static void doVarietyDemo() {
const char *text = "\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1wa\xE3\x80\x81\xE4\xB8\x96\xE7\x95\x8C\xEF\xBC\x81\x20\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4";
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version;
bool ok;
version = qrcodegen_encodeText(text, tempBuffer, qrcode,
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_0, true);
if (version != 0)
if (ok)
printQr(qrcode);
version = qrcodegen_encodeText(text, tempBuffer, qrcode,
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_1, true);
if (version != 0)
if (ok)
printQr(qrcode);
version = qrcodegen_encodeText(text, tempBuffer, qrcode,
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_5, true);
if (version != 0)
if (ok)
printQr(qrcode);
version = qrcodegen_encodeText(text, tempBuffer, qrcode,
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_7, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
@ -127,9 +127,9 @@ static void doVarietyDemo() {
"a White Rabbit with pink eyes ran close by her.";
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
int version = qrcodegen_encodeText(text, tempBuffer, qrcode,
bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (version != 0)
if (ok)
printQr(qrcode);
}
}

View File

@ -74,31 +74,31 @@ int main(void) {
}
// Try to make QR Code symbol
int version;
bool ok;
if (isAscii) {
char *text = malloc((length + 1) * sizeof(char));
for (int i = 0; i < length; i++)
text[i] = (char)data[i];
text[length] = '\0';
version = qrcodegen_encodeText(text, tempBuffer, qrcode, (enum qrcodegen_Ecc)errCorLvl,
ok = qrcodegen_encodeText(text, tempBuffer, qrcode, (enum qrcodegen_Ecc)errCorLvl,
minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
free(text);
} else if (length <= bufferLen) {
for (int i = 0; i < length; i++)
tempBuffer[i] = data[i];
version = qrcodegen_encodeBinary(tempBuffer, (size_t)length, qrcode, (enum qrcodegen_Ecc)errCorLvl,
ok = qrcodegen_encodeBinary(tempBuffer, (size_t)length, qrcode, (enum qrcodegen_Ecc)errCorLvl,
minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
} else
version = 0;
ok = false;
free(data);
free(tempBuffer);
// Print grid of modules
if (version == 0)
if (!ok)
printf("-1\n");
else {
printf("%d\n", version);
int size = qrcodegen_getSize(qrcode);
printf("%d\n", (size - 17) / 4);
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++)
printf("%d\n", qrcodegen_getModule(qrcode, x, y) ? 1 : 0);

View File

@ -108,7 +108,7 @@ static const int PENALTY_N4 = 10;
/*---- High-level QR Code encoding functions ----*/
// Public function - see documentation comment in header file.
int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX);
assert(0 <= (int)ecl && (int)ecl <= 3 && -1 <= (int)mask && (int)mask <= 7);
@ -118,11 +118,11 @@ int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[
int textBits;
int textLen = getTextProperties(text, &isNumeric, &isAlphanumeric, &textBits);
if (textLen < 0)
return 0;
goto fail;
if (!isAlphanumeric) { // Fully handle in binary mode
if (textLen > qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion))
return 0;
goto fail;
for (int i = 0; i < textLen; i++)
tempBuffer[i] = (uint8_t)text[i];
return qrcodegen_encodeBinary(tempBuffer, (size_t)textLen, qrcode, ecl, minVersion, maxVersion, mask, boostEcl);
@ -131,7 +131,7 @@ int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[
int version = fitVersionToData(minVersion, maxVersion, ecl, textLen, (int)textBits,
(isNumeric ? 10 : 9), (isNumeric ? 12 : 11), (isNumeric ? 14 : 13));
if (version == 0)
return 0;
goto fail;
memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
int bitLen = 0;
@ -175,23 +175,27 @@ int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[
// Make QR Code
encodeQrCodeTail(qrcode, bitLen, tempBuffer, version, ecl, mask, boostEcl);
return version;
return true;
fail:
qrcode[0] = 0; // An invalid size value for safety
return false;
}
// Public function - see documentation comment in header file.
int qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX);
assert(0 <= (int)ecl && (int)ecl <= 3 && -1 <= (int)mask && (int)mask <= 7);
// Check length and find version
if (dataLen > INT16_MAX / 8)
return 0;
goto fail;
// Now dataLen * 8 <= 32767 <= INT_MAX
int version = fitVersionToData(minVersion, maxVersion, ecl, (int)dataLen, (int)dataLen * 8, 8, 16, 16);
if (version == 0)
return 0;
goto fail;
// Make bit sequence and QR Code
memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
@ -201,7 +205,11 @@ int qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode
for (size_t i = 0; i < dataLen; i++)
appendBitsToBuffer(dataAndTemp[i], 8, qrcode, &bitLen);
encodeQrCodeTail(qrcode, bitLen, dataAndTemp, version, ecl, mask, boostEcl);
return version;
return true;
fail:
qrcode[0] = 0; // An invalid size value for safety
return false;
}

View File

@ -77,24 +77,24 @@ enum qrcodegen_Mask {
/*---- Top-level QR Code functions ----*/
/*
* Encodes the given text data to a QR Code symbol, returning the actual version number used.
* Encodes the given text data to a QR Code symbol, returning whether encoding succeeded.
* If the data is too long to fit in any version in the given range at the given ECC level,
* then 0 is returned. Both dataAndTemp and qrcode each must have length at least
* then false is returned. Both dataAndTemp and qrcode each must have length at least
* qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). The text must be encoded in UTF-8.
* The resulting QR Code may use numeric, alphanumeric, or byte mode to encode the text.
*/
int qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
/*
* Encodes the given binary data to a QR Code symbol, returning the actual version number used.
* Encodes the given binary data to a QR Code symbol, returning whether encoding succeeded.
* If the data is too long to fit in any version in the given range at the given ECC level,
* then 0 is returned. dataAndTemp[0 : dataLen] represents the input data, and the function
* then false is returned. dataAndTemp[0 : dataLen] represents the input data, and the function
* may overwrite the array's contents as a temporary work area. Both dataAndTemp and qrcode
* must have length at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion).
*/
int qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);