Skip to content

Commit

Permalink
Issue zxing#105 avoid accessing Charset Cp437 until absolutely necess…
Browse files Browse the repository at this point in the history
…ary, as it won't work on Android sometimes
  • Loading branch information
srowen committed Mar 28, 2014
1 parent 699471b commit b09290c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ public PDF417() {
public PDF417(boolean compact) {
this.compact = compact;
compaction = Compaction.AUTO;
encoding = PDF417HighLevelEncoder.DEFAULT_ENCODING;
encoding = null; // Use default
minCols = 2;
maxCols = 30;
maxRows = 30;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@

import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Arrays;
import java.util.List;

/**
* PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in
Expand Down Expand Up @@ -125,7 +127,7 @@ final class PDF417HighLevelEncoder {
private static final byte[] MIXED = new byte[128];
private static final byte[] PUNCTUATION = new byte[128];

static final Charset DEFAULT_ENCODING = Charset.forName("Cp437");
private static final List<String> DEFAULT_ENCODING_NAMES = Arrays.asList("Cp437", "IBM437");

private PDF417HighLevelEncoder() {
}
Expand Down Expand Up @@ -154,14 +156,17 @@ private PDF417HighLevelEncoder() {
* is used.
*
* @param msg the message
* @param compaction compaction mode to use
* @param encoding character encoding used to encode in default or byte compaction
* or {@code null} for default / not applicable
* @return the encoded message (the char values range from 0 to 928)
*/
static String encodeHighLevel(String msg, Compaction compaction, Charset encoding) throws WriterException {

//the codewords 0..928 are encoded as Unicode characters
StringBuilder sb = new StringBuilder(msg.length());

if (!DEFAULT_ENCODING.equals(encoding)) {
if (encoding != null || !DEFAULT_ENCODING_NAMES.contains(encoding.name())) {
CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding.name());
if (eci != null) {
encodingECI(eci.getValue(), sb);
Expand All @@ -178,7 +183,7 @@ static String encodeHighLevel(String msg, Compaction compaction, Charset encodin
encodeText(msg, p, len, sb, textSubMode);

} else if (compaction == Compaction.BYTE) {
bytes = msg.getBytes(encoding);
bytes = toBytes(msg, encoding);
encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb);

} else if (compaction == Compaction.NUMERIC) {
Expand Down Expand Up @@ -207,7 +212,7 @@ static String encodeHighLevel(String msg, Compaction compaction, Charset encodin
p += t;
} else {
if (bytes == null) {
bytes = msg.getBytes(encoding);
bytes = toBytes(msg, encoding);
}
int b = determineConsecutiveBinaryCount(msg, bytes, p);
if (b == 0) {
Expand All @@ -231,6 +236,24 @@ static String encodeHighLevel(String msg, Compaction compaction, Charset encodin
return sb.toString();
}

private static byte[] toBytes(String msg, Charset encoding) throws WriterException {
// Defer instantiating default Charset until needed, since it may be for an unsupported
// encoding. For example the default of Cp437 doesn't seem to exist on Android.
if (encoding == null) {
for (String encodingName : DEFAULT_ENCODING_NAMES) {
try {
encoding = Charset.forName(encodingName);
} catch (UnsupportedCharsetException uce) {
// continue
}
}
if (encoding == null) {
throw new WriterException("No support for any encoding: " + DEFAULT_ENCODING_NAMES);
}
}
return msg.getBytes(encoding);
}

/**
* Encode parts of the message using Text Compaction as described in ISO/IEC 15438:2001(E),
* chapter 4.4.2.
Expand Down

0 comments on commit b09290c

Please sign in to comment.