From df729db98bb9a4a7dbf1b18bb30891d634e820a4 Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Mon, 5 Nov 2018 04:37:57 +0000 Subject: [PATCH] Added "data too long" exception class, changed code to make use of it, updated Javadoc comments. --- .../fastqrcodegen/DataTooLongException.java | 57 +++++++++++++++++++ src/io/nayuki/fastqrcodegen/QrCode.java | 19 ++++--- .../fastqrcodegen/QrCodeGeneratorWorker.java | 4 +- .../fastqrcodegen/QrSegmentAdvanced.java | 15 +++-- 4 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 src/io/nayuki/fastqrcodegen/DataTooLongException.java diff --git a/src/io/nayuki/fastqrcodegen/DataTooLongException.java b/src/io/nayuki/fastqrcodegen/DataTooLongException.java new file mode 100644 index 0000000..c6e4444 --- /dev/null +++ b/src/io/nayuki/fastqrcodegen/DataTooLongException.java @@ -0,0 +1,57 @@ +/* + * Fast QR Code generator library + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/fast-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.fastqrcodegen; + + +/** + * Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception include: + * + * @see QrCode#encodeText(String, QrCode.Ecc) + * @see QrCode#encodeBinary(byte[], QrCode.Ecc) + * @see QrCode#encodeSegments(java.util.List, QrCode.Ecc) + * @see QrCode#encodeSegments(java.util.List, QrCode.Ecc, int, int, int, boolean) + * @see QrSegmentAdvanced#makeSegmentsOptimally(String, QrCode.Ecc, int, int) + */ +public class DataTooLongException extends IllegalArgumentException { + + public DataTooLongException() {} + + + public DataTooLongException(String msg) { + super(msg); + } + +} diff --git a/src/io/nayuki/fastqrcodegen/QrCode.java b/src/io/nayuki/fastqrcodegen/QrCode.java index 091bec5..c24aae4 100644 --- a/src/io/nayuki/fastqrcodegen/QrCode.java +++ b/src/io/nayuki/fastqrcodegen/QrCode.java @@ -64,7 +64,7 @@ public final class QrCode { * @param ecl the error correction level to use (not {@code null}) (boostable) * @return a QR Code (not {@code null}) representing the text * @throws NullPointerException if the text or error correction level is {@code null} - * @throws IllegalArgumentException if the text fails to fit in the + * @throws DataTooLongException if the text fails to fit in the * largest version QR Code at the ECL, which means it is too long */ public static QrCode encodeText(String text, Ecc ecl) { @@ -84,7 +84,7 @@ public final class QrCode { * @param ecl the error correction level to use (not {@code null}) (boostable) * @return a QR Code (not {@code null}) representing the data * @throws NullPointerException if the data or error correction level is {@code null} - * @throws IllegalArgumentException if the data fails to fit in the + * @throws DataTooLongException if the data fails to fit in the * largest version QR Code at the ECL, which means it is too long */ public static QrCode encodeBinary(byte[] data, Ecc ecl) { @@ -109,7 +109,7 @@ public final class QrCode { * @param ecl the error correction level to use (not {@code null}) (boostable) * @return a QR Code (not {@code null}) representing the segments * @throws NullPointerException if the list of segments, any segment, or the error correction level is {@code null} - * @throws IllegalArgumentException if the segments fail to fit in the + * @throws DataTooLongException if the segments fail to fit in the * largest version QR Code at the ECL, which means they are too long */ public static QrCode encodeSegments(List segs, Ecc ecl) { @@ -137,8 +137,9 @@ public final class QrCode { * @return a QR Code (not {@code null}) representing the segments * @throws NullPointerException if the list of segments, any segment, or the error correction level is {@code null} * @throws IllegalArgumentException if 1 ≤ minVersion ≤ maxVersion ≤ 40 - * or −1 ≤ mask ≤ 7 is violated; or if the segments fail to - * fit in the maxVersion QR Code at the ECL, which means they are too long + * or −1 ≤ mask ≤ 7 is violated + * @throws DataTooLongException if the segments fail to fit in + * the maxVersion QR Code at the ECL, which means they are too long */ public static QrCode encodeSegments(List segs, Ecc ecl, int minVersion, int maxVersion, int mask, boolean boostEcl) { Objects.requireNonNull(segs); @@ -153,8 +154,12 @@ public final class QrCode { dataUsedBits = QrSegment.getTotalBits(segs, version); if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) break; // This version number is found to be suitable - if (version >= maxVersion) // All versions in the range could not fit the given data - throw new IllegalArgumentException("Data too long"); + if (version >= maxVersion) { // All versions in the range could not fit the given data + String msg = "Segment too long"; + if (dataUsedBits != -1) + msg = String.format("Data length = %d bits, Max capacity = %d bits", dataUsedBits, dataCapacityBits); + throw new DataTooLongException(msg); + } } assert dataUsedBits != -1; diff --git a/src/io/nayuki/fastqrcodegen/QrCodeGeneratorWorker.java b/src/io/nayuki/fastqrcodegen/QrCodeGeneratorWorker.java index eb9dd36..fc0c9d1 100644 --- a/src/io/nayuki/fastqrcodegen/QrCodeGeneratorWorker.java +++ b/src/io/nayuki/fastqrcodegen/QrCodeGeneratorWorker.java @@ -91,9 +91,7 @@ public final class QrCodeGeneratorWorker { System.out.println(qr.getModule(x, y) ? 1 : 0); } - } catch (IllegalArgumentException e) { - if (!e.getMessage().equals("Data too long")) - throw e; + } catch (DataTooLongException e) { System.out.println(-1); } System.out.flush(); diff --git a/src/io/nayuki/fastqrcodegen/QrSegmentAdvanced.java b/src/io/nayuki/fastqrcodegen/QrSegmentAdvanced.java index 6cbdb7b..3cd5ae5 100644 --- a/src/io/nayuki/fastqrcodegen/QrSegmentAdvanced.java +++ b/src/io/nayuki/fastqrcodegen/QrSegmentAdvanced.java @@ -57,8 +57,8 @@ public final class QrSegmentAdvanced { * @return a new mutable list (not {@code null}) of segments (not {@code null}) * containing the text, minimizing the bit length with respect to the constraints * @throws NullPointerException if the text or error correction level is {@code null} - * @throws IllegalArgumentException if 1 ≤ minVersion ≤ maxVersion ≤ 40 - * is violated, or if the data is too long to fit in a QR Code at maxVersion at ECL + * @throws IllegalArgumentException if 1 ≤ minVersion ≤ maxVersion ≤ 40 is violated + * @throws DataTooLongException if the text fails to fit in the maxVersion QR Code at the ECL */ public static List makeSegmentsOptimally(String text, QrCode.Ecc ecl, int minVersion, int maxVersion) { // Check arguments @@ -70,7 +70,7 @@ public final class QrSegmentAdvanced { // Iterate through version numbers, and make tentative segments List segs = null; int[] codePoints = toCodePoints(text); - for (int version = minVersion; version <= maxVersion; version++) { + for (int version = minVersion; ; version++) { if (version == minVersion || version == 10 || version == 27) segs = makeSegmentsOptimally(codePoints, version); assert segs != null; @@ -79,9 +79,14 @@ public final class QrSegmentAdvanced { int dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8; int dataUsedBits = QrSegment.getTotalBits(segs, version); if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) - return segs; + return segs; // This version number is found to be suitable + if (version >= maxVersion) { // All versions in the range could not fit the given text + String msg = "Segment too long"; + if (dataUsedBits != -1) + msg = String.format("Data length = %d bits, Max capacity = %d bits", dataUsedBits, dataCapacityBits); + throw new DataTooLongException(msg); + } } - throw new IllegalArgumentException("Data too long"); }