/// <summary> /// Encodes a string for inclusion in JSON. /// </summary> /// <param name="s">String to encode.</param> /// <returns>Encoded string.</returns> public static string Encode(string s) { return(CommonTypes.Escape(s, jsonCharactersToEscape, jsonCharacterEscapes)); }
private static void Encode(object Object, int?Indent, StringBuilder Json) { if (Object == null) { Json.Append("null"); } else { Type T = Object.GetType(); TypeInfo TI = T.GetTypeInfo(); if (TI.IsValueType) { if (Object is bool b) { Json.Append(CommonTypes.Encode(b)); } else if (Object is char ch) { Json.Append('"'); Json.Append(Encode(new string(ch, 1))); Json.Append('"'); } else if (Object is double dbl) { Json.Append(CommonTypes.Encode(dbl)); } else if (Object is float fl) { Json.Append(CommonTypes.Encode(fl)); } else if (Object is decimal dec) { Json.Append(CommonTypes.Encode(dec)); } else if (TI.IsEnum) { Json.Append('"'); Json.Append(Encode(Object.ToString())); Json.Append('"'); } else if (Object is DateTime TP) { Json.Append(((int)((TP.ToUniversalTime() - UnixEpoch).TotalSeconds)).ToString()); } else { Json.Append(Object.ToString()); } } else if (Object is string s) { Json.Append('"'); Json.Append(Encode(s)); Json.Append('"'); } else if (Object is IEnumerable <KeyValuePair <string, object> > Obj) { Encode(Obj, Indent, Json, null); } else if (Object is IEnumerable E) { IEnumerator e = E.GetEnumerator(); bool First = true; Json.Append('['); if (Indent.HasValue) { Indent = Indent + 1; } while (e.MoveNext()) { if (First) { First = false; } else { Json.Append(','); } if (Indent.HasValue) { Json.AppendLine(); Json.Append(new string('\t', Indent.Value)); } Encode(e.Current, Indent, Json); } if (!First && Indent.HasValue) { Json.AppendLine(); Indent = Indent - 1; Json.Append(new string('\t', Indent.Value)); } Json.Append(']'); } else { throw new ArgumentException("Unsupported type: " + T.FullName, nameof(Object)); } } }
private static object Parse(string Json, ref int Pos, int Len) { StringBuilder sb = null; int State = 0; int Start = 0; int i = 0; char ch; while (Pos < Len) { ch = Json[Pos++]; switch (State) { case 0: if (ch <= ' ' || ch == 160) { break; } if ((ch >= '0' && ch <= '9') || (ch == '-') || (ch == '+')) { Start = Pos - 1; State++; } else if (ch == '.') { Start = Pos - 1; State += 2; } else if (ch == '"') { sb = new StringBuilder(); State += 5; } else if (ch == 't') { State += 11; } else if (ch == 'f') { State += 14; } else if (ch == 'n') { State += 18; } else if (ch == '[') { while (Pos < Len && ((ch = Json[Pos]) <= ' ' || ch == 160)) { Pos++; } if (Pos >= Len) { throw new Exception("Unexpected end of JSON."); } if (ch == ']') { return(new object[0]); } List <object> Array = new List <object>(); while (true) { Array.Add(JSON.Parse(Json, ref Pos, Len)); while (Pos < Len && ((ch = Json[Pos]) <= ' ' || ch == 160)) { Pos++; } if (Pos >= Len) { throw new Exception("Unexpected end of JSON."); } if (ch == ']') { break; } else if (ch == ',') { Pos++; } else { throw new Exception("Invalid JSON."); } } Pos++; return(Array.ToArray()); } else if (ch == '{') { Dictionary <string, object> Object = new Dictionary <string, object>(); while (Pos < Len && ((ch = Json[Pos]) <= ' ' || ch == 160)) { Pos++; } if (Pos >= Len) { throw new Exception("Unexpected end of JSON."); } if (ch == '}') { Pos++; return(Object); } while (true) { if (!(JSON.Parse(Json, ref Pos, Len) is string Key)) { throw new Exception("Expected member name."); } while (Pos < Len && ((ch = Json[Pos]) <= ' ' || ch == 160)) { Pos++; } if (Pos >= Len) { throw new Exception("Unexpected end of JSON."); } if (ch != ':') { throw new Exception("Expected :"); } Pos++; Object[Key] = JSON.Parse(Json, ref Pos, Len); while (Pos < Len && ((ch = Json[Pos]) <= ' ' || ch == 160)) { Pos++; } if (Pos >= Len) { throw new Exception("Unexpected end of JSON."); } if (ch == '}') { break; } else if (ch == ',') { Pos++; } else { throw new Exception("Invalid JSON."); } } Pos++; return(Object); } else { throw new Exception("Invalid JSON."); } break; case 1: // Number (Integer?) if (ch >= '0' && ch <= '9') { break; } else if (ch == '.') { State++; } else if (ch == 'e' || ch == 'E') { State += 2; } else { Pos--; string s = Json.Substring(Start, Pos - Start); if (int.TryParse(s, out i)) { return(i); } else if (long.TryParse(s, out long l)) { return(l); } else if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } break; case 2: // Decimal number, decimal part. if (ch >= '0' && ch <= '9') { break; } else if (ch == 'e' || ch == 'E') { State++; } else { Pos--; string s = Json.Substring(Start, Pos - Start); if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } break; case 3: // Decimal number, exponent sign. if (ch == '+' || ch == '-' || (ch >= '0' && ch <= '9')) { State++; } else { throw new Exception("Invalid JSON."); } break; case 4: // Decimal number, exponent. if (ch >= '0' && ch <= '9') { break; } else { Pos--; string s = Json.Substring(Start, Pos - Start); if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } case 5: // String. if (ch == '\\') { State++; } else if (ch == '"') { return(sb.ToString()); } else { sb.Append(ch); } break; case 6: // String, escaped character. switch (ch) { case 'a': sb.Append('\a'); break; case 'b': sb.Append('\b'); break; case 'f': sb.Append('\f'); break; case 'n': sb.Append('\n'); break; case 'r': sb.Append('\r'); break; case 't': sb.Append('\t'); break; case 'v': sb.Append('\v'); break; case 'x': i = 0; State += 4; break; case 'u': i = 0; State += 2; break; default: sb.Append(ch); break; } State--; break; case 7: // hex digit 1(4) i = HexDigit(ch); State++; break; case 8: // hex digit 2(4) i <<= 4; i |= HexDigit(ch); State++; break; case 9: // hex digit 3(4) i <<= 4; i |= HexDigit(ch); State++; break; case 10: // hex digit 4(4) i <<= 4; i |= HexDigit(ch); sb.Append((char)i); State -= 5; break; case 11: // True if (ch == 'r') { State++; break; } else { throw new Exception("Invalid JSON."); } case 12: // tRue if (ch == 'u') { State++; break; } else { throw new Exception("Invalid JSON."); } case 13: // trUe if (ch == 'e') { return(true); } else { throw new Exception("Invalid JSON."); } case 14: // False if (ch == 'a') { State++; break; } else { throw new Exception("Invalid JSON."); } case 15: // fAlse if (ch == 'l') { State++; break; } else { throw new Exception("Invalid JSON."); } case 16: // faLse if (ch == 's') { State++; break; } else { throw new Exception("Invalid JSON."); } case 17: // falsE if (ch == 'e') { return(false); } else { throw new Exception("Invalid JSON."); } case 18: // Null if (ch == 'u') { State++; break; } else { throw new Exception("Invalid JSON."); } case 19: // nUll if (ch == 'l') { State++; break; } else { throw new Exception("Invalid JSON."); } case 20: // nuLl if (ch == 'l') { return(null); } else { throw new Exception("Invalid JSON."); } } } if (State == 1) { string s = Json.Substring(Start, Pos - Start); if (int.TryParse(s, out i)) { return(i); } else if (long.TryParse(s, out long l)) { return(l); } else if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } else if (State == 2) { string s = Json.Substring(Start, Pos - Start); if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } else if (State == 4) { string s = Json.Substring(Start, Pos - Start); if (CommonTypes.TryParse(s, out double d)) { return(d); } else if (CommonTypes.TryParse(s, out decimal dec)) { return(dec); } else { throw new Exception("Invalid JSON."); } } else { throw new Exception("Unexpected end of JSON."); } }
/// <summary> /// <see cref="Object.ToString()"/> /// </summary> public override string ToString() { StringBuilder sb = new StringBuilder(); if (this.negation) { sb.Append('-'); } sb.Append('P'); if (this.years != 0) { sb.Append(this.years.ToString()); sb.Append('Y'); } if (this.months != 0) { sb.Append(this.months.ToString()); sb.Append('M'); } if (this.days != 0) { sb.Append(this.days.ToString()); sb.Append('D'); } if (this.hours != 0 || this.minutes != 0 || this.seconds != 0) { sb.Append('T'); if (this.hours != 0) { sb.Append(this.hours.ToString()); sb.Append('H'); } if (this.minutes != 0) { sb.Append(this.minutes.ToString()); sb.Append('M'); } if (this.seconds != 0) { sb.Append(CommonTypes.Encode(this.seconds)); sb.Append('S'); } } string Result = sb.ToString(); if (Result.Length <= 2) { Result += "T0S"; } return(Result); }
private static void Encode(object Object, int?Indent, StringBuilder Json) { if (Object is null) { Json.Append("null"); } else { Type T = Object.GetType(); TypeInfo TI = T.GetTypeInfo(); if (TI.IsValueType) { if (Object is bool b) { Json.Append(CommonTypes.Encode(b)); } else if (Object is char ch) { Json.Append('"'); Json.Append(Encode(new string(ch, 1))); Json.Append('"'); } else if (Object is double dbl) { Json.Append(CommonTypes.Encode(dbl)); } else if (Object is float fl) { Json.Append(CommonTypes.Encode(fl)); } else if (Object is decimal dec) { Json.Append(CommonTypes.Encode(dec)); } else if (TI.IsEnum) { Json.Append('"'); Json.Append(Encode(Object.ToString())); Json.Append('"'); } else if (Object is DateTime TP) { Json.Append(((int)((TP.ToUniversalTime() - UnixEpoch).TotalSeconds)).ToString()); } else { Json.Append(Object.ToString()); } } else if (Object is string s) { Json.Append('"'); Json.Append(Encode(s)); Json.Append('"'); } else if (Object is IEnumerable <KeyValuePair <string, object> > Obj) { Encode(Obj, Indent, Json, null); } else if (Object is IEnumerable <KeyValuePair <string, IElement> > Obj2) { Encode(Obj2, Indent, Json); } else if (Object is IEnumerable E) { IEnumerator e = E.GetEnumerator(); bool First = true; Json.Append('['); if (Indent.HasValue) { Indent++; } while (e.MoveNext()) { if (First) { First = false; } else { Json.Append(','); } if (Indent.HasValue) { Json.AppendLine(); Json.Append(new string('\t', Indent.Value)); } Encode(e.Current, Indent, Json); } if (!First && Indent.HasValue) { Json.AppendLine(); Indent--; Json.Append(new string('\t', Indent.Value)); } Json.Append(']'); } else if (Object is ObjectMatrix M && !(M.ColumnNames is null)) { bool First = true; Json.Append('['); if (Indent.HasValue) { Indent++; } foreach (IElement Element in M.VectorElements) { if (First) { First = false; Encode(M.ColumnNames, Indent, Json); } Json.Append(','); if (Indent.HasValue) { Json.AppendLine(); Json.Append(new string('\t', Indent.Value)); } Encode(Element.AssociatedObjectValue, Indent, Json); } if (!First && Indent.HasValue) { Json.AppendLine(); Indent--; Json.Append(new string('\t', Indent.Value)); } Json.Append(']'); }
/// <summary> /// Decodes an object. /// </summary> /// <param name="ContentType">Internet Content Type.</param> /// <param name="Data">Encoded object.</param> /// <param name="BaseUri">Base URI, if any. If not available, value is null.</param> /// <returns>Decoded object.</returns> /// <exception cref="ArgumentException">If the object cannot be decoded.</exception> public static object Decode(string ContentType, byte[] Data, Uri BaseUri) { Encoding Encoding = null; KeyValuePair <string, string>[] Fields; int i; i = ContentType.IndexOf(';'); if (i > 0) { Fields = CommonTypes.ParseFieldValues(ContentType.Substring(i + 1).TrimStart()); ContentType = ContentType.Substring(0, i).TrimEnd(); foreach (KeyValuePair <string, string> Field in Fields) { if (Field.Key.ToUpper() == "CHARSET") { // Reference: http://www.iana.org/assignments/character-sets/character-sets.xhtml switch (Field.Value.ToUpper()) { case "ASCII": case "US-ASCII": Encoding = Encoding.ASCII; break; case "UTF-16LE": case "UTF-16": Encoding = Encoding.Unicode; break; case "UTF-16BE": Encoding = Encoding.BigEndianUnicode; break; case "UTF-32": case "UTF-32LE": Encoding = Encoding.UTF32; break; case "UNICODE-1-1-UTF-7": case "UTF-7": Encoding = Encoding.UTF7; break; case "UTF-8": Encoding = Encoding.UTF8; break; default: Encoding = Encoding.GetEncoding(Field.Value); break; } } } } else { Fields = new KeyValuePair <string, string> [0]; } return(Decode(ContentType, Data, Encoding, Fields, BaseUri)); }
private static void Encode(object Object, int?Indent, StringBuilder Json) { if (Object == null) { Json.Append("null"); } else { Type T = Object.GetType(); TypeInfo TI = T.GetTypeInfo(); if (TI.IsValueType) { if (Object is bool b) { Json.Append(CommonTypes.Encode(b)); } else if (Object is char ch) { Json.Append('"'); Json.Append(Encode(new string(ch, 1))); Json.Append('"'); } else if (Object is double dbl) { Json.Append(CommonTypes.Encode(dbl)); } else if (Object is float fl) { Json.Append(CommonTypes.Encode(fl)); } else if (Object is decimal dec) { Json.Append(CommonTypes.Encode(dec)); } else if (TI.IsEnum) { Json.Append('"'); Json.Append(Encode(Object.ToString())); Json.Append('"'); } else { Json.Append(Object.ToString()); } } else if (Object is string s) { Json.Append('"'); Json.Append(Encode(s)); Json.Append('"'); } else if (Object is Dictionary <string, object> Obj) { bool First = true; Json.Append('{'); if (Indent.HasValue) { Indent = Indent + 1; } foreach (KeyValuePair <string, object> Member in Obj) { if (First) { First = false; } else { Json.Append(','); } if (Indent.HasValue) { Json.AppendLine(); Json.Append(new string('\t', Indent.Value)); } Json.Append('"'); Json.Append(Encode(Member.Key)); Json.Append("\":"); if (Indent.HasValue) { Json.Append(' '); } Encode(Member.Value, Indent, Json); } if (!First) { Json.AppendLine(); if (Indent.HasValue) { Indent = Indent - 1; } Json.Append(new string('\t', Indent.Value)); } Json.Append('}'); } else if (Object is IEnumerable E) { IEnumerator e = E.GetEnumerator(); bool First = true; Json.Append('['); if (Indent.HasValue) { Indent = Indent + 1; } while (e.MoveNext()) { if (First) { First = false; } else { Json.Append(','); } if (Indent.HasValue) { Json.AppendLine(); Json.Append(new string('\t', Indent.Value)); } Encode(e.Current, Indent, Json); } if (!First) { Json.AppendLine(); if (Indent.HasValue) { Indent = Indent - 1; } Json.Append(new string('\t', Indent.Value)); } Json.Append(']'); } else { throw new ArgumentException("Unsupported type: " + T.FullName, nameof(Object)); } } }