JsonValue ReadCore(bool objectWithoutBraces = false) { int c = objectWithoutBraces ? '{' : SkipPeekChar(); if (c < 0) { throw ParseError("Incomplete input"); } switch (c) { case '[': JsonArray list; WscJsonArray wscL = null; ReadChar(); ResetWhite(); if (ReadWsc) { list = wscL = new WscJsonArray(); } else { list = new JsonArray(); } SkipPeekChar(); if (ReadWsc) { wscL.Comments.Add(GetWhite()); } for (int i = 0; ; i++) { if (SkipPeekChar() == ']') { ReadChar(); break; } if (HasReader) { Reader.Index(i); } var value = ReadCore(); if (HasReader) { Reader.Value(value); } list.Add(value); ResetWhite(); if (SkipPeekChar() == ',') { ReadChar(); ResetWhite(); SkipPeekChar(); } if (ReadWsc) { wscL.Comments.Add(GetWhite()); } } return(list); case '{': JsonObject obj; WscJsonObject wsc = null; if (!objectWithoutBraces) { ReadChar(); ResetWhite(); } if (ReadWsc) { obj = wsc = new WscJsonObject() { RootBraces = !objectWithoutBraces } } ; else { obj = new JsonObject(); } SkipPeekChar(); if (ReadWsc) { wsc.Comments[""] = GetWhite(); } for (; ;) { if (objectWithoutBraces) { if (SkipPeekChar() < 0) { break; } } else if (SkipPeekChar() == '}') { ReadChar(); break; } string name = ReadKeyName(); SkipWhite2(); Expect(':'); SkipWhite2(); if (HasReader) { Reader.Key(name); } var value = ReadCore(); if (HasReader) { Reader.Value(value); } obj.Add(new JsonPair(name, value)); ResetWhite(); if (SkipPeekChar() == ',') { ReadChar(); ResetWhite(); SkipPeekChar(); } if (ReadWsc) { wsc.Comments[name] = GetWhite(); wsc.Order.Add(name); } } return(obj); case '\'': case '"': return(ReadStringLiteral(ReadMlString)); default: return(ReadTfnns(c)); } }
public void Save(JsonValue value, TextWriter tw, int level, bool hasComment, string separator, bool noIndent = false, bool isRootObject = false) { if (value == null) { tw.Write(separator); tw.Write("null"); return; } // check for DSF string dsfValue = HjsonDsf.Stringify(dsfProviders, value); if (dsfValue != null) { tw.Write(separator); tw.Write(dsfValue); return; } switch (value.JsonType) { case JsonType.Object: var obj = value.Qo(); WscJsonObject kw = writeWsc ? obj as WscJsonObject : null; bool showBraces = !isRootObject || (kw != null ? kw.RootBraces : emitRootBraces); if (!noIndent) { if (obj.Count > 0) { Nl(tw, level); } else { tw.Write(separator); } } if (showBraces) { tw.Write('{'); } else { level--; // reduce level for root } if (kw != null) { var kwl = GetWsc(kw.Comments, ""); foreach (string key in kw.Order.Concat(kw.Keys).Distinct()) { if (!obj.ContainsKey(key)) { continue; } var val = obj[key]; tw.Write(kwl); Nl(tw, level + 1); kwl = GetWsc(kw.Comments, key); tw.Write(EscapeName(key)); tw.Write(":"); Save(val, tw, level + 1, TestWsc(kwl), " "); } tw.Write(kwl); if (showBraces) { Nl(tw, level); } } else { bool skipFirst = !showBraces; foreach (JsonPair pair in obj) { if (!skipFirst) { Nl(tw, level + 1); } else { skipFirst = false; } tw.Write(EscapeName(pair.Key)); tw.Write(":"); Save(pair.Value, tw, level + 1, false, " "); } if (showBraces && obj.Count > 0) { Nl(tw, level); } } if (showBraces) { tw.Write('}'); } break; case JsonType.Array: int i = 0, n = value.Count; if (!noIndent) { if (n > 0) { Nl(tw, level); } else { tw.Write(separator); } } tw.Write('['); WscJsonArray whiteL = null; string wsl = null; if (writeWsc) { whiteL = value as WscJsonArray; if (whiteL != null) { wsl = GetWsc(whiteL.Comments, 0); } } for (; i < n; i++) { var v = value[i]; if (whiteL != null) { tw.Write(wsl); wsl = GetWsc(whiteL.Comments, i + 1); } Nl(tw, level + 1); Save(v, tw, level + 1, wsl != null && TestWsc(wsl), "", true); } if (whiteL != null) { tw.Write(wsl); } if (n > 0) { Nl(tw, level); } tw.Write(']'); break; case JsonType.Boolean: tw.Write(separator); tw.Write((bool)value ? "true" : "false"); break; case JsonType.String: WriteString(((JsonPrimitive)value).GetRawString(), tw, level, hasComment, separator); break; default: tw.Write(separator); tw.Write(((JsonPrimitive)value).GetRawString()); break; } }