private LineResult ReadLine(TbonContext context, int tabCount) { switch (TryReadValueName(context, out var valueName)) { case ValueNameResult.InvalidFormat: throw new FormatException("Invalid format, " + GetDebugInfo(context)); case ValueNameResult.BlankLine: return(LineResult.BlankLine); case ValueNameResult.EndOfFile: return(LineResult.EndOfFile); } switch (TryReadValue(context, out var value)) { case ValueResult.Success: children[valueName] = new TValue(value); break; case ValueResult.EndOfFile: throw new FormatException("End of file occured during value discovery, " + GetDebugInfo(context)); case ValueResult.ObjectValue: children[valueName] = new TObject(context, tabCount + 1); break; } return(LineResult.Success); }
/// <summary> /// Reads the tab count for the line /// </summary> private void ReadTabs(TbonContext context) { int spaces = 0; int peek; while (true) { peek = context.Peek(); if (peek == -1) { context.tabs = -1; return; } if ((char)peek == '\t') { spaces += 4; } else if ((char)peek == ' ') { spaces++; } else { break; } context.Read(); } context.tabs += (spaces + 3) / 4; }
private void Read(TbonContext context, int tabCount) { int blankCount = 0; while (true) { ReadTabs(context); if (context.tabs == -1) { return; } if (context.tabs != tabCount) { return; } switch (ReadLine(context, tabCount)) { case LineResult.BlankLine: if (++blankCount == 2) { nextObject = new TObject(context, tabCount); return; } break; case LineResult.EndOfFile: return; case LineResult.Success: blankCount = 0; break; } } }
private ValueResult TryReadValue(TbonContext context, out string value) { ReadUntil(context, out value, out var stopped, '\n'); switch (stopped) { case '\0': return(string.IsNullOrWhiteSpace(value) ? ValueResult.EndOfFile : ValueResult.Success); case '\n': return(string.IsNullOrWhiteSpace(value) ? ValueResult.ObjectValue : ValueResult.Success); } return(ValueResult.Success); }
private ValueNameResult TryReadValueName(TbonContext context, out string value) { ReadUntil(context, out value, out var stopped, '\n', ':'); switch (stopped) { case '\0': return(ValueNameResult.EndOfFile); case '\n': return(string.IsNullOrWhiteSpace(value) ? ValueNameResult.BlankLine : ValueNameResult.InvalidFormat); case ':': return(ValueNameResult.Success); } return(ValueNameResult.InvalidFormat); }
private void ReadUntil(TbonContext context, out string value, out char stopped, params char[] stopChars) { int charCount = 0; char character; value = null; stopped = '\0'; while (true) { int read = context.Peek(); if (read == -1) { stopped = '\0'; if (charCount == 0) { return; } value = new string(context.characterBuffer, 0, charCount); return; } character = context.Read(); if (TryCharsContain(stopChars, character, out stopped)) { if (charCount == 0) { return; } value = new string(context.characterBuffer, 0, charCount); return; } else { context.characterBuffer[charCount] = character; } charCount++; } }
private string GetDebugInfo(TbonContext context) { return($"line: {context.line + 1}, char: {context.character + 1}"); }
/// <summary> /// Creates a TObject with a given tabbed in count /// </summary> private TObject(TbonContext context, int tabCount) { Read(context, tabCount); }