public void encode(EncoderContext context) { //step F var buffer = new StringBuilder(); while (context.HasMoreCharacters) { char c = context.CurrentChar; encodeChar(c, buffer); context.Pos++; int count = buffer.Length; if (count >= 4) { context.writeCodewords(encodeToCodewords(buffer, 0)); buffer.Remove(0, 4); int newMode = HighLevelEncoder.lookAheadTest(context.Msg, context.Pos, EncodingMode); if (newMode != EncodingMode) { context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); break; } } } buffer.Append((char)31); //Unlatch handleEOD(context, buffer); }
override public void encode(EncoderContext context) { //step C StringBuilder buffer = new StringBuilder(); while (context.HasMoreCharacters) { char c = context.CurrentChar; context.Pos++; encodeChar(c, buffer); int count = buffer.Length; if ((count % 3) == 0) { writeNextTriplet(context, buffer); int newMode = HighLevelEncoder.lookAheadTest(context.Msg, context.Pos, EncodingMode); if (newMode != EncodingMode) { context.signalEncoderChange(newMode); break; } } } handleEOD(context, buffer); }
/// <summary> /// Handle "end of data" situations /// </summary> /// <param name="context">the encoder context</param> /// <param name="buffer">the buffer with the remaining encoded characters</param> private static void handleEOD(EncoderContext context, StringBuilder buffer) { try { int count = buffer.Length; if (count == 0) { return; //Already finished } if (count == 1) { //Only an unlatch at the end context.updateSymbolInfo(); int available = context.SymbolInfo.dataCapacity - context.CodewordCount; int remaining = context.RemainingCharacters; if (remaining == 0 && available <= 2) { return; //No unlatch } } if (count > 4) { throw new InvalidOperationException("Count must not exceed 4"); } int restChars = count - 1; String encoded = encodeToCodewords(buffer, 0); bool endOfSymbolReached = !context.HasMoreCharacters; bool restInAscii = endOfSymbolReached && restChars <= 2; if (restChars <= 2) { context.updateSymbolInfo(context.CodewordCount + restChars); int available = context.SymbolInfo.dataCapacity - context.CodewordCount; if (available >= 3) { restInAscii = false; context.updateSymbolInfo(context.CodewordCount + encoded.Length); //available = context.symbolInfo.dataCapacity - context.getCodewordCount(); } } if (restInAscii) { context.resetSymbolInfo(); context.Pos -= restChars; } else { context.writeCodewords(encoded); } } finally { context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); } }
/// <summary> /// Handle "end of data" situations /// </summary> /// <param name="context">the encoder context</param> /// <param name="buffer">the buffer with the remaining encoded characters</param> virtual protected void handleEOD(EncoderContext context, StringBuilder buffer) { int unwritten = (buffer.Length / 3) * 2; int rest = buffer.Length % 3; int curCodewordCount = context.CodewordCount + unwritten; context.updateSymbolInfo(curCodewordCount); int available = context.SymbolInfo.dataCapacity - curCodewordCount; if (rest == 2) { buffer.Append('\u0000'); //Shift 1 while (buffer.Length >= 3) { writeNextTriplet(context, buffer); } if (context.HasMoreCharacters) { context.writeCodeword(HighLevelEncoder.C40_UNLATCH); } } else if (available == 1 && rest == 1) { while (buffer.Length >= 3) { writeNextTriplet(context, buffer); } if (context.HasMoreCharacters) { context.writeCodeword(HighLevelEncoder.C40_UNLATCH); } // else no unlatch context.Pos--; } else if (rest == 0) { while (buffer.Length >= 3) { writeNextTriplet(context, buffer); } if (available > 0 || context.HasMoreCharacters) { context.writeCodeword(HighLevelEncoder.C40_UNLATCH); } } else { throw new InvalidOperationException("Unexpected case. Please report!"); } context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); }
public void encode(EncoderContext context) { var buffer = new StringBuilder(); buffer.Append('\u0000'); //Initialize length field while (context.HasMoreCharacters) { char c = context.CurrentChar; buffer.Append(c); context.Pos++; int newMode = HighLevelEncoder.lookAheadTest(context.Msg, context.Pos, EncodingMode); if (newMode != EncodingMode) { context.signalEncoderChange(newMode); break; } } int dataCount = buffer.Length - 1; const int lengthFieldSize = 1; int currentSize = context.CodewordCount + dataCount + lengthFieldSize; context.updateSymbolInfo(currentSize); bool mustPad = (context.SymbolInfo.dataCapacity - currentSize) > 0; if (context.HasMoreCharacters || mustPad) { if (dataCount <= 249) { buffer[0] = (char)dataCount; } else if (dataCount > 249 && dataCount <= 1555) { buffer[0] = (char)((dataCount / 250) + 249); buffer.Insert(1, new [] { (char)(dataCount % 250) }); } else { throw new InvalidOperationException( "Message length not in valid ranges: " + dataCount); } } { var c = buffer.Length; for (int i = 0; i < c; i++) { context.writeCodeword(randomize255State( buffer[i], context.CodewordCount + 1)); } } }
private int backtrackOneCharacter(EncoderContext context, StringBuilder buffer, StringBuilder removed, int lastCharSize) { int count = buffer.Length; buffer.Remove(count - lastCharSize, lastCharSize); context.Pos--; char c = context.CurrentChar; lastCharSize = encodeChar(c, removed); context.resetSymbolInfo(); //Deal with possible reduction in symbol size return(lastCharSize); }
virtual public void encode(EncoderContext context) { //step C var buffer = new StringBuilder(); while (context.HasMoreCharacters) { char c = context.CurrentChar; context.Pos++; int lastCharSize = encodeChar(c, buffer); int unwritten = (buffer.Length / 3) * 2; int curCodewordCount = context.CodewordCount + unwritten; context.updateSymbolInfo(curCodewordCount); int available = context.SymbolInfo.dataCapacity - curCodewordCount; if (!context.HasMoreCharacters) { //Avoid having a single C40 value in the last triplet var removed = new StringBuilder(); if ((buffer.Length % 3) == 2) { if (available < 2 || available > 2) { lastCharSize = backtrackOneCharacter(context, buffer, removed, lastCharSize); } } while ((buffer.Length % 3) == 1 && ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) { lastCharSize = backtrackOneCharacter(context, buffer, removed, lastCharSize); } break; } int count = buffer.Length; if ((count % 3) == 0) { int newMode = HighLevelEncoder.lookAheadTest(context.Msg, context.Pos, EncodingMode); if (newMode != EncodingMode) { context.signalEncoderChange(newMode); break; } } } handleEOD(context, buffer); }
override protected void handleEOD(EncoderContext context, StringBuilder buffer) { context.updateSymbolInfo(); int available = context.SymbolInfo.dataCapacity - context.CodewordCount; int count = buffer.Length; if (count == 2) { context.writeCodeword(HighLevelEncoder.X12_UNLATCH); context.Pos -= 2; context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); } else if (count == 1) { context.Pos--; if (available > 1) { context.writeCodeword(HighLevelEncoder.X12_UNLATCH); } //NOP - No unlatch necessary context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); } }
/// <summary> /// Performs message encoding of a DataMatrix message using the algorithm described in annex P /// of ISO/IEC 16022:2000(E). /// </summary> /// <param name="msg">the message</param> /// <param name="shape">requested shape. May be {@code SymbolShapeHint.FORCE_NONE},{@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.</param> /// <param name="minSize">the minimum symbol size constraint or null for no constraint</param> /// <param name="maxSize">the maximum symbol size constraint or null for no constraint</param> /// <returns>the encoded message (the char values range from 0 to 255)</returns> public static String encodeHighLevel(String msg, SymbolShapeHint shape, Dimension minSize, Dimension maxSize) { //the codewords 0..255 are encoded as Unicode characters Encoder[] encoders = { new ASCIIEncoder(), new C40Encoder(), new TextEncoder(), new X12Encoder(), new EdifactEncoder(), new Base256Encoder() }; var context = new EncoderContext(msg); context.setSymbolShape(shape); context.setSizeConstraints(minSize, maxSize); if (msg.StartsWith(MACRO_05_HEADER) && msg.EndsWith(MACRO_TRAILER)) { context.writeCodeword(MACRO_05); context.setSkipAtEnd(2); context.Pos += MACRO_05_HEADER.Length; } else if (msg.StartsWith(MACRO_06_HEADER) && msg.EndsWith(MACRO_TRAILER)) { context.writeCodeword(MACRO_06); context.setSkipAtEnd(2); context.Pos += MACRO_06_HEADER.Length; } int encodingMode = ASCII_ENCODATION; //Default mode while (context.HasMoreCharacters) { encoders[encodingMode].encode(context); if (context.NewEncoding >= 0) { encodingMode = context.NewEncoding; context.resetEncoderSignal(); } } int len = context.Codewords.Length; context.updateSymbolInfo(); int capacity = context.SymbolInfo.dataCapacity; if (len < capacity) { if (encodingMode != ASCII_ENCODATION && encodingMode != BASE256_ENCODATION) { context.writeCodeword('\u00fe'); //Unlatch (254) } } //Padding StringBuilder codewords = context.Codewords; if (codewords.Length < capacity) { codewords.Append(PAD); } while (codewords.Length < capacity) { codewords.Append(randomize253State(PAD, codewords.Length + 1)); } return(context.Codewords.ToString()); }
internal static void writeNextTriplet(EncoderContext context, StringBuilder buffer) { context.writeCodewords(encodeToCodewords(buffer, 0)); buffer.Remove(0, 3); }
public void encode(EncoderContext context) { //step B int n = HighLevelEncoder.determineConsecutiveDigitCount(context.Msg, context.Pos); if (n >= 2) { context.writeCodeword(encodeASCIIDigits(context.Msg[context.Pos], context.Msg[context.Pos + 1])); context.Pos += 2; } else { char c = context.CurrentChar; int newMode = HighLevelEncoder.lookAheadTest(context.Msg, context.Pos, EncodingMode); if (newMode != EncodingMode) { switch (newMode) { case HighLevelEncoder.BASE256_ENCODATION: context.writeCodeword(HighLevelEncoder.LATCH_TO_BASE256); context.signalEncoderChange(HighLevelEncoder.BASE256_ENCODATION); return; case HighLevelEncoder.C40_ENCODATION: context.writeCodeword(HighLevelEncoder.LATCH_TO_C40); context.signalEncoderChange(HighLevelEncoder.C40_ENCODATION); return; case HighLevelEncoder.X12_ENCODATION: context.writeCodeword(HighLevelEncoder.LATCH_TO_ANSIX12); context.signalEncoderChange(HighLevelEncoder.X12_ENCODATION); break; case HighLevelEncoder.TEXT_ENCODATION: context.writeCodeword(HighLevelEncoder.LATCH_TO_TEXT); context.signalEncoderChange(HighLevelEncoder.TEXT_ENCODATION); break; case HighLevelEncoder.EDIFACT_ENCODATION: context.writeCodeword(HighLevelEncoder.LATCH_TO_EDIFACT); context.signalEncoderChange(HighLevelEncoder.EDIFACT_ENCODATION); break; default: throw new InvalidOperationException("Illegal mode: " + newMode); } } else if (HighLevelEncoder.isExtendedASCII(c)) { context.writeCodeword(HighLevelEncoder.UPPER_SHIFT); context.writeCodeword((char)(c - 128 + 1)); context.Pos++; } else { context.writeCodeword((char)(c + 1)); context.Pos++; } } }