private void ParseNext() { var trailingWhitespace = false; var token = _scanner.NextToken(); while (true) { int action = TransitionActions[_state, token]; switch (action) { default: throw new InvalidTokenException(token); case ActionNotDefined: throw new IonException("Invalid state"); case ActionEof: _state = StateEof; _eof = true; return; case ActionLoadFieldName: if (!IsInStruct) { throw new IonException("Field names have to be inside struct"); } LoadTokenContents(token); var symtok = ParseSymbolToken(_valueBuffer, token); SetFieldName(symtok); ClearValueBuffer(); token = _scanner.NextToken(); if (token != TextConstants.TokenColon) { throw new InvalidTokenException("Field name has to be followed by a colon"); } _scanner.MarkTokenFinished(); _state = StateBeforeAnnotationContained; token = _scanner.NextToken(); break; case ActionLoadAnnotation: LoadTokenContents(token); trailingWhitespace = _scanner.SkipWhiteSpace(); if (!_scanner.TrySkipDoubleColon()) { _state = GetStateAfterAnnotation(_state, _containerStack.Peek()); break; } var sym = ParseSymbolToken(_valueBuffer, token); _annotations.Add(sym); ClearValueBuffer(); _scanner.MarkTokenFinished(); // Consumed the annotation, move on. // note: that peekDoubleColon() consumed the two colons // so nextToken won't see them token = _scanner.NextToken(); switch (token) { case TextConstants.TokenSymbolIdentifier: case TextConstants.TokenSymbolQuoted: // This may be another annotation, so stay in this state // and come around the horn again to check it out. break; default: // we leave the error handling to the transition _state = GetStateAfterAnnotation(_state, _containerStack.Peek()); break; } break; case ActionStartStruct: _valueType = IonType.Struct; _expectedContainerClosingSymbol.Push(TextConstants.TokenCloseBrace); _state = StateBeforeFieldName; return; case ActionStartList: _valueType = IonType.List; _expectedContainerClosingSymbol.Push(TextConstants.TokenCloseSquare); _state = StateBeforeAnnotationContained; return; case ActionStartSexp: _valueType = IonType.Sexp; _expectedContainerClosingSymbol.Push(TextConstants.TokenCloseParen); _state = StateBeforeAnnotationSexp; return; case ActionStartLob: switch (_scanner.PeekLobStartPunctuation()) { case TextConstants.TokenStringDoubleQuote: _lobToken = TextConstants.TokenStringDoubleQuote; _valueType = IonType.Clob; break; case TextConstants.TokenStringTripleQuote: _lobToken = TextConstants.TokenStringTripleQuote; _valueType = IonType.Clob; break; default: _state = StateInBlobContent; _lobToken = TextConstants.TokenOpenDoubleBrace; _valueType = IonType.Blob; break; } return; case ActionLoadScalar: if (token == TextConstants.TokenSymbolIdentifier) { LoadTokenContents(token); //token has been wholy loaded _scanner.MarkTokenFinished(); _valueKeyword = TextConstants.GetKeyword(_valueBuffer, 0, _valueBuffer.Length); switch (_valueKeyword) { default: _valueType = IonType.Symbol; break; case TextConstants.KeywordNull: ReadNullType(trailingWhitespace); break; case TextConstants.KeywordTrue: _valueType = IonType.Bool; _v.BoolValue = true; break; case TextConstants.KeywordFalse: _valueType = IonType.Bool; _v.BoolValue = false; break; case TextConstants.KeywordNan: _valueType = IonType.Float; ClearValueBuffer(); _v.DoubleValue = double.NaN; break; case TextConstants.KeywordSid: var sid = TextConstants.DecodeSid(_valueBuffer); _v.IntValue = sid; _valueType = IonType.Symbol; break; } //do not clear the buffer yet because LoadTokenContents() might be called again } else if (token == TextConstants.TokenDot) { _valueType = IonType.Symbol; ClearValueBuffer(); _v.StringValue = "."; } else { // if it's not a symbol we just look at the token type _valueType = TextConstants.GetIonTypeOfToken(token); } _state = GetStateAfterValue(_containerStack.Peek()); return; case ActionEatComma: if (_containerProhibitsCommas) { throw new InvalidTokenException(','); } _state = _containerIsStruct ? StateBeforeFieldName : StateBeforeAnnotationContained; _scanner.MarkTokenFinished(); token = _scanner.NextToken(); break; case ActionFinishDatagram: Debug.Assert(CurrentDepth == 0); _eof = true; _state = StateEof; return; case ActionFinishContainer: ValidateClosingSymbol(token); _state = GetStateAfterContainer(_containerStack.Peek()); _eof = true; return; case ActionFinishLob: _state = GetStateAfterValue(_containerStack.Peek()); return; case ActionPlusInf: _valueType = IonType.Float; ClearValueBuffer(); _v.DoubleValue = double.PositiveInfinity; _state = GetStateAfterValue(_containerStack.Peek()); return; case ActionMinusInf: _valueType = IonType.Float; ClearValueBuffer(); _v.DoubleValue = double.NegativeInfinity; _state = GetStateAfterValue(_containerStack.Peek()); return; } } }