using System; using System.Text; using System.Collections.Generic; using System.Linq; namespace ln.json { public class JSONString : JSONValue { static System.Tuple[] escapeCharacters = { System.Tuple.Create('\\','\\'), System.Tuple.Create('/','/'), System.Tuple.Create('"','"'), System.Tuple.Create('b','\b'), System.Tuple.Create('f','\f'), System.Tuple.Create('n','\n'), System.Tuple.Create('r','\r'), System.Tuple.Create('t','\t'), }; static HashSet escapeSet = new HashSet(escapeCharacters.Select((x) => x.Item2)); public string Value { get; private set; } public override object ToNative() => Value; public JSONString(String value) :base(JSONValueType.STRING) { Value = value; } public override string ToString() { return String.Format("\"{0}\"", Escape(Value)); } public static string Escape(string source){ StringBuilder sb = new StringBuilder(); foreach (char ch in source){ if (escapeSet.Contains(ch)) { foreach (System.Tuple repl in escapeCharacters) { if (repl.Item2 == ch) { sb.Append("\\"); sb.Append(repl.Item1); break; } } } else if (ch < 128) { sb.Append(ch); } else { byte[] bytes = BitConverter.GetBytes((int)ch); sb.Append("\\u"); sb.AppendFormat("{0:x2}{1:x2}", bytes[1], bytes[0]); } } return sb.ToString(); } public static string Unescape(string jsonString) { StringBuilder sb = new StringBuilder(); CharEnumerator ce = jsonString.GetEnumerator(); char[] hex = new char[4]; while (ce.MoveNext()){ if (ce.Current == '\\'){ ce.MoveNext(); if (ce.Current == 'u') { for (int n = 0; n < 4; n++) { ce.MoveNext(); hex[3 - n] = ce.Current; } sb.Append((char)Convert.ToInt16(new String(hex),16)); } else { foreach (System.Tuple repl in escapeCharacters) { if (repl.Item1 == ce.Current) { sb.Append(repl.Item2); break; } } } } else { sb.Append(ce.Current); } } return sb.ToString(); } } }