Merge pull request #395 from strguntbr/multibyteFix

Multibyte fix
This commit is contained in:
Sean Owen 2015-05-20 18:25:28 +01:00
commit faee672889
2 changed files with 18 additions and 15 deletions

View file

@ -25,6 +25,7 @@ import com.google.zxing.common.CharacterSetECI;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Arrays;
/**
@ -178,12 +179,11 @@ final class PDF417HighLevelEncoder {
int textSubMode = SUBMODE_ALPHA;
// User selected encoding mode
byte[] bytes = null; //Fill later and only if needed
if (compaction == Compaction.TEXT) {
encodeText(msg, p, len, sb, textSubMode);
} else if (compaction == Compaction.BYTE) {
bytes = msg.getBytes(encoding);
byte[] bytes = msg.getBytes(encoding);
encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb);
} else if (compaction == Compaction.NUMERIC) {
@ -211,19 +211,17 @@ final class PDF417HighLevelEncoder {
textSubMode = encodeText(msg, p, t, sb, textSubMode);
p += t;
} else {
if (bytes == null) {
bytes = msg.getBytes(encoding);
}
int b = determineConsecutiveBinaryCount(msg, bytes, p);
int b = determineConsecutiveBinaryCount(msg, p, encoding);
if (b == 0) {
b = 1;
}
if (b == 1 && encodingMode == TEXT_COMPACTION) {
byte[] bytes = msg.substring(p, b).getBytes(encoding);
if (bytes.length == 1 && encodingMode == TEXT_COMPACTION) {
//Switch for one byte (instead of latch)
encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
encodeBinary(bytes, 0, 1, TEXT_COMPACTION, sb);
} else {
//Mode latch performed by encodeBinary()
encodeBinary(bytes, p, b, encodingMode, sb);
encodeBinary(bytes, 0, bytes.length, encodingMode, sb);
encodingMode = BYTE_COMPACTION;
textSubMode = SUBMODE_ALPHA; //Reset after latch
}
@ -530,12 +528,13 @@ final class PDF417HighLevelEncoder {
* Determines the number of consecutive characters that are encodable using binary compaction.
*
* @param msg the message
* @param bytes the message converted to a byte array
* @param startpos the start position within the message
* @param encoding the charset used to convert the message to a byte array
* @return the requested character count
*/
private static int determineConsecutiveBinaryCount(CharSequence msg, byte[] bytes, int startpos)
private static int determineConsecutiveBinaryCount(String msg, int startpos, Charset encoding)
throws WriterException {
final CharsetEncoder encoder = encoding.newEncoder();
int len = msg.length();
int idx = startpos;
while (idx < len) {
@ -556,10 +555,7 @@ final class PDF417HighLevelEncoder {
}
ch = msg.charAt(idx);
//Check if character is encodable
//Sun returns a ASCII 63 (?) for a character that cannot be mapped. Let's hope all
//other VMs do the same
if (bytes[idx] == 63 && ch != '?') {
if (!encoder.canEncode(ch)) {
throw new WriterException("Non-encodable character detected: " + ch + " (Unicode: " + (int) ch + ')');
}
idx++;

View file

@ -30,6 +30,13 @@ public final class PDF417EncoderTestCase extends Assert {
assertEquals("\u039f\u001A\u0385ABCD", encoded);
}
@Test
public void testEncodeAutoWithSpecialChars() throws Exception {
//Just check if this does not throw an exception
PDF417HighLevelEncoder.encodeHighLevel(
"1%§s ?aG$", Compaction.AUTO, StandardCharsets.UTF_8);
}
@Test
public void testEncodeText() throws Exception {
String encoded = PDF417HighLevelEncoder.encodeHighLevel(