📄 datamatrixhighlevelencoder.java
字号:
int v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
char cw1 = (char)((v >> 16) & 255);
char cw2 = (char)((v >> 8) & 255);
char cw3 = (char)(v & 255);
StringBuffer res = new StringBuffer(3);
res.append(cw1);
if (len >= 2) {
res.append(cw2);
}
if (len >= 3) {
res.append(cw3);
}
return res.toString();
}
}
private static class Base256Encoder implements Encoder {
public int getEncodingMode() {
return BASE256_ENCODATION;
}
public void encode(EncoderContext context) {
StringBuffer buffer = new StringBuffer();
buffer.append('\0'); //Initialize length field
while (context.hasMoreCharacters()) {
char c = (char)(context.getCurrentByte() & 0xff);
buffer.append(c);
context.pos++;
int newMode = lookAheadTest(context.msg, context.pos, getEncodingMode());
if (newMode != getEncodingMode()) {
context.signalEncoderChange(newMode);
break;
}
}
int dataCount = buffer.length() - 1;
int lengthFieldSize = 1;
boolean longLengthField = (dataCount > 249);
int currentSize = (context.getCodewordCount() + dataCount + lengthFieldSize);
context.updateSymbolInfo(currentSize);
boolean mustPad = ((context.symbolInfo.dataCapacity - currentSize) > 0);
if (longLengthField && mustPad) {
//more than
lengthFieldSize++;
currentSize++;
}
if (context.hasMoreCharacters() || mustPad) {
if (dataCount <= 249) {
buffer.setCharAt(0, (char)dataCount);
} else if (dataCount > 249 && dataCount <= 1555) {
buffer.setCharAt(0, (char)((dataCount / 250) + 249));
buffer.insert(1, (char)(dataCount % 250));
} else {
throw new IllegalStateException(
"Message length not in valid ranges: " + dataCount);
}
}
for (int i = 0, c = buffer.length(); i < c; i++) {
context.writeCodeword(randomize255State(
buffer.charAt(i), context.getCodewordCount() + 1));
}
}
}
private static char encodeASCIIDigits(char digit1, char digit2) {
if (isDigit(digit1) && isDigit(digit2)) {
int num = (digit1 - 48) * 10 + (digit2 - 48);
return (char)(num + 130);
} else {
throw new IllegalArgumentException("not digits: " + digit1 + digit2);
}
}
private static int lookAheadTest(String msg, int startpos, int currentMode) {
if (startpos >= msg.length()) {
return currentMode;
}
float[] charCounts;
//step J
if (currentMode == ASCII_ENCODATION) {
charCounts = new float[] {0, 1, 1, 1, 1, 1.25f};
} else {
charCounts = new float[] {1, 2, 2, 2, 2, 2.25f};
charCounts[currentMode] = 0;
}
int charsProcessed = 0;
while (true) {
//step K
if ((startpos + charsProcessed) == msg.length()) {
int min = Integer.MAX_VALUE;
byte[] mins = new byte[6];
int[] intCharCounts = new int[6];
min = findMinimums(charCounts, intCharCounts, min, mins);
int minCount = getMinimumCount(mins);
if (intCharCounts[ASCII_ENCODATION] == min) {
return ASCII_ENCODATION;
} else if (minCount == 1 && mins[BASE256_ENCODATION] > 0) {
return BASE256_ENCODATION;
} else if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
return EDIFACT_ENCODATION;
} else if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
return TEXT_ENCODATION;
} else if (minCount == 1 && mins[X12_ENCODATION] > 0) {
return X12_ENCODATION;
} else {
return C40_ENCODATION;
}
}
char c = msg.charAt(startpos + charsProcessed);
charsProcessed++;
//step L
if (isDigit(c)) {
charCounts[ASCII_ENCODATION] += 0.5;
} else if (isExtendedASCII(c)) {
charCounts[ASCII_ENCODATION] = (int)Math.ceil(charCounts[ASCII_ENCODATION]);
charCounts[ASCII_ENCODATION] += 2;
} else {
charCounts[ASCII_ENCODATION] = (int)Math.ceil(charCounts[ASCII_ENCODATION]);
charCounts[ASCII_ENCODATION] += 1;
}
//step M
if (isNativeC40(c)) {
charCounts[C40_ENCODATION] += 2f / 3f;
} else if (isExtendedASCII(c)) {
charCounts[C40_ENCODATION] += 8f / 3f;
} else {
charCounts[C40_ENCODATION] += 4f / 3f;
}
//step N
if (isNativeText(c)) {
charCounts[TEXT_ENCODATION] += 2f / 3f;
} else if (isExtendedASCII(c)) {
charCounts[TEXT_ENCODATION] += 8f / 3f;
} else {
charCounts[TEXT_ENCODATION] += 4f / 3f;
}
//step O
if (isNativeX12(c)) {
charCounts[X12_ENCODATION] += 2f / 3f;
} else if (isExtendedASCII(c)) {
charCounts[X12_ENCODATION] += 13f / 3f;
} else {
charCounts[X12_ENCODATION] += 10f / 3f;
}
//step P
if (isNativeEDIFACT(c)) {
charCounts[EDIFACT_ENCODATION] += 3f / 4f;
} else if (isExtendedASCII(c)) {
charCounts[EDIFACT_ENCODATION] += 17f / 4f;
} else {
charCounts[EDIFACT_ENCODATION] += 13f / 4f;
}
// step Q
if (isSpecialB256(c)) {
charCounts[BASE256_ENCODATION] += 4;
} else {
charCounts[BASE256_ENCODATION] += 1;
}
//step R
if (charsProcessed >= 4) {
/*
for (int a = 0; a < charCounts.length; a++) {
System.out.println(a + " " + ENCODATION_NAMES[a] + " " + charCounts[a]);
}*/
int min = Integer.MAX_VALUE;
int[] intCharCounts = new int[6];
byte[] mins = new byte[6];
min = findMinimums(charCounts, intCharCounts, min, mins);
int minCount = getMinimumCount(mins);
if (intCharCounts[ASCII_ENCODATION] + 1 <= intCharCounts[BASE256_ENCODATION]
&& intCharCounts[ASCII_ENCODATION] + 1 <= intCharCounts[C40_ENCODATION]
&& intCharCounts[ASCII_ENCODATION] + 1 <= intCharCounts[TEXT_ENCODATION]
&& intCharCounts[ASCII_ENCODATION] + 1 <= intCharCounts[X12_ENCODATION]
&& intCharCounts[ASCII_ENCODATION] + 1 <= intCharCounts[EDIFACT_ENCODATION]) {
return ASCII_ENCODATION;
} else if (intCharCounts[BASE256_ENCODATION] + 1 <= intCharCounts[ASCII_ENCODATION]
|| (mins[C40_ENCODATION]
+ mins[TEXT_ENCODATION]
+ mins[X12_ENCODATION]
+ mins[EDIFACT_ENCODATION]) == 0) {
return BASE256_ENCODATION;
} else if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
return EDIFACT_ENCODATION;
} else if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
return TEXT_ENCODATION;
} else if (minCount == 1 && mins[X12_ENCODATION] > 0) {
return X12_ENCODATION;
} else if (intCharCounts[C40_ENCODATION] + 1 < intCharCounts[ASCII_ENCODATION]
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[BASE256_ENCODATION]
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[EDIFACT_ENCODATION]
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[TEXT_ENCODATION]) {
if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) {
return C40_ENCODATION;
} else if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) {
int p = startpos + charsProcessed + 1;
while (p < msg.length()) {
char tc = msg.charAt(p);
if (isX12TermSep(tc)) {
return X12_ENCODATION;
} else if (!isNativeX12(tc)) {
break;
}
p++;
}
return C40_ENCODATION;
}
}
}
}
}
private static int findMinimums(float[] charCounts, int[] intCharCounts,
int min, byte[] mins) {
Arrays.fill(mins, (byte)0);
for (int i = 0; i < 6; i++) {
intCharCounts[i] = (int)Math.ceil(charCounts[i]);
int current = intCharCounts[i];
if (min > current) {
min = current;
Arrays.fill(mins, (byte)0);
}
if (min == current) {
mins[i]++;
}
}
return min;
}
private static int getMinimumCount(byte[] mins) {
int minCount = 0;
for (int i = 0; i < 6; i++) {
minCount += mins[i];
}
return minCount;
}
private static boolean isDigit(char ch) {
return ch >= '0' && ch <= '9';
}
private static final String EXTENDED_ASCII;
static {
byte[] buf = new byte[128];
for (int i = 0; i < 128; i++) {
buf[i] = (byte)(i + 128);
}
try {
EXTENDED_ASCII = new String(buf, DEFAULT_ASCII_ENCODING);
if (EXTENDED_ASCII.length() != buf.length) {
throw new UnsupportedOperationException(
"Cannot deal with encodings that don't have"
+ " a 1:1 character/byte relationship!");
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
private static boolean isExtendedASCII(char ch) {
return (EXTENDED_ASCII.indexOf(ch) >= 0);
}
private static boolean isASCII7(char ch) {
return (ch >= 0 && ch <= 127);
}
private static boolean isNativeC40(char ch) {
//return isASCII7(ch);
return (ch == 32)
|| (ch >= 48 && ch <= 57) //0..9
|| (ch >= 65 && ch <= 90); //A..Z
}
private static boolean isNativeText(char ch) {
//return isASCII7(ch);
return (ch == 32)
|| (ch >= 48 && ch <= 57) //0..9
|| (ch >= 97 && ch <= 122); //a..z
}
private static boolean isNativeX12(char ch) {
return isX12TermSep(ch)
|| (ch == 32) //SPACE
|| (ch >= 48 && ch <= 57)
|| (ch >= 65 && ch <= 90);
}
private static boolean isX12TermSep(char ch) {
return (ch == 13) //CR
|| (ch == 42) //"*"
|| (ch == 62); //">"
}
private static boolean isNativeEDIFACT(char ch) {
return (ch >= 32 && ch <= 94);
}
private static boolean isSpecialB256(char ch) {
return false; //TODO NOT IMPLEMENTED YET!!!
}
/**
* Determines the number of consecutive characters that are encodable using numeric compaction.
* @param msg the message
* @param startpos the start position within the message
* @return the requested character count
*/
public static int determineConsecutiveDigitCount(String msg, int startpos) {
int count = 0;
int len = msg.length();
int idx = startpos;
if (idx < len) {
char ch = msg.charAt(idx);
while (isDigit(ch) && idx < len) {
count++;
idx++;
if (idx < len) {
ch = msg.charAt(idx);
}
}
}
return count;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -