public bool TryReadObject(out JsonObjectReader reader, ref JsonObjectFileInfo fileInfo) { fileInfo.StartLine = fileInfo.EndLine; int status; var length = ReadObject(out status, ref fileInfo); if (status == KResultInvalidJson) { throw new Exception($"JsonStreamReader.TryReadObject expected '{{' as the next character. Line=[{fileInfo.EndLine}]"); } if (status != KResultSuccess) { reader = new JsonObjectReader { Line = fileInfo.StartLine }; return(false); } reader = new JsonObjectReader(m_ObjectBuffer, 0, length) { Line = fileInfo.StartLine }; return(true); }
public static void Accept(Stream input, Stream output) { var jsonStreamReader = new JsonStreamReader(input); using (var binaryStream = new MemoryStream()) using (var binaryWriter = new BinaryWriter(binaryStream)) { var commandStreamWriter = new BinaryWriter(output); var c = jsonStreamReader.ReadChar(); // '[' Assert.IsTrue(c == '[', $"FlatJson.FrontEnd.Accept expected '[' but found '{c}' as the first character of the stream. Line=[1]"); var fileInfo = new JsonObjectFileInfo(); // Read the next full json object from '{' to '} JsonObjectReader objectReader; while (jsonStreamReader.TryReadObject(out objectReader, ref fileInfo)) { objectReader.ReadBeginObject(); // Unpack the typeId var property = objectReader.ReadPropertyNameSegment(); Assert.IsTrue(property.Array[property.Offset] == '$'); var typeId = (UTinyTypeId)objectReader.ReadUInt16(); objectReader.Position = 0; commandStreamWriter.Write(CommandType.GetCreateCommandType(typeId)); // Translate the json object to binary BinaryTranslator.TranslateObject(ref objectReader, binaryWriter); // Write the command payload as binary commandStreamWriter.Write((uint)binaryStream.Position); commandStreamWriter.Write(binaryStream.GetBuffer(), 0, (int)binaryStream.Position); binaryStream.Position = 0; c = jsonStreamReader.ReadChar(); // ',' or ']' if (!(c == ',' || c == ']')) { throw new Exception($"FlatJson.FrontEnd.Accept expected ',' or ']' but found '{Escape(c)}' as the next character in the stream. Line=[{objectReader.Line}]"); } } } }
/// <summary> /// Reads a json object from '{' to '}' /// </summary> /// <param name="result">Read result</param> /// <returns>Number of characters read</returns> private int ReadObject(out int result, ref JsonObjectFileInfo fileInfo) { unsafe { fixed(char *p = m_CharBuffer) { result = KResultError; char c; var count = 0; var index = 0; var buffer = m_ObjectBuffer; var length = m_ObjectBuffer.Length; // Read until we hit the first '{' brace var found = false; do { if (m_Position >= m_Count) { // Refill the underlying buffer if (!FillBuffer()) { result = KResultEndOfStream; return(0); } } for (; m_Position < m_Count; m_Position++) { c = *(p + m_Position); if (c == '{') { found = true; break; } switch (c) { case '\n': fileInfo.StartLine++; fileInfo.EndLine++; continue; case ' ': case '\t': case '\r': continue; } result = KResultInvalidJson; return(count); } } while (!found); var begin = m_Position; var depth = 1; m_Position++; // Read until we hit the matching '}' brace found = false; do { // Output buffer bounds check if (index + m_Position - begin >= length - 1) { // realloc length *= 2; m_ObjectBuffer = new char[length]; Array.Copy(buffer, m_ObjectBuffer, index); buffer = m_ObjectBuffer; } if (m_Position >= m_Count) { // Copy to the output buffer var len = m_Count - begin; Array.Copy(m_CharBuffer, begin, buffer, index, len); index += len; count += len; // Refill the underlying buffer if (!FillBuffer()) { result = KResultEndOfStream; return(count); } begin = m_Position; } var end = m_Position + Math.Min(length - (index + m_Position - begin), m_Count - m_Position); for (; m_Position < end; m_Position++) { c = *(p + m_Position); if (c == '{') { depth++; } else if (c == '}') { depth--; if (depth != 0) { continue; } result = KResultSuccess; found = true; m_Position++; break; } else if (c == '\n') { fileInfo.EndLine++; } } } while (!found); // Flush to the output buffer Array.Copy(m_CharBuffer, begin, buffer, index, m_Position - begin); count += m_Position - begin; return(count); } } }