ln.json/JSONString.cs

100 lines
2.8 KiB
C#

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
namespace ln.json
{
public class JSONString : JSONValue
{
static System.Tuple<char,char>[] 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<char> escapeSet = new HashSet<char>(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<char, char> 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<char, char> repl in escapeCharacters)
{
if (repl.Item1 == ce.Current)
{
sb.Append(repl.Item2);
break;
}
}
}
} else {
sb.Append(ce.Current);
}
}
return sb.ToString();
}
}
}