/// <summary> /// Parses tdta contents into tokens. Throws a generic exception if unrecognized tokens are encountered /// </summary> /// <param name="r"></param> /// <returns></returns> public static Token nextToken(BinaryReverseReader r) { if (!r.CanReadByte()) { return(null); } char c = r.ReadChar(); switch (c) { case '(': return(new Token(parseBinary(r))); //Binary data. Leading and trailing parens are stripped, and escaped parens are restored to normal. case '[': return(new Token(TokenType.StartList, c.ToString())); // [ opening list char case ']': return(new Token(TokenType.EndList, c.ToString())); //Closing list char } //<< opening dict //>> closing dict if (c == '<' || c == '>') { char c2 = r.ReadChar(); if (c2 != c) { throw new TdTaParseException("Unrecognized token: " + c + c2, r); } if (c == '<') { return(new Token(TokenType.StartDict, "<<")); } else { return(new Token(TokenType.EndDict, ">>")); } } //Dict key (Any non-whitespace, non-[]<> sequence allowed following forward slash) if (c == '/') { StringBuilder sb = new StringBuilder(40); while (r.CanReadByte()) { //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc == '[' || pc == ']' || pc == '<' || pc == '>') { //We're done. //Strip the leading slash, create token with name return(new Token(TokenType.MapKey, sb.ToString())); } else { //A valid char, append it. sb.Append(r.ReadChar()); } } } //Integer or double. Ends at whitespace, newline, ], or > if (Char.IsDigit(c) || c == '-' || c == '.') { StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()) { //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc == ']' || pc == '>') { //We're done. Find out what kind of number it is. string s = sb.ToString(); //If it has a decimal, it's a double if (s.Contains('.')) { return(new Token(TokenType.Double, double.Parse(s, floatingPointStyle, NumberFormatInfo.InvariantInfo))); } else { return(new Token(TokenType.Integer, int.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo))); } } else if (Char.IsDigit(c) || c == '-' || c == '.') { //A valid char, append it. sb.Append(r.ReadChar()); } else { //Unrecognized char in numeric sq throw new TdTaParseException("Unrecognized character in numeric sequence: " + sb.ToString() + pc, r); } } } //Boolean (true|false) parsing if (c == 't' || c == 'T' || c == 'f' || c == 'F') { string s = c.ToString() + r.ReadChar().ToString() + r.ReadChar().ToString() + r.ReadChar().ToString(); char pc = (char)r.PeekChar(); if (s.Equals("true", StringComparison.OrdinalIgnoreCase)) { return(new Token(TokenType.Boolean, true)); } else if (s.Equals("fals", StringComparison.OrdinalIgnoreCase) && (pc == 'e' || pc == 'E')) { r.ReadChar(); //discard 'e' return(new Token(TokenType.Boolean, false)); } else { throw new TdTaParseException("Unrecognized boolean value: " + s + pc, r); } } //Whitespace parsing if (Char.IsWhiteSpace(c) || c == '\n') { StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()) { //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n') { sb.Append(r.ReadChar()); } else { //We done. break; } } return(new Token(TokenType.Whitespace, sb.ToString())); } throw new TdTaParseException("Unrecognized token: " + c, r); }
/// <summary> /// Parses tdta contents into tokens. Throws a generic exception if unrecognized tokens are encountered /// </summary> /// <param name="r"></param> /// <returns></returns> public static Token nextToken(BinaryReverseReader r) { if (!r.CanReadByte()) return null; char c = r.ReadChar(); switch (c) { case '(': return new Token(parseBinary(r)); //Binary data. Leading and trailing parens are stripped, and escaped parens are restored to normal. case '[': return new Token(TokenType.StartList, c.ToString()); // [ opening list char case ']': return new Token(TokenType.EndList, c.ToString()); //Closing list char } //<< opening dict //>> closing dict if (c == '<' || c == '>') { char c2 = r.ReadChar(); if (c2 != c) throw new TdTaParseException("Unrecognized token: " + c + c2,r); if (c == '<') return new Token(TokenType.StartDict, "<<"); else return new Token(TokenType.EndDict, ">>"); } //Dict key (Any non-whitespace, non-[]<> sequence allowed following forward slash) if (c == '/'){ StringBuilder sb = new StringBuilder(40); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc=='[' || pc==']' || pc=='<' || pc=='>'){ //We're done. //Strip the leading slash, create token with name return new Token(TokenType.MapKey,sb.ToString()); }else{ //A valid char, append it. sb.Append(r.ReadChar()); } } } //Integer or double. Ends at whitespace, newline, ], or > if (Char.IsDigit(c) || c=='-' || c == '.'){ StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc ==']' || pc =='>'){ //We're done. Find out what kind of number it is. string s = sb.ToString(); //If it has a decimal, it's a double if (s.Contains('.')){ return new Token(TokenType.Double,double.Parse(s, floatingPointStyle,NumberFormatInfo.InvariantInfo)); }else{ return new Token(TokenType.Integer,int.Parse(s,NumberStyles.Integer,NumberFormatInfo.InvariantInfo)); } }else if (Char.IsDigit(c) || c=='-' || c == '.'){ //A valid char, append it. sb.Append(r.ReadChar()); }else{ //Unrecognized char in numeric sq throw new TdTaParseException("Unrecognized character in numeric sequence: " + sb.ToString() + pc,r); } } } //Boolean (true|false) parsing if (c == 't' || c == 'T' || c == 'f' || c == 'F'){ string s = c.ToString() + r.ReadChar().ToString() + r.ReadChar().ToString() + r.ReadChar().ToString(); char pc = (char)r.PeekChar(); if (s.Equals("true", StringComparison.OrdinalIgnoreCase)){ return new Token(TokenType.Boolean,true); }else if (s.Equals("fals", StringComparison.OrdinalIgnoreCase) && (pc == 'e' || pc == 'E')){ r.ReadChar(); //discard 'e' return new Token(TokenType.Boolean,false); }else{ throw new TdTaParseException("Unrecognized boolean value: " + s + pc,r); } } //Whitespace parsing if (Char.IsWhiteSpace(c) || c == '\n'){ StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n'){ sb.Append(r.ReadChar()); }else{ //We done. break; } } return new Token(TokenType.Whitespace,sb.ToString()); } throw new TdTaParseException("Unrecognized token: " + c,r); }