1/* 2 * QR Code generator test worker (TypeScript) 3 * 4 * This program reads data and encoding parameters from standard input and writes 5 * QR Code bitmaps to standard output. The I/O format is one integer per line. 6 * Run with no command line arguments. The program is intended for automated 7 * batch testing of end-to-end functionality of this QR Code generator library. 8 * 9 * Copyright (c) Project Nayuki. (MIT License) 10 * https://www.nayuki.io/page/qr-code-generator-library 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 * this software and associated documentation files (the "Software"), to deal in 14 * the Software without restriction, including without limitation the rights to 15 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 * the Software, and to permit persons to whom the Software is furnished to do so, 17 * subject to the following conditions: 18 * - The above copyright notice and this permission notice shall be included in 19 * all copies or substantial portions of the Software. 20 * - The Software is provided "as is", without warranty of any kind, express or 21 * implied, including but not limited to the warranties of merchantability, 22 * fitness for a particular purpose and noninfringement. In no event shall the 23 * authors or copyright holders be liable for any claim, damages or other 24 * liability, whether in an action of contract, tort or otherwise, arising from, 25 * out of or in connection with the Software or the use or other dealings in the 26 * Software. 27 */ 28 29"use strict"; 30 31 32async function main(): Promise<void> { 33 while (true) { 34 // Read data or exit 35 const length: number = await input.readInt(); 36 if (length == -1) 37 break; 38 let data: Array<number> = []; 39 for (let i = 0; i < length; i++) 40 data.push(await input.readInt()); 41 42 // Read encoding parameters 43 const errCorLvl : number = await input.readInt(); 44 const minVersion: number = await input.readInt(); 45 const maxVersion: number = await input.readInt(); 46 const mask : number = await input.readInt(); 47 const boostEcl : number = await input.readInt(); 48 49 // Make segments for encoding 50 let segs: Array<qrcodegen.QrSegment>; 51 if (data.every(b => b < 128)) { // Is ASCII 52 const s: string = data.map(b => String.fromCharCode(b)).join(""); 53 segs = qrcodegen.QrSegment.makeSegments(s); 54 } else 55 segs = [qrcodegen.QrSegment.makeBytes(data)]; 56 57 try { // Try to make QR Code symbol 58 const qr = qrcodegen.QrCode.encodeSegments( 59 segs, ECC_LEVELS[errCorLvl], minVersion, maxVersion, mask, boostEcl != 0); 60 // Print grid of modules 61 await printLine(qr.version); 62 for (let y = 0; y < qr.size; y++) { 63 for (let x = 0; x < qr.size; x++) 64 await printLine(qr.getModule(x, y) ? 1 : 0); 65 } 66 67 } catch (e) { 68 if (e == "Data too long") 69 await printLine(-1); 70 } 71 } 72} 73 74 75namespace input { 76 77 let queue: Array<string> = []; 78 let callback: ((line:string)=>void)|null = null; 79 80 const readline = require("readline"); 81 let reader = readline.createInterface({ 82 input: process.stdin, 83 terminal: false, 84 }); 85 reader.on("line", (line: string) => { 86 queue.push(line); 87 if (callback !== null) { 88 callback(queue.shift() as string); 89 callback = null; 90 } 91 }); 92 93 94 async function readLine(): Promise<string> { 95 return new Promise(resolve => { 96 if (callback !== null) 97 throw "Illegal state"; 98 if (queue.length > 0) 99 resolve(queue.shift() as string); 100 else 101 callback = resolve; 102 }); 103 } 104 105 106 export async function readInt(): Promise<number> { 107 let s = await readLine(); 108 if (!/^-?\d+$/.test(s)) 109 throw "Invalid number syntax"; 110 return parseInt(s, 10); 111 } 112 113} 114 115 116async function printLine(x: Object): Promise<void> { 117 return new Promise(resolve => 118 process.stdout.write(x + "\n", "utf-8", ()=>resolve())); 119} 120 121 122const ECC_LEVELS: Array<qrcodegen.QrCode.Ecc> = [ 123 qrcodegen.QrCode.Ecc.LOW, 124 qrcodegen.QrCode.Ecc.MEDIUM, 125 qrcodegen.QrCode.Ecc.QUARTILE, 126 qrcodegen.QrCode.Ecc.HIGH, 127]; 128 129 130main(); 131