/// <summary> /// Reads the string from input stream. /// </summary> private object ReadString() { int beginLine = _input.Line; int beginOffset = _input.LineOffset + 1; int lastLine; int lastOffset; StringBuilder buffer = new StringBuilder(); StringBuilder number = new StringBuilder(); StringHelperStatusCode result = StringHelper.ReadStringChars(_input, buffer, number, true, out lastLine, out lastOffset); // throw exceptions for selected errors: switch (result) { case StringHelperStatusCode.UnexpectedEoF: throw new JSonReaderException("Unexpected end of text while reading a string", PopTopToken()); case StringHelperStatusCode.UnexpectedNewLine: throw new JSonReaderException("Unexpected new line character in the middle of a string", buffer.ToString(), beginLine, beginOffset); case StringHelperStatusCode.UnknownEscapedChar: throw new JSonReaderException("Unknown escape combination", _input.CurrentChar.ToString(), lastLine, lastOffset); case StringHelperStatusCode.TooShortEscapedChar: throw new JSonReaderException("Invalid escape definition of Unicode character", _input.CurrentChar.ToString(), lastLine, lastOffset); case StringHelperStatusCode.TooLongEscapedChar: throw new JSonReaderException("Too long Unicode number definition", number.ToString(), lastLine, lastOffset); } // remove the beggining of the string token " from the top of the tokens stack PopTopToken(); return(_factory.CreateString(buffer.ToString())); }
/// <summary> /// Reads the string from given input stream. /// </summary> internal static StringHelperStatusCode ReadStringChars(IStringReader reader, StringBuilder output, StringBuilder escapedUnicodeNumberBuffer, bool errorOnNewLine, out int lastLine, out int lastOffset) { bool escape = false; bool unicodeNumber = false; if (escapedUnicodeNumberBuffer == null) { escapedUnicodeNumberBuffer = new StringBuilder(); } lastLine = reader.Line; lastOffset = reader.LineOffset; do { if (!unicodeNumber) { lastLine = reader.Line; lastOffset = reader.LineOffset; } var currentChar = reader.ReadNext(); // verify if not an invalid character was found in text: if (reader.IsEof) { return(StringHelperStatusCode.UnexpectedEoF); } if (errorOnNewLine && (currentChar == '\r' || currentChar == '\n')) { return(StringHelperStatusCode.UnexpectedNewLine); } if (unicodeNumber) { StringHelperStatusCode result = ReadStringUnicodeCharacter(currentChar, output, escapedUnicodeNumberBuffer, out unicodeNumber); // if parsing Unicode character failed, immediatelly stop! if (result != StringHelperStatusCode.Success) { return(result); } continue; } if (currentChar == '\\' && !escape) { escape = true; } else { if (escape) { switch (currentChar) { case 'n': output.Append('\n'); break; case 'r': output.Append('\r'); break; case 't': output.Append('\t'); break; case '/': output.Append('/'); break; case '\\': output.Append('\\'); break; case 'f': output.Append('\f'); break; case 'U': case 'u': unicodeNumber = true; break; case '"': output.Append('"'); break; case '\'': output.Append('\''); break; default: return(StringHelperStatusCode.UnknownEscapedChar); } escape = false; } else { if (currentChar == '"') { break; } output.Append(currentChar); } } }while (true); // as the string might finish with a Unicode character... if (unicodeNumber) { return(AddUnicodeChar(output, escapedUnicodeNumberBuffer, false)); } return(StringHelperStatusCode.Success); }
private static StringList Read(IStringReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } // if there is nothing to read, return an empty instance: if (reader.IsEmpty) { return(new StringList()); } StringBuilder buffer = new StringBuilder(); StringBuilder escapedUnicode = new StringBuilder(); StringListToken token; Dictionary <string, string> result = new Dictionary <string, string>(); string key = null; string value = null; bool identitySpot = false; do { token = ReadNextToken(reader); switch (token) { case StringListToken.CommentLine: // skip till the end of line: StringHelper.ReadCommentChars(reader, false); break; case StringListToken.CommentMultiline: StringHelper.ReadCommentChars(reader, true); break; case StringListToken.Semicolon: // verify if semicolon is at the end of the 'stable' state: if (!string.IsNullOrEmpty(key)) { if (identitySpot && value != null) { if (result.ContainsKey(key)) { result[key] = value; } else { result.Add(key, value); } // reset state: key = null; value = null; identitySpot = false; } else { if (identitySpot) { throw new FormatException("Incomplete definition at: (" + reader.Line + ":" + reader.LineOffset + ")"); } throw new FormatException("Single text without valid assignment found: \"" + key + "\""); } } break; case StringListToken.Identity: if (identitySpot) { throw new FormatException("Double identity operator found"); } identitySpot = true; if (string.IsNullOrEmpty(key)) { throw new FormatException("Empty assignment found"); } break; case StringListToken.String: { if (key != null && value != null) { throw new FormatException("Invalid definition found at: (" + reader.Line + ":" + reader.LineOffset + ")"); } int lastLine; int lastOffset; StringHelperStatusCode status = StringHelper.ReadStringChars(reader, buffer, escapedUnicode, false, out lastLine, out lastOffset); // throw exceptions for selected errors: switch (status) { case StringHelperStatusCode.UnexpectedEoF: throw new FormatException("Unexpected end of file while reading a string: \"" + buffer + "\""); case StringHelperStatusCode.UnexpectedNewLine: throw new FormatException("Unexpected new line character in the middle of a string: \"" + buffer + "\""); case StringHelperStatusCode.UnknownEscapedChar: throw new FormatException("Unknown escape combination: " + reader.CurrentChar); case StringHelperStatusCode.TooShortEscapedChar: throw new FormatException("Invalid escape definition of Unicode character: " + reader.CurrentChar); case StringHelperStatusCode.TooLongEscapedChar: throw new FormatException("Too long Unicode number definition: " + escapedUnicode); } if (identitySpot) { value = buffer.ToString(); } else { if (key != null) { throw new FormatException("Missing identity operator"); } key = buffer.ToString(); } buffer.Remove(0, buffer.Length); } break; case StringListToken.Eof: if (identitySpot) { throw new FormatException("Missing value for key at the end of the file"); } if (!string.IsNullOrEmpty(key)) { throw new FormatException("Missing definition for key at the of the file"); } return(new StringList(result)); case StringListToken.Invalid: throw new FormatException("Invalid token found at (" + reader.Line + ":" + reader.LineOffset + ")"); } }while (true); }