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:
+ *
+ * Decrease the error correction level if it was greater than {@code Ecc.LOW}.
+ * If the advanced {@code encodeSegments()} function with 6 arguments or the
+ * {@code makeSegmentsOptimally()} function was called, then increase the maxVersion argument
+ * if it was less than {@link QrCode#MAX_VERSION}. (This advice does not apply to the other
+ * factory functions because they search all versions up to {@code QrCode.MAX_VERSION}.)
+ * Split the text data into better or optimal segments in order to reduce the number of
+ * bits required. (See {@link QrSegmentAdvanced#makeSegmentsOptimally(String,QrCode.Ecc,int,int)
+ * QrSegmentAdvanced.makeSegmentsOptimally()}.)
+ * Change the text or binary data to be shorter.
+ * Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).
+ * Propagate the error upward to the caller/user.
+ *
+ * @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");
}