mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-10 12:41:57 -05:00
373 lines
11 KiB
C#
373 lines
11 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
|
|
namespace UniJSON
|
|
{
|
|
public static class JsonString
|
|
{
|
|
#region Quote
|
|
public static void Escape(String s, IStore w)
|
|
{
|
|
if (String.IsNullOrEmpty(s))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var it = s.ToCharArray().Cast<char>().GetEnumerator();
|
|
while (it.MoveNext())
|
|
{
|
|
switch (it.Current)
|
|
{
|
|
case '"':
|
|
case '\\':
|
|
case '/':
|
|
// \\ prefix
|
|
w.Write('\\');
|
|
w.Write(it.Current);
|
|
break;
|
|
|
|
case '\b':
|
|
w.Write('\\');
|
|
w.Write('b');
|
|
break;
|
|
case '\f':
|
|
w.Write('\\');
|
|
w.Write('f');
|
|
break;
|
|
case '\n':
|
|
w.Write('\\');
|
|
w.Write('n');
|
|
break;
|
|
case '\r':
|
|
w.Write('\\');
|
|
w.Write('r');
|
|
break;
|
|
case '\t':
|
|
w.Write('\\');
|
|
w.Write('t');
|
|
break;
|
|
|
|
default:
|
|
w.Write(it.Current);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Escape(Utf8String s, IStore w)
|
|
{
|
|
if (s.IsEmpty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var it = s.GetIterator();
|
|
while(it.MoveNext())
|
|
{
|
|
var l = it.CurrentByteLength;
|
|
if (l == 1)
|
|
{
|
|
var b = it.Current;
|
|
switch (b)
|
|
{
|
|
case (Byte)'"':
|
|
case (Byte)'\\':
|
|
case (Byte)'/':
|
|
// \\ prefix
|
|
w.Write((Byte)'\\');
|
|
w.Write(b);
|
|
break;
|
|
|
|
case (Byte)'\b':
|
|
w.Write((Byte)'\\');
|
|
w.Write((Byte)'b');
|
|
break;
|
|
case (Byte)'\f':
|
|
w.Write((Byte)'\\');
|
|
w.Write((Byte)'f');
|
|
break;
|
|
case (Byte)'\n':
|
|
w.Write((Byte)'\\');
|
|
w.Write((Byte)'n');
|
|
break;
|
|
case (Byte)'\r':
|
|
w.Write((Byte)'\\');
|
|
w.Write((Byte)'r');
|
|
break;
|
|
case (Byte)'\t':
|
|
w.Write((Byte)'\\');
|
|
w.Write((Byte)'t');
|
|
break;
|
|
|
|
default:
|
|
w.Write(b);
|
|
break;
|
|
}
|
|
// ascii
|
|
}
|
|
else if (l == 2)
|
|
{
|
|
w.Write(it.Current);
|
|
w.Write(it.Second);
|
|
}
|
|
else if (l == 3)
|
|
{
|
|
w.Write(it.Current);
|
|
w.Write(it.Second);
|
|
w.Write(it.Third);
|
|
}
|
|
else if (l == 4)
|
|
{
|
|
w.Write(it.Current);
|
|
w.Write(it.Second);
|
|
w.Write(it.Third);
|
|
w.Write(it.Fourth);
|
|
}
|
|
else
|
|
{
|
|
throw new ParserException("invalid utf8");
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string Escape(String s)
|
|
{
|
|
var sb = new StringBuilder();
|
|
Escape(s, new StringBuilderStore(sb));
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static void Quote(String s, IStore w)
|
|
{
|
|
w.Write('"');
|
|
Escape(s, w);
|
|
w.Write('"');
|
|
}
|
|
|
|
public static void Quote(Utf8String s, IStore w)
|
|
{
|
|
w.Write((Byte)'"');
|
|
Escape(s, w);
|
|
w.Write((Byte)'"');
|
|
}
|
|
|
|
/// <summary>
|
|
/// Added " and Escape
|
|
/// </summary>
|
|
/// <param name="s"></param>
|
|
/// <param name="w"></param>
|
|
public static string Quote(string s)
|
|
{
|
|
var sb = new StringBuilder();
|
|
Quote(s, new StringBuilderStore(sb));
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static Utf8String Quote(Utf8String s)
|
|
{
|
|
var sb = new BytesStore(s.ByteLength);
|
|
Quote(s, sb);
|
|
return new Utf8String(sb.Bytes);
|
|
}
|
|
#endregion
|
|
|
|
#region Unquote
|
|
public static int Unescape(string src, IStore w)
|
|
{
|
|
int writeCount = 0;
|
|
Action<Char> Write = c =>
|
|
{
|
|
if (w != null)
|
|
{
|
|
w.Write(c);
|
|
}
|
|
++writeCount;
|
|
};
|
|
|
|
int i = 0;
|
|
int length = src.Length - 1;
|
|
while (i < length)
|
|
{
|
|
if (src[i] == '\\')
|
|
{
|
|
var c = src[i + 1];
|
|
switch (c)
|
|
{
|
|
case '\\':
|
|
case '/':
|
|
case '"':
|
|
// remove prefix
|
|
Write(c);
|
|
i += 2;
|
|
continue;
|
|
|
|
case 'b':
|
|
Write('\b');
|
|
i += 2;
|
|
continue;
|
|
case 'f':
|
|
Write('\f');
|
|
i += 2;
|
|
continue;
|
|
case 'n':
|
|
Write('\n');
|
|
i += 2;
|
|
continue;
|
|
case 'r':
|
|
Write('\r');
|
|
i += 2;
|
|
continue;
|
|
case 't':
|
|
Write('\t');
|
|
i += 2;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Write(src[i]);
|
|
i += 1;
|
|
}
|
|
while (i <= length)
|
|
{
|
|
Write(src[i++]);
|
|
}
|
|
|
|
return writeCount;
|
|
}
|
|
|
|
public static int Unescape(Utf8String s, IStore w)
|
|
{
|
|
int writeCount = 0;
|
|
Action<Byte> Write = c =>
|
|
{
|
|
if (w != null)
|
|
{
|
|
w.Write(c);
|
|
}
|
|
++writeCount;
|
|
};
|
|
|
|
var it = s.GetIterator();
|
|
while(it.MoveNext())
|
|
{
|
|
var l = it.CurrentByteLength;
|
|
if (l == 1)
|
|
{
|
|
if (it.Current == (Byte)'\\')
|
|
{
|
|
var c = it.Second;
|
|
switch (c)
|
|
{
|
|
case (Byte)'\\':
|
|
case (Byte)'/':
|
|
case (Byte)'"':
|
|
// remove prefix
|
|
Write(c);
|
|
it.MoveNext();
|
|
continue;
|
|
|
|
case (Byte)'b':
|
|
Write((Byte)'\b');
|
|
it.MoveNext();
|
|
continue;
|
|
case (Byte)'f':
|
|
Write((Byte)'\f');
|
|
it.MoveNext();
|
|
continue;
|
|
case (Byte)'n':
|
|
Write((Byte)'\n');
|
|
it.MoveNext();
|
|
continue;
|
|
case (Byte)'r':
|
|
Write((Byte)'\r');
|
|
it.MoveNext();
|
|
continue;
|
|
case (Byte)'t':
|
|
Write((Byte)'\t');
|
|
it.MoveNext();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Write(it.Current);
|
|
}
|
|
else if (l == 2)
|
|
{
|
|
Write(it.Current);
|
|
Write(it.Second);
|
|
}
|
|
else if (l == 3)
|
|
{
|
|
Write(it.Current);
|
|
Write(it.Second);
|
|
Write(it.Third);
|
|
}
|
|
else if (l == 4)
|
|
{
|
|
Write(it.Current);
|
|
Write(it.Second);
|
|
Write(it.Third);
|
|
Write(it.Fourth);
|
|
}
|
|
else
|
|
{
|
|
throw new ParserException("invalid utf8");
|
|
}
|
|
}
|
|
|
|
return writeCount;
|
|
}
|
|
|
|
public static string Unescape(string src)
|
|
{
|
|
var sb = new StringBuilder();
|
|
Unescape(src, new StringBuilderStore(sb));
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static int Unquote(string src, IStore w)
|
|
{
|
|
return Unescape(src.Substring(1, src.Length - 2), w);
|
|
}
|
|
|
|
public static int Unquote(Utf8String src, IStore w)
|
|
{
|
|
return Unescape(src.Subbytes(1, src.ByteLength - 2), w);
|
|
}
|
|
|
|
public static string Unquote(string src)
|
|
{
|
|
var count = Unquote(src, null);
|
|
if (count == src.Length - 2)
|
|
{
|
|
return src.Substring(1, src.Length - 2);
|
|
}
|
|
else
|
|
{
|
|
var sb = new StringBuilder(count);
|
|
Unquote(src, new StringBuilderStore(sb));
|
|
var str = sb.ToString();
|
|
return str;
|
|
}
|
|
}
|
|
|
|
public static Utf8String Unquote(Utf8String src)
|
|
{
|
|
var count = Unquote(src, null);
|
|
if (count == src.ByteLength - 2)
|
|
{
|
|
return src.Subbytes(1, src.ByteLength - 2);
|
|
}
|
|
else
|
|
{
|
|
var sb = new BytesStore(count);
|
|
Unquote(src, sb);
|
|
return new Utf8String(sb.Bytes);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|