private List <INode> GetStartNodes(byte[] input) { if (input.Length == 0) { return(new List <INode> { EmptyStringNode.Instance }); } var result = new List <INode>(); var count = DigitRun(input, 0); var isTerminal = count == input.Length; // Use CodeC only if the total input is two digits // Or if it starts with at least four digits. if (isTerminal && count == 2 || count >= 4) { var actualCount = count - count % 2; result.Add(new CodeCStart(actualCount, actualCount == input.Length)); return(result); } var types = CodeSetAB; foreach (var type in types) { count = CodeSetRun(input, _mapping.GetCodeSet(type), 0, out var isHigh); isTerminal = count == input.Length; if (count > 0) { if (isHigh) { if (count > 4 || isTerminal && count >= 2) { // always switch to high mode, no need to try anything else result.Add(new CodeSetStart(type, count, isTerminal, HighModeChange.Toggle)); } else { // try switching and shifting result.Add(new CodeSetStart(type, count, isTerminal, HighModeChange.Toggle)); result.Add(new CodeSetStart(type, count, isTerminal, HighModeChange.Shift)); } } else { result.Add(new CodeSetStart(type, count, count == input.Length, HighModeChange.Keep)); } } } return(result); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { var set = mapping.GetCodeSet(CodeSetType.CodeC); buffer.Add(set.GetSymbolForCode(set.StartCode)); FlushHelper.FlushCodeSetC(mapping, input, buffer, Start, Length); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { var set = mapping.GetCodeSet(_codeSet); buffer.Add(set.GetSymbolForCode(set.StartCode)); _highMode.Wrap(set, buffer, FlushHelper.CreateFlushEmits(set, input, buffer, Start, Length)); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { if (_needsChangeOfSet) { var previousSet = mapping.GetCodeSet(Predecessor.FinalCodeSet); var mySet = mapping.GetCodeSet(FinalCodeSet); if (!mySet.SwitchToCode.HasValue) { throw new InvalidOperationException($"Cannot switch to {FinalCodeSet} from "); } buffer.Add(previousSet.GetSymbolForCode(mySet.SwitchToCode.Value)); } var set = mapping.GetCodeSet(FinalCodeSet); _highMode.Wrap(set, buffer, FlushHelper.CreateFlushEmits(set, input, buffer, Start, Length)); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { var previousSet = mapping.GetCodeSet(Predecessor.FinalCodeSet); var mySet = mapping.GetCodeSet(_codeSet); if (!previousSet.ShiftOtherCode.HasValue) { throw new InvalidOperationException($"Cannot switch to {_codeSet} from "); } var actions = Enumerable.Range(Start, Length).Select(index => new Action(() => { buffer.Add(previousSet.GetSymbolForCode(previousSet.ShiftOtherCode.Value)); buffer.Add(mySet.GetSymbolForCode(input[Start])); })); _highMode.Wrap(previousSet, buffer, actions); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { if (_switchToSet) { var previousSet = mapping.GetCodeSet(Predecessor.FinalCodeSet); buffer.Add(previousSet.GetSymbolForCode(SpecialCodes.SwitchToCodeC)); } FlushHelper.FlushCodeSetC(mapping, input, buffer, Start, Length); }
public static int FlushCodeSetC(IMapping mapping, byte[] input, ICollection <Symbol> buffer, int startIndex, int count) { var set = mapping.GetCodeSet(CodeSetType.CodeC); while (count >= 2) { var n = 10 * (input[startIndex] - '0') + (input[startIndex + 1] - '0'); var code = set.GetSymbolForCode((ushort)n); buffer.Add(code); startIndex += 2; count -= 2; } return(startIndex); }
public override void Emit(IMapping mapping, byte[] input, ICollection <Symbol> buffer) { var set = mapping.GetCodeSet(FinalCodeSet); buffer.Add(set.GetSymbolForCode(set.StartCode)); }
private void Handle() { var next = Peek(1); if (next != null && next.Code == SpecialCodes.Stop) { // this is the checksum, consume without interpreting Consume(); return; } switch (_current.Code) { case SpecialCodes.Func1: case SpecialCodes.Func2: case SpecialCodes.Func3: // TODO determine what to do Consume(); break; case SpecialCodes.Func4: if (_tempSet.HasValue) { throw new CodeError("Unexpected Func4 after code set shift."); } Consume(); _high += 128; var peek = Peek(0); if (peek == null || peek.Code != SpecialCodes.Func4) { _highShift = true; } else { Consume(); } break; case SpecialCodes.SwitchToCodeA: HandleCodeSetSwitch(CodeSetType.CodeA); break; case SpecialCodes.SwitchToCodeB: HandleCodeSetSwitch(CodeSetType.CodeB); break; case SpecialCodes.SwitchToCodeC: HandleCodeSetSwitch(CodeSetType.CodeC); break; case SpecialCodes.ShiftToA: HandleShift(CodeSetType.CodeB, CodeSetType.CodeA); break; case SpecialCodes.ShiftToB: HandleShift(CodeSetType.CodeA, CodeSetType.CodeB); break; case SpecialCodes.StartA: case SpecialCodes.StartB: case SpecialCodes.StartC: throw new CodeError("Unexpected start token"); case SpecialCodes.Stop: Consume(); return; default: switch (_tempSet ?? _activeType) { case CodeSetType.CodeC: var value = _current.Code; _output.AddRange(_encoding.GetBytes(value.ToString("00"))); break; default: _output.Add((byte)(_current.Code + _high)); break; } if (_highShift) { _high += 128; _highShift = false; } if (_tempSet.HasValue) { _tempSet = null; _activeCodeSet = _mapping.GetCodeSet(_activeType); } Consume(); break; } }