/// <summary> /// Matches a JSON value: a "string", null, a number (double value), true or false. /// Not error is set if match fails. /// </summary> /// <param name="this">This <see cref="StringMatcher"/>.</param> /// <param name="value">The parsed value. Can be null.</param> /// <returns>True if a JSON value has been matched, false otherwise.</returns> public static bool TryMatchJSONValue(this StringMatcher @this, out object value) { string s; if (@this.TryMatchJSONQuotedString(out s, true)) { value = s; return(true); } double d; if (@this.TryMatchDoubleValue(out d)) { value = d; return(true); } if (@this.TryMatchText("true")) { value = true; return(true); } if (@this.TryMatchText("false")) { value = false; return(true); } value = null; return(false); }
/// <summary> /// Visits a comma seprarated list of "property" : ... fields until a closing } is found /// or <see cref="Matcher"/>.<see cref="StringMatcher.IsEnd">IsEnd</see> becomes true. /// </summary> /// <returns>True on success. On error a message may be retrieved from the <see cref="Matcher"/>.</returns> public virtual bool VisitObjectContent() { int propertyNumber = 0; while (!_m.IsEnd) { SkipWhiteSpaces(); if (_m.TryMatchChar('}')) { return(true); } int startPropertyIndex = _m.StartIndex; string propName; if (!_m.TryMatchJSONQuotedString(out propName)) { return(false); } SkipWhiteSpaces(); if (!_m.MatchChar(':') || !VisitObjectProperty(startPropertyIndex, propName, propertyNumber)) { return(false); } SkipWhiteSpaces(); // This accepts e trailing comma at the end of a property list: ..."a":0,} is not an error. _m.TryMatchChar(','); ++propertyNumber; } return(false); }
/// <summary> /// Matches a JSON value: a "string", null, a number (double value), true or false. /// This method ignores the actual value and does not set any error if match fails. /// </summary> /// <param name="this">This <see cref="StringMatcher"/>.</param> /// <returns>True if a JSON value has been matched, false otherwise.</returns> public static bool TryMatchJSONTerminalValue(this StringMatcher @this) { return(@this.TryMatchJSONQuotedString(true) || @this.TryMatchDoubleValue() || @this.TryMatchText("true") || @this.TryMatchText("false")); }
/// <summary> /// Matches a very simple version of a JSON object content: this match stops at the first closing }. /// Whitespaces and JS comments (//... or /* ... */) are skipped. /// </summary> /// <param name="this">This <see cref="StringMatcher"/>.</param> /// <param name="o">The read object on success as a list of KeyValuePair.</param> /// <returns>True on success, false on error.</returns> public static bool MatchJSONObjectContent(this StringMatcher @this, out List <KeyValuePair <string, object> > o) { o = null; while ([email protected]) { @this.SkipWhiteSpacesAndJSComments(); string propName; object value; if (@this.TryMatchChar('}')) { if (o == null) { o = new List <KeyValuePair <string, object> >(); } return(true); } if ([email protected](out propName)) { o = null; return(@this.SetError("Quoted Property Name.")); } @this.SkipWhiteSpacesAndJSComments(); if ([email protected](':') || !MatchJSONObject(@this, out value)) { o = null; return(false); } if (o == null) { o = new List <KeyValuePair <string, object> >(); } o.Add(new KeyValuePair <string, object>(propName, value)); @this.SkipWhiteSpacesAndJSComments(); // This accepts e trailing comma at the end of a property list: ..."a":0,} is not an error. @this.TryMatchChar(','); } return(@this.SetError("JSON object definition but reached end of match.")); }