Removed the test worker program in every language and the Python batch tester, because this is not core functionality and is hard to explain.
parent
d4080974f2
commit
2261248957
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* QR Code generator test worker (C)
|
||||
*
|
||||
* This program reads data and encoding parameters from standard input and writes
|
||||
* QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
* Run with no command line arguments. The program is intended for automated
|
||||
* batch testing of end-to-end functionality of this QR Code generator library.
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "qrcodegen.h"
|
||||
|
||||
|
||||
int main(void) {
|
||||
while (true) {
|
||||
|
||||
// Read data length or exit
|
||||
size_t length;
|
||||
{
|
||||
int temp;
|
||||
if (scanf("%d", &temp) != 1)
|
||||
return EXIT_FAILURE;
|
||||
if (temp == -1)
|
||||
break;
|
||||
length = (size_t)temp;
|
||||
}
|
||||
|
||||
// Read data bytes
|
||||
bool isAscii = true;
|
||||
uint8_t *data = malloc(length * sizeof(uint8_t));
|
||||
if (data == NULL) {
|
||||
perror("malloc");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
int b;
|
||||
if (scanf("%d", &b) != 1)
|
||||
return EXIT_FAILURE;
|
||||
data[i] = (uint8_t)b;
|
||||
isAscii &= 0 < b && b < 128;
|
||||
}
|
||||
|
||||
// Read encoding parameters
|
||||
int errCorLvl, minVersion, maxVersion, mask, boostEcl;
|
||||
if (scanf("%d %d %d %d %d", &errCorLvl, &minVersion, &maxVersion, &mask, &boostEcl) != 5)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Allocate memory for QR Code
|
||||
size_t bufferLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);
|
||||
uint8_t *qrcode = malloc(bufferLen * sizeof(uint8_t));
|
||||
uint8_t *tempBuffer = malloc(bufferLen * sizeof(uint8_t));
|
||||
if (qrcode == NULL || tempBuffer == NULL) {
|
||||
perror("malloc");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Try to make QR Code symbol
|
||||
bool ok;
|
||||
if (isAscii) {
|
||||
char *text = malloc((length + 1) * sizeof(char));
|
||||
if (text == NULL) {
|
||||
perror("malloc");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (size_t i = 0; i < length; i++)
|
||||
text[i] = (char)data[i];
|
||||
text[length] = '\0';
|
||||
ok = qrcodegen_encodeText(text, tempBuffer, qrcode, (enum qrcodegen_Ecc)errCorLvl,
|
||||
minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
|
||||
free(text);
|
||||
} else if (length <= bufferLen) {
|
||||
memcpy(tempBuffer, data, length * sizeof(data[0]));
|
||||
ok = qrcodegen_encodeBinary(tempBuffer, length, qrcode, (enum qrcodegen_Ecc)errCorLvl,
|
||||
minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
|
||||
} else
|
||||
ok = false;
|
||||
free(data);
|
||||
free(tempBuffer);
|
||||
|
||||
if (ok) {
|
||||
// Print grid of modules
|
||||
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);
|
||||
}
|
||||
} else
|
||||
printf("-1\n");
|
||||
free(qrcode);
|
||||
fflush(stdout);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* QR Code generator test worker (C++)
|
||||
*
|
||||
* This program reads data and encoding parameters from standard input and writes
|
||||
* QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
* Run with no command line arguments. The program is intended for automated
|
||||
* batch testing of end-to-end functionality of this QR Code generator library.
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "qrcodegen.hpp"
|
||||
|
||||
using qrcodegen::QrCode;
|
||||
using qrcodegen::QrSegment;
|
||||
|
||||
|
||||
static const std::vector<QrCode::Ecc> ECC_LEVELS{
|
||||
QrCode::Ecc::LOW,
|
||||
QrCode::Ecc::MEDIUM,
|
||||
QrCode::Ecc::QUARTILE,
|
||||
QrCode::Ecc::HIGH,
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
while (true) {
|
||||
|
||||
// Read data length or exit
|
||||
int length;
|
||||
std::cin >> length;
|
||||
if (length == -1)
|
||||
break;
|
||||
|
||||
// Read data bytes
|
||||
bool isAscii = true;
|
||||
std::vector<uint8_t> data;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int b;
|
||||
std::cin >> b;
|
||||
data.push_back(static_cast<uint8_t>(b));
|
||||
isAscii &= 0 < b && b < 128;
|
||||
}
|
||||
|
||||
// Read encoding parameters
|
||||
int errCorLvl, minVersion, maxVersion, mask, boostEcl;
|
||||
std::cin >> errCorLvl;
|
||||
std::cin >> minVersion;
|
||||
std::cin >> maxVersion;
|
||||
std::cin >> mask;
|
||||
std::cin >> boostEcl;
|
||||
|
||||
// Make list of segments
|
||||
std::vector<QrSegment> segs;
|
||||
if (isAscii) {
|
||||
std::vector<char> text(data.cbegin(), data.cend());
|
||||
text.push_back('\0');
|
||||
segs = QrSegment::makeSegments(text.data());
|
||||
} else
|
||||
segs.push_back(QrSegment::makeBytes(data));
|
||||
|
||||
try { // Try to make QR Code symbol
|
||||
const QrCode qr = QrCode::encodeSegments(segs,
|
||||
ECC_LEVELS.at(static_cast<std::size_t>(errCorLvl)), minVersion, maxVersion, mask, boostEcl == 1);
|
||||
// Print grid of modules
|
||||
std::cout << qr.getVersion() << std::endl;
|
||||
for (int y = 0; y < qr.getSize(); y++) {
|
||||
for (int x = 0; x < qr.getSize(); x++)
|
||||
std::cout << (qr.getModule(x, y) ? 1 : 0) << std::endl;
|
||||
}
|
||||
|
||||
} catch (const qrcodegen::data_too_long &ex) {
|
||||
std::cout << -1 << std::endl;
|
||||
}
|
||||
std::cout << std::flush;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* QR Code generator test worker (Java)
|
||||
*
|
||||
* This program reads data and encoding parameters from standard input and writes
|
||||
* QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
* Run with no command line arguments. The program is intended for automated
|
||||
* batch testing of end-to-end functionality of this QR Code generator library.
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
package io.nayuki.qrcodegen;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
|
||||
public final class QrCodeGeneratorWorker {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Set up input stream and start loop
|
||||
try (Scanner input = new Scanner(System.in, "US-ASCII")) {
|
||||
input.useDelimiter("\r\n|\n|\r");
|
||||
while (processCase(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean processCase(Scanner input) {
|
||||
// Read data length or exit
|
||||
int length = input.nextInt();
|
||||
if (length == -1)
|
||||
return false;
|
||||
if (length > Short.MAX_VALUE)
|
||||
throw new RuntimeException();
|
||||
|
||||
// Read data bytes
|
||||
boolean isAscii = true;
|
||||
byte[] data = new byte[length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int b = input.nextInt();
|
||||
if (b < 0 || b > 255)
|
||||
throw new RuntimeException();
|
||||
data[i] = (byte)b;
|
||||
isAscii &= b < 128;
|
||||
}
|
||||
|
||||
// Read encoding parameters
|
||||
int errCorLvl = input.nextInt();
|
||||
int minVersion = input.nextInt();
|
||||
int maxVersion = input.nextInt();
|
||||
int mask = input.nextInt();
|
||||
int boostEcl = input.nextInt();
|
||||
if (!(0 <= errCorLvl && errCorLvl <= 3) || !(-1 <= mask && mask <= 7) || (boostEcl >>> 1) != 0
|
||||
|| !(QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= QrCode.MAX_VERSION))
|
||||
throw new RuntimeException();
|
||||
|
||||
// Make segments for encoding
|
||||
List<QrSegment> segs;
|
||||
if (isAscii)
|
||||
segs = QrSegment.makeSegments(new String(data, StandardCharsets.US_ASCII));
|
||||
else
|
||||
segs = Arrays.asList(QrSegment.makeBytes(data));
|
||||
|
||||
try { // Try to make QR Code symbol
|
||||
QrCode qr = QrCode.encodeSegments(segs, QrCode.Ecc.values()[errCorLvl], minVersion, maxVersion, mask, boostEcl != 0);
|
||||
// Print grid of modules
|
||||
System.out.println(qr.version);
|
||||
for (int y = 0; y < qr.size; y++) {
|
||||
for (int x = 0; x < qr.size; x++)
|
||||
System.out.println(qr.getModule(x, y) ? 1 : 0);
|
||||
}
|
||||
|
||||
} catch (DataTooLongException e) {
|
||||
System.out.println(-1);
|
||||
}
|
||||
System.out.flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
#
|
||||
# QR Code generator batch test (Python)
|
||||
#
|
||||
# Runs various versions of the QR Code generator test worker as subprocesses,
|
||||
# feeds each one the same random input, and compares their output for equality.
|
||||
#
|
||||
# Copyright (c) Project Nayuki. (MIT License)
|
||||
# https://www.nayuki.io/page/qr-code-generator-library
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
# - The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# - The Software is provided "as is", without warranty of any kind, express or
|
||||
# implied, including but not limited to the warranties of merchantability,
|
||||
# fitness for a particular purpose and noninfringement. In no event shall the
|
||||
# authors or copyright holders be liable for any claim, damages or other
|
||||
# liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
# out of or in connection with the Software or the use or other dealings in the
|
||||
# Software.
|
||||
#
|
||||
|
||||
import itertools, random, subprocess, sys, time
|
||||
from typing import List, Optional, TypeVar
|
||||
|
||||
|
||||
CHILD_PROGRAMS: List[List[str]] = [
|
||||
["python3", "-B", "../python/qrcodegen-worker.py"], # Python program
|
||||
["java", "-cp", "../java/bin", "-ea:io.nayuki.qrcodegen...", "io/nayuki/qrcodegen/QrCodeGeneratorWorker"], # Java program
|
||||
["node", "../typescript-javascript/qrcodegen-worker.js"], # TypeScript program
|
||||
["../c/qrcodegen-worker"], # C program
|
||||
["../cpp/QrCodeGeneratorWorker"], # C++ program
|
||||
["../rust/target/debug/examples/qrcodegen-worker"], # Rust program
|
||||
]
|
||||
|
||||
|
||||
subprocs: List[subprocess.Popen] = []
|
||||
|
||||
def main() -> None:
|
||||
# Launch workers
|
||||
global subprocs
|
||||
try:
|
||||
for args in CHILD_PROGRAMS:
|
||||
subprocs.append(subprocess.Popen(args, universal_newlines=True,
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE))
|
||||
except FileNotFoundError:
|
||||
write_all(-1)
|
||||
raise
|
||||
|
||||
# Check if any died
|
||||
time.sleep(0.3)
|
||||
if any(proc.poll() is not None for proc in subprocs):
|
||||
for proc in subprocs:
|
||||
if proc.poll() is None:
|
||||
print(-1, file=proc.stdin)
|
||||
not_none(proc.stdin).flush()
|
||||
sys.exit("Error: One or more workers failed to start")
|
||||
|
||||
# Do tests
|
||||
for i in itertools.count():
|
||||
print("Trial {}: ".format(i), end="")
|
||||
do_trial()
|
||||
print()
|
||||
|
||||
|
||||
def do_trial() -> None:
|
||||
mode: int = random.randrange(4)
|
||||
length: int
|
||||
data: List[int]
|
||||
if mode == 0: # Numeric
|
||||
length = round((2 * 7089) ** random.random())
|
||||
data = random.choices(b"0123456789", k=length)
|
||||
elif mode == 1: # Alphanumeric
|
||||
length = round((2 * 4296) ** random.random())
|
||||
data = random.choices(b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:", k=length)
|
||||
elif mode == 2: # ASCII
|
||||
length = round((2 * 2953) ** random.random())
|
||||
data = [random.randrange(128) for _ in range(length)]
|
||||
elif mode == 3: # Byte
|
||||
length = round((2 * 2953) ** random.random())
|
||||
data = [random.randrange(256) for _ in range(length)]
|
||||
else:
|
||||
raise AssertionError()
|
||||
|
||||
write_all(length)
|
||||
for b in data:
|
||||
write_all(b)
|
||||
|
||||
errcorlvl: int = random.randrange(4)
|
||||
minversion: int = random.randint(1, 40)
|
||||
maxversion: int = random.randint(1, 40)
|
||||
if minversion > maxversion:
|
||||
minversion, maxversion = maxversion, minversion
|
||||
mask: int = -1
|
||||
if random.random() < 0.5:
|
||||
mask = random.randrange(8)
|
||||
boostecl = int(random.random() < 0.2)
|
||||
print("mode={} len={} ecl={} minv={} maxv={} mask={} boost={}".format(mode, length, errcorlvl, minversion, maxversion, mask, boostecl), end="")
|
||||
|
||||
write_all(errcorlvl)
|
||||
write_all(minversion)
|
||||
write_all(maxversion)
|
||||
write_all(mask)
|
||||
write_all(boostecl)
|
||||
flush_all()
|
||||
|
||||
version: int = read_verify()
|
||||
print(" version={}".format(version), end="")
|
||||
if version == -1:
|
||||
return
|
||||
size: int = version * 4 + 17
|
||||
for _ in range(size**2):
|
||||
read_verify()
|
||||
|
||||
|
||||
def write_all(val: int) -> None:
|
||||
for proc in subprocs:
|
||||
print(val, file=proc.stdin)
|
||||
|
||||
def flush_all() -> None:
|
||||
for proc in subprocs:
|
||||
not_none(proc.stdin).flush()
|
||||
|
||||
def read_verify() -> int:
|
||||
val: str = not_none(subprocs[0].stdout).readline().rstrip("\r\n")
|
||||
for proc in subprocs[1 : ]:
|
||||
if not_none(proc.stdout).readline().rstrip("\r\n") != val:
|
||||
raise ValueError("Mismatch")
|
||||
return int(val)
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
def not_none(obj: Optional[T]) -> T:
|
||||
if obj is None:
|
||||
raise TypeError()
|
||||
return obj
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,82 +0,0 @@
|
||||
#
|
||||
# QR Code generator test worker (Python)
|
||||
#
|
||||
# This program reads data and encoding parameters from standard input and writes
|
||||
# QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
# Run with no command line arguments. The program is intended for automated
|
||||
# batch testing of end-to-end functionality of this QR Code generator library.
|
||||
#
|
||||
# Copyright (c) Project Nayuki. (MIT License)
|
||||
# https://www.nayuki.io/page/qr-code-generator-library
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
# - The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# - The Software is provided "as is", without warranty of any kind, express or
|
||||
# implied, including but not limited to the warranties of merchantability,
|
||||
# fitness for a particular purpose and noninfringement. In no event shall the
|
||||
# authors or copyright holders be liable for any claim, damages or other
|
||||
# liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
# out of or in connection with the Software or the use or other dealings in the
|
||||
# Software.
|
||||
#
|
||||
|
||||
import sys
|
||||
from typing import List, Sequence
|
||||
import qrcodegen
|
||||
|
||||
|
||||
def read_int() -> int:
|
||||
return int(input())
|
||||
|
||||
|
||||
def main() -> None:
|
||||
while True:
|
||||
|
||||
# Read data or exit
|
||||
length: int = read_int()
|
||||
if length == -1:
|
||||
break
|
||||
data = bytearray(read_int() for _ in range(length))
|
||||
|
||||
# Read encoding parameters
|
||||
errcorlvl : int = read_int()
|
||||
minversion: int = read_int()
|
||||
maxversion: int = read_int()
|
||||
mask : int = read_int()
|
||||
boostecl : int = read_int()
|
||||
|
||||
# Make segments for encoding
|
||||
if all((b < 128) for b in data): # Is ASCII
|
||||
segs: List[qrcodegen.QrSegment] = qrcodegen.QrSegment.make_segments(data.decode("ASCII"))
|
||||
else:
|
||||
segs = [qrcodegen.QrSegment.make_bytes(data)]
|
||||
|
||||
try: # Try to make QR Code symbol
|
||||
qr: qrcodegen.QrCode = qrcodegen.QrCode.encode_segments(segs, ECC_LEVELS[errcorlvl], minversion, maxversion, mask, boostecl != 0)
|
||||
# Print grid of modules
|
||||
print(qr.get_version())
|
||||
for y in range(qr.get_size()):
|
||||
for x in range(qr.get_size()):
|
||||
print(1 if qr.get_module(x, y) else 0)
|
||||
|
||||
except qrcodegen.DataTooLongError:
|
||||
print(-1)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
ECC_LEVELS: Sequence[qrcodegen.QrCode.Ecc] = (
|
||||
qrcodegen.QrCode.Ecc.LOW,
|
||||
qrcodegen.QrCode.Ecc.MEDIUM,
|
||||
qrcodegen.QrCode.Ecc.QUARTILE,
|
||||
qrcodegen.QrCode.Ecc.HIGH,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* QR Code generator test worker (Rust)
|
||||
*
|
||||
* This program reads data and encoding parameters from standard input and writes
|
||||
* QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
* Run with no command line arguments. The program is intended for automated
|
||||
* batch testing of end-to-end functionality of this QR Code generator library.
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
extern crate qrcodegen;
|
||||
use qrcodegen::Mask;
|
||||
use qrcodegen::QrCode;
|
||||
use qrcodegen::QrCodeEcc;
|
||||
use qrcodegen::QrSegment;
|
||||
use qrcodegen::Version;
|
||||
|
||||
|
||||
fn main() {
|
||||
loop {
|
||||
|
||||
// Read data length or exit
|
||||
let length: i16 = read_int();
|
||||
if length == -1 {
|
||||
break;
|
||||
}
|
||||
|
||||
// Read data bytes
|
||||
let mut data = Vec::<u8>::with_capacity(length as usize);
|
||||
for _ in 0 .. length {
|
||||
let b: i16 = read_int();
|
||||
assert_eq!(i16::from(b as u8), b, "Byte value out of range");
|
||||
data.push(b as u8);
|
||||
}
|
||||
let isascii: bool = data.iter().all(|b| *b < 128);
|
||||
|
||||
// Read encoding parameters
|
||||
let errcorlvl = read_int();
|
||||
let minversion = read_int();
|
||||
let maxversion = read_int();
|
||||
let mask = read_int();
|
||||
let boostecl = read_int();
|
||||
assert!(0 <= errcorlvl && errcorlvl <= 3);
|
||||
assert!(i16::from(Version::MIN.value()) <= minversion
|
||||
&& minversion <= maxversion
|
||||
&& maxversion <= i16::from(Version::MAX.value()));
|
||||
assert!(-1 <= mask && mask <= 7);
|
||||
assert!(boostecl >> 1 == 0);
|
||||
|
||||
// Make segments for encoding
|
||||
let segs: Vec<QrSegment> = if isascii {
|
||||
let chrs: Vec<char> = std::str::from_utf8(&data).unwrap().chars().collect();
|
||||
QrSegment::make_segments(&chrs)
|
||||
} else {
|
||||
vec![QrSegment::make_bytes(&data)]
|
||||
};
|
||||
|
||||
// Try to make QR Code symbol
|
||||
let msk = if mask == -1 { None } else { Some(Mask::new(mask as u8)) };
|
||||
match QrCode::encode_segments_advanced(&segs, ECC_LEVELS[errcorlvl as usize],
|
||||
Version::new(minversion as u8), Version::new(maxversion as u8), msk, boostecl != 0) {
|
||||
|
||||
Ok(qr) => {
|
||||
// Print grid of modules
|
||||
println!("{}", qr.version().value());
|
||||
for y in 0 .. qr.size() {
|
||||
for x in 0 .. qr.size() {
|
||||
println!("{}", qr.get_module(x, y) as i8);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => println!("-1"),
|
||||
}
|
||||
use std::io::Write;
|
||||
std::io::stdout().flush().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn read_int() -> i16 {
|
||||
let mut line = String::new();
|
||||
std::io::stdin().read_line(&mut line).unwrap();
|
||||
let mut chrs: Vec<char> = line.chars().collect();
|
||||
assert_eq!(chrs.pop().unwrap(), '\n');
|
||||
let line: String = chrs.iter().cloned().collect();
|
||||
line.parse::<i16>().expect("Invalid number")
|
||||
}
|
||||
|
||||
|
||||
static ECC_LEVELS: [QrCodeEcc; 4] = [
|
||||
QrCodeEcc::Low,
|
||||
QrCodeEcc::Medium,
|
||||
QrCodeEcc::Quartile,
|
||||
QrCodeEcc::High,
|
||||
];
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* QR Code generator test worker (TypeScript)
|
||||
*
|
||||
* This program reads data and encoding parameters from standard input and writes
|
||||
* QR Code bitmaps to standard output. The I/O format is one integer per line.
|
||||
* Run with no command line arguments. The program is intended for automated
|
||||
* batch testing of end-to-end functionality of this QR Code generator library.
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
async function main(): Promise<void> {
|
||||
while (true) {
|
||||
// Read data or exit
|
||||
const length: number = await input.readInt();
|
||||
if (length == -1)
|
||||
break;
|
||||
let data: Array<number> = [];
|
||||
for (let i = 0; i < length; i++)
|
||||
data.push(await input.readInt());
|
||||
|
||||
// Read encoding parameters
|
||||
const errCorLvl : number = await input.readInt();
|
||||
const minVersion: number = await input.readInt();
|
||||
const maxVersion: number = await input.readInt();
|
||||
const mask : number = await input.readInt();
|
||||
const boostEcl : number = await input.readInt();
|
||||
|
||||
// Make segments for encoding
|
||||
let segs: Array<qrcodegen.QrSegment>;
|
||||
if (data.every(b => b < 128)) { // Is ASCII
|
||||
const s: string = data.map(b => String.fromCharCode(b)).join("");
|
||||
segs = qrcodegen.QrSegment.makeSegments(s);
|
||||
} else
|
||||
segs = [qrcodegen.QrSegment.makeBytes(data)];
|
||||
|
||||
try { // Try to make QR Code symbol
|
||||
const qr = qrcodegen.QrCode.encodeSegments(
|
||||
segs, ECC_LEVELS[errCorLvl], minVersion, maxVersion, mask, boostEcl != 0);
|
||||
// Print grid of modules
|
||||
await printLine(qr.version);
|
||||
for (let y = 0; y < qr.size; y++) {
|
||||
for (let x = 0; x < qr.size; x++)
|
||||
await printLine(qr.getModule(x, y) ? 1 : 0);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (e == "Data too long")
|
||||
await printLine(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace input {
|
||||
|
||||
let queue: Array<string> = [];
|
||||
let callback: ((line:string)=>void)|null = null;
|
||||
|
||||
const readline = require("readline");
|
||||
let reader = readline.createInterface({
|
||||
input: process.stdin,
|
||||
terminal: false,
|
||||
});
|
||||
reader.on("line", (line: string) => {
|
||||
queue.push(line);
|
||||
if (callback !== null) {
|
||||
callback(queue.shift() as string);
|
||||
callback = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
async function readLine(): Promise<string> {
|
||||
return new Promise(resolve => {
|
||||
if (callback !== null)
|
||||
throw "Illegal state";
|
||||
if (queue.length > 0)
|
||||
resolve(queue.shift() as string);
|
||||
else
|
||||
callback = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export async function readInt(): Promise<number> {
|
||||
let s = await readLine();
|
||||
if (!/^-?\d+$/.test(s))
|
||||
throw "Invalid number syntax";
|
||||
return parseInt(s, 10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
async function printLine(x: Object): Promise<void> {
|
||||
return new Promise(resolve =>
|
||||
process.stdout.write(x + "\n", "utf-8", ()=>resolve()));
|
||||
}
|
||||
|
||||
|
||||
const ECC_LEVELS: Array<qrcodegen.QrCode.Ecc> = [
|
||||
qrcodegen.QrCode.Ecc.LOW,
|
||||
qrcodegen.QrCode.Ecc.MEDIUM,
|
||||
qrcodegen.QrCode.Ecc.QUARTILE,
|
||||
qrcodegen.QrCode.Ecc.HIGH,
|
||||
];
|
||||
|
||||
|
||||
main();
|
Loading…
Reference in new issue