diff --git a/Assets/UniGLTF/Runtime/UniJSON/Json/JsonString.cs b/Assets/UniGLTF/Runtime/UniJSON/Json/JsonString.cs index 5fb5a95e4..ed145f272 100644 --- a/Assets/UniGLTF/Runtime/UniJSON/Json/JsonString.cs +++ b/Assets/UniGLTF/Runtime/UniJSON/Json/JsonString.cs @@ -64,7 +64,7 @@ namespace UniJSON } var it = s.GetIterator(); - while(it.MoveNext()) + while (it.MoveNext()) { var l = it.CurrentByteLength; if (l == 1) @@ -174,6 +174,43 @@ namespace UniJSON #endregion #region Unquote + static byte CheckHex(int b) + { + switch ((char)b) + { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'A': + case 'a': + return 10; + case 'B': + case 'b': + return 11; + case 'C': + case 'c': + return 12; + case 'D': + case 'd': + return 13; + case 'E': + case 'e': + return 14; + case 'F': + case 'f': + return 15; + } + + throw new ArgumentOutOfRangeException(); + } + public static int Unescape(string src, IStore w) { int writeCount = 0; @@ -223,6 +260,17 @@ namespace UniJSON Write('\t'); i += 2; continue; + case 'u': + { + var u0 = CheckHex(src[i + 2]); + var u1 = CheckHex(src[i + 3]); + var u2 = CheckHex(src[i + 4]); + var u3 = CheckHex(src[i + 5]); + var u = (u0 << 12) + (u1 << 8) + (u2 << 4) + u3; + Write((char)u); + i += 6; + } + continue; } } @@ -250,7 +298,7 @@ namespace UniJSON }; var it = s.GetIterator(); - while(it.MoveNext()) + while (it.MoveNext()) { var l = it.CurrentByteLength; if (l == 1) @@ -288,6 +336,33 @@ namespace UniJSON Write((Byte)'\t'); it.MoveNext(); continue; + case (Byte)'u': + { + // skip back slash + it.MoveNext(); + // skip u + it.MoveNext(); + + var u0 = CheckHex((char)it.Current); + it.MoveNext(); + + var u1 = CheckHex((char)it.Current); + it.MoveNext(); + + var u2 = CheckHex((char)it.Current); + it.MoveNext(); + + var u3 = CheckHex((char)it.Current); + + var u = (u0 << 12) + (u1 << 8) + (u2 << 4) + u3; + var utf8 = Utf8String.From(new string(new char[] { (char)u })); + // var utf8 = Utf8String.From((int)u); + foreach (var x in utf8.Bytes) + { + Write(x); + } + } + continue; } } diff --git a/Assets/UniGLTF/Tests/UniJSON/Utf8StringTest.cs b/Assets/UniGLTF/Tests/UniJSON/Utf8StringTest.cs index 44379dc15..30e6e5b04 100644 --- a/Assets/UniGLTF/Tests/UniJSON/Utf8StringTest.cs +++ b/Assets/UniGLTF/Tests/UniJSON/Utf8StringTest.cs @@ -1,6 +1,7 @@ using NUnit.Framework; +using System.IO; using System.Linq; - +using System.Text; namespace UniJSON { @@ -168,10 +169,38 @@ namespace UniJSON [Test] public void UnicodeEscapeTest() { - var src = "\"\\u8868\\u60c5\""; - var json = src.ParseAsJson(); - var decoded = json.GetString(); - Assert.AreEqual("表情", decoded); + // UTF-8 Encoding: 0xE8 0xA1 0xA8 + // UTF-16 Encoding: 0x8868 + // UTF-32 Encoding: 0x00008868 + + { + var src = "\"\\u8868\\u60c5\""; + var json = src.ParseAsJson(); + var decoded = json.GetString(); + Assert.AreEqual("表情", decoded); + } + + { + Assert.AreEqual("表"[0], (char)0x8868); + } + + { + var src = Utf8String.From("表"); + var dst = src.Bytes.ToArray(); + Assert.AreEqual(0xE8, dst[0]); + Assert.AreEqual(0xA1, dst[1]); + Assert.AreEqual(0xA8, dst[2]); + } + + { + var src = Utf8String.From("\\u8868"); + var ms = new MemoryStream(); + JsonString.Unescape(src, new StreamStore(ms)); + var dst = ms.ToArray(); + Assert.AreEqual(0xE8, dst[0]); + Assert.AreEqual(0xA1, dst[1]); + Assert.AreEqual(0xA8, dst[2]); + } } } }