From 546029090c657ac6db30f1ec070f105dbbdee602 Mon Sep 17 00:00:00 2001
From: Project Nayuki <me@nayuki.io>
Date: Tue, 25 Apr 2017 06:15:11 +0000
Subject: [PATCH] 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.

---
 c/qrcodegen-demo.c   | 38 +++++++++++++++++++-------------------
 c/qrcodegen-worker.c | 12 ++++++------
 c/qrcodegen.c        | 26 +++++++++++++++++---------
 c/qrcodegen.h        | 12 ++++++------
 4 files changed, 48 insertions(+), 40 deletions(-)

diff --git a/c/qrcodegen-demo.c b/c/qrcodegen-demo.c
index 3af9b72..2227e23 100644
--- a/c/qrcodegen-demo.c
+++ b/c/qrcodegen-demo.c
@@ -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);
 	}
 }
diff --git a/c/qrcodegen-worker.c b/c/qrcodegen-worker.c
index e18a426..43d50c0 100644
--- a/c/qrcodegen-worker.c
+++ b/c/qrcodegen-worker.c
@@ -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);
diff --git a/c/qrcodegen.c b/c/qrcodegen.c
index 01fb9b0..33fb7d9 100644
--- a/c/qrcodegen.c
+++ b/c/qrcodegen.c
@@ -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;
 }
 
 
diff --git a/c/qrcodegen.h b/c/qrcodegen.h
index 9b75047..7d925ad 100644
--- a/c/qrcodegen.h
+++ b/c/qrcodegen.h
@@ -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);