hrev44277 adds 2 changesets to branch 'master' old head: db744fca35a90986d1c3d061a5b81a803ffa7170 new head: e0ef5b2a972ffaab288c78e04bc9b657ad8badf0 ---------------------------------------------------------------------------- a86c7d0: Add qrwebpost to generate URLs for easier data collection. Using the qrwebpost debugger command one can initialize an id for subsequent QR codes. All QR codes generated following such an invokation produce URL QR codes that link to an online service that concatenates all data with the same id and later allows it to be displayed/downloaded in one piece. This makes collecting larger amounts of data more convenient. Note though that the URL encoding does waste space and therefore reduces data density, causing more QR codes to be generated for the same amount of input data. e0ef5b2: Allow aborting the command while QR codes are generated. [ Michael Lotz <mmlr@xxxxxxxx> ] ---------------------------------------------------------------------------- 1 file changed, 105 insertions(+), 6 deletions(-) src/add-ons/kernel/debugger/qrencode/module.cpp | 111 ++++++++++++++++++- ############################################################################ Commit: a86c7d0ab32920e70e98ac4437b45f26a63c4b06 URL: http://cgit.haiku-os.org/haiku/commit/?id=a86c7d0 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Jul 1 16:29:11 2012 UTC Add qrwebpost to generate URLs for easier data collection. Using the qrwebpost debugger command one can initialize an id for subsequent QR codes. All QR codes generated following such an invokation produce URL QR codes that link to an online service that concatenates all data with the same id and later allows it to be displayed/downloaded in one piece. This makes collecting larger amounts of data more convenient. Note though that the URL encoding does waste space and therefore reduces data density, causing more QR codes to be generated for the same amount of input data. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index 58751ca..f945a35 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -8,6 +8,7 @@ #include <debug.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -17,11 +18,15 @@ extern "C" { } +static const char* kWebPostBaseURL = "http://haiku.mlotz.ch/qrencode/store.php";; + static char sStringBuffer[16 * 1024]; static char sEncodeBuffer[3 * 1024]; static int sBufferPosition = 0; static int sQRCodeVersion = 19; static QRecLevel sQRCodeLevel = QR_ECLEVEL_L; +static char sWebPostId[64]; +static int sWebPostCounter = 0; static bool @@ -70,6 +75,50 @@ print_qrcode(QRcode* qrCode, bool waitForKey) static int +encode_url(const char* query, const char* data, int encodeLength, + int inputLength) +{ + sEncodeBuffer[0] = 0; + strlcat(sEncodeBuffer, kWebPostBaseURL, encodeLength + 1); + strlcat(sEncodeBuffer, "?id=", encodeLength + 1); + strlcat(sEncodeBuffer, sWebPostId, encodeLength + 1); + strlcat(sEncodeBuffer, "&", encodeLength + 1); + strlcat(sEncodeBuffer, query, encodeLength + 1); + int position = strlcat(sEncodeBuffer, "=", encodeLength + 1); + if (position > encodeLength) + return -1; + + int copyCount = 0; + while (inputLength > 0 && position < encodeLength) { + char character = data[copyCount]; + if ((character >= 'a' && character <= 'z') + || (character >= 'A' && character <= 'Z') + || (character >= '0' && character <= '9') + || character == '.' || character == '-' || character == '_' + || character == '~') { + sEncodeBuffer[position++] = character; + sEncodeBuffer[position] = 0; + } else { + // Encode to a %xx escape. + if (encodeLength - position < 3) { + // Doesn't fit anymore, we're done. + break; + } + + char escaped[4]; + sprintf(escaped, "%%%.2x", character); + position = strlcat(sEncodeBuffer, escaped, encodeLength + 1); + } + + inputLength--; + copyCount++; + } + + return copyCount; +} + + +static int qrencode(int argc, char* argv[]) { if (argc > 1 && strcmp(argv[1], "--help") == 0) { @@ -91,14 +140,25 @@ qrencode(int argc, char* argv[]) int inputLength = strlen(source); int encodeLength = QRspec_getDataLength(sQRCodeVersion, sQRCodeLevel) - 3; while (inputLength > 0) { - int copyCount = inputLength < encodeLength ? inputLength : encodeLength; - memcpy(sEncodeBuffer, source, copyCount); - sEncodeBuffer[copyCount] = 0; + int copyCount = 0; + if (sWebPostId[0] != 0) { + copyCount = encode_url(sWebPostCounter++ == 0 ? "clear" : "data", + source, encodeLength, inputLength); + if (copyCount < 0) { + kprintf("Failed to URL encode buffer.\n"); + QRcode_clearCache(); + return 1; + } + } else { + copyCount = inputLength < encodeLength ? inputLength : encodeLength; + memcpy(sEncodeBuffer, source, copyCount); + sEncodeBuffer[copyCount] = 0; + } QRcode* qrCode = QRcode_encodeString8bit(sEncodeBuffer, sQRCodeVersion, sQRCodeLevel); if (qrCode == NULL) { - kprintf("Failed to encode buffer into qr code\n"); + kprintf("Failed to encode buffer into qr code.\n"); QRcode_clearCache(); return 1; } @@ -222,6 +282,36 @@ qrconfig(int argc, char* argv[]) } +static int +qrwebpost(int argc, char* argv[]) +{ + if (argc >= 3 && strcmp(argv[1], "start") == 0) { + strlcpy(sWebPostId, argv[2], sizeof(sWebPostId)); + sWebPostCounter = 0; + + // Generate the clear code. + const char* args[2] = { "", "yes" }; + qrencode(2, (char**)args); + } else if (argc >= 2 && strcmp(argv[1], "stop") == 0) { + sWebPostId[0] = 0; + } else { + kprintf("%s start <id>\n", argv[0]); + kprintf("%s stop\n", argv[0]); + kprintf("Causes the QR codes to be rendered as URLs that resolve to\n" + "a service that allows appending the data of multiple QR codes\n" + "for easier handling.\n" + "An initial QR code is generated that invokes a clear operation\n" + "to prepare the output file on the server.\n" + "Note that there is no logic behind the service, if you and\n" + "someone else use the same id at the same time, they will\n" + "overwrite eachother. Therefore use a reasonably unique name.\n"); + return 1; + } + + return 0; +} + + static status_t std_ops(int32 op, ...) { @@ -237,6 +327,8 @@ std_ops(int32 op, ...) "encodes the current QR buffer and clears it"); add_debugger_command("qrconfig", qrconfig, "sets the QR code version to be used"); + add_debugger_command("qrwebpost", qrwebpost, + "sets up URL encoding for QR codes"); return B_OK; case B_MODULE_UNINIT: remove_debugger_command("qrencode", qrencode); @@ -244,6 +336,7 @@ std_ops(int32 op, ...) remove_debugger_command("qrclear", qrclear); remove_debugger_command("qrflush", qrflush); remove_debugger_command("qrconfig", qrconfig); + remove_debugger_command("qrwebpost", qrwebpost); return B_OK; } ############################################################################ Revision: hrev44277 Commit: e0ef5b2a972ffaab288c78e04bc9b657ad8badf0 URL: http://cgit.haiku-os.org/haiku/commit/?id=e0ef5b2 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Jul 1 16:53:37 2012 UTC Allow aborting the command while QR codes are generated. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index f945a35..8947067 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -18,6 +18,11 @@ extern "C" { } +extern "C" { +extern void abort_debugger_command(); +} + + static const char* kWebPostBaseURL = "http://haiku.mlotz.ch/qrencode/store.php";; static char sStringBuffer[16 * 1024]; @@ -68,8 +73,9 @@ print_qrcode(QRcode* qrCode, bool waitForKey) move_to_and_clear_line(qrCode->width / 2 + 3); if (waitForKey) { - kputs("press any key to continue...\x1b[1B\x1b[G"); - kgetc(); + kputs("press q to abort or any other key to continue...\x1b[1B\x1b[G"); + if (kgetc() == 'q') + abort_debugger_command(); } }