diff --git a/Packages/UniGLTF/Runtime/UniGLTF/Format/ExtensionsAndExtras/gltfExtension.cs b/Packages/UniGLTF/Runtime/UniGLTF/Format/ExtensionsAndExtras/gltfExtension.cs index 66e32f487..e4d81144e 100644 --- a/Packages/UniGLTF/Runtime/UniGLTF/Format/ExtensionsAndExtras/gltfExtension.cs +++ b/Packages/UniGLTF/Runtime/UniGLTF/Format/ExtensionsAndExtras/gltfExtension.cs @@ -130,8 +130,7 @@ namespace UniGLTF public override string ToString() { - var bytes = m_json.Value.Bytes; - return "import: " + Encoding.UTF8.GetString(bytes.Array, bytes.Offset, bytes.Count); + return "import: " + Encoding.UTF8.GetString(m_json.Value.Bytes.Span); } public IEnumerable> ObjectItems() @@ -147,7 +146,7 @@ namespace UniGLTF public override void Serialize(JsonFormatter f) { - f.Raw(m_json.Value.Bytes); + f.Raw(m_json.Value.Bytes.Span); } } diff --git a/Packages/UniGLTF/Runtime/UniJSON/ByteBuffer.cs b/Packages/UniGLTF/Runtime/UniJSON/ByteBuffer.cs index 019c9835b..990bf55ad 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/ByteBuffer.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/ByteBuffer.cs @@ -67,6 +67,13 @@ namespace UniJSON m_used += buffer.Count; } + public void Push(ReadOnlyMemory buffer) + { + Ensure(buffer.Length); + buffer.Span.CopyTo(new Span(m_buffer, m_used, buffer.Length)); + m_used += buffer.Length; + } + public void Unshift(int size) { if (size > m_used) diff --git a/Packages/UniGLTF/Runtime/UniJSON/IStore/BytesStore.cs b/Packages/UniGLTF/Runtime/UniJSON/IStore/BytesStore.cs index 67bfd151c..cceb45ebc 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/IStore/BytesStore.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/IStore/BytesStore.cs @@ -93,6 +93,13 @@ namespace UniJSON m_pos += bytes.Count; } + public void Write(ReadOnlySpan bytes) + { + Require(bytes.Length); + bytes.CopyTo(new Span(m_buffer, m_pos, bytes.Length)); + m_pos += bytes.Length; + } + public void Write(sbyte value) { Require(Marshal.SizeOf(value)); diff --git a/Packages/UniGLTF/Runtime/UniJSON/IStore/IStore.cs b/Packages/UniGLTF/Runtime/UniJSON/IStore/IStore.cs index 7c552afa4..0fa9c8f3f 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/IStore/IStore.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/IStore/IStore.cs @@ -33,6 +33,7 @@ namespace UniJSON void WriteLittleEndian(Double value); void Write(ArraySegment bytes); + void Write(ReadOnlySpan bytes) => Write(new ArraySegment(bytes.ToArray())); void Write(string src); void Write(char c); @@ -55,6 +56,11 @@ namespace UniJSON s.Write(new ArraySegment(bytes.ToArray())); } + public static void Write(this IStore s, ReadOnlyMemory bytes) + { + s.Write(bytes.Span); + } + public static Utf8String ToUtf8String(this IStore s) { return new Utf8String(s.Bytes); diff --git a/Packages/UniGLTF/Runtime/UniJSON/IStore/StreamStore.cs b/Packages/UniGLTF/Runtime/UniJSON/IStore/StreamStore.cs index 191a83612..be091dd97 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/IStore/StreamStore.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/IStore/StreamStore.cs @@ -62,6 +62,11 @@ namespace UniJSON m_w.Write(bytes.Array, bytes.Offset, bytes.Count); } + public void Write(ReadOnlySpan bytes) + { + m_s.Write(bytes); + } + #region BigEndian public void WriteBigEndian(int value) { diff --git a/Packages/UniGLTF/Runtime/UniJSON/IStore/StringBuilderStore.cs b/Packages/UniGLTF/Runtime/UniJSON/IStore/StringBuilderStore.cs index 5ea55c925..fcac0c7b0 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/IStore/StringBuilderStore.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/IStore/StringBuilderStore.cs @@ -40,6 +40,11 @@ namespace UniJSON Write(text); } + public void Write(ReadOnlySpan bytes) + { + Write(Encoding.UTF8.GetString(bytes)); + } + public void Write(byte value) { throw new NotImplementedException(); diff --git a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonFormatter.cs b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonFormatter.cs index 9a9132de8..0e5f5c3bb 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonFormatter.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonFormatter.cs @@ -266,6 +266,12 @@ namespace UniJSON m_w.Write(x); } + public void Raw(ReadOnlySpan x) + { + CommaCheck(); + m_w.Write(x); + } + // ISO-8601: YYYY-MM-DD“T”hh:mm:ss“Z” public void Value(DateTimeOffset x) { diff --git a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonParser.cs b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonParser.cs index 1da036317..21a2c2e73 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonParser.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonParser.cs @@ -153,7 +153,7 @@ namespace UniJSON } // fix array range - var count = current.Bytes.Offset + 1 - segment.Bytes.Offset; + var count = segment.ByteLength - current.ByteLength + 1; array.SetValueBytesCount(count); return array; @@ -242,7 +242,7 @@ namespace UniJSON } // fix obj range - var count = current.Bytes.Offset + 1 - segment.Bytes.Offset; + var count = segment.ByteLength - current.ByteLength + 1; obj.SetValueBytesCount(count); return obj; diff --git a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonString.cs b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonString.cs index 712593d78..6bbaedf34 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonString.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonString.cs @@ -357,7 +357,7 @@ namespace UniJSON 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) + foreach (var x in utf8.Bytes.Span) { Write(x); } diff --git a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonValue.cs b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonValue.cs index 1e0d6545f..2c67c5877 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Json/JsonValue.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Json/JsonValue.cs @@ -6,10 +6,10 @@ namespace UniJSON public struct JsonValue { public Utf8String Segment; - public ArraySegment Bytes { get { return Segment.Bytes; } } + public ReadOnlyMemory Bytes { get { return Segment.Bytes; } } public void SetBytesCount(int count) { - Segment = new Utf8String(new ArraySegment(Bytes.Array, Bytes.Offset, count)); + Segment = new Utf8String(Segment.Bytes.Slice(0, count)); } public ValueNodeType ValueType diff --git a/Packages/UniGLTF/Runtime/UniJSON/ListTreeNode/ListTreeNode.cs b/Packages/UniGLTF/Runtime/UniJSON/ListTreeNode/ListTreeNode.cs index fffb72146..00d217816 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/ListTreeNode/ListTreeNode.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/ListTreeNode/ListTreeNode.cs @@ -332,6 +332,11 @@ namespace UniJSON return AddValue(default(JsonValue).New(bytes, valueType, ValueIndex)); } + public JsonNode AddValue(ReadOnlyMemory bytes, ValueNodeType valueType) + { + return AddValue(new JsonValue(new Utf8String(bytes), valueType, ValueIndex)); + } + public JsonNode AddValue(JsonValue value) { if (m_Values == null) diff --git a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8Iterator.cs b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8Iterator.cs index 440703aa2..9dbc22bb8 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8Iterator.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8Iterator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; @@ -7,24 +7,20 @@ namespace UniJSON { public struct Utf8Iterator : IEnumerator { - Byte[] m_bytes; - int m_offset; + ReadOnlyMemory m_memory; int m_start; int m_position; - int m_end; - public Utf8Iterator(ArraySegment range, int start = 0) + public Utf8Iterator(ReadOnlyMemory memory, int start = 0) { - m_bytes = range.Array; - m_offset = range.Offset; - m_start = m_offset + start; + m_memory = memory; + m_start = start; m_position = -1; - m_end = range.Offset + range.Count; } public int BytePosition { - get { return m_position - m_offset; } + get { return m_position; } } public int CurrentByteLength @@ -57,7 +53,7 @@ namespace UniJSON public byte Current { - get { return m_bytes[m_position]; } + get { return m_memory.Span[m_position]; } } object IEnumerator.Current @@ -67,17 +63,17 @@ namespace UniJSON public byte Second { - get { return m_bytes[m_position + 1]; } + get { return m_memory.Span[m_position + 1]; } } public byte Third { - get { return m_bytes[m_position + 2]; } + get { return m_memory.Span[m_position + 2]; } } public byte Fourth { - get { return m_bytes[m_position + 3]; } + get { return m_memory.Span[m_position + 3]; } } public const uint Mask1 = 0x01; @@ -188,7 +184,7 @@ namespace UniJSON { m_position += CurrentByteLength; } - return m_position < m_end; + return m_position < m_memory.Length; } public void Reset() diff --git a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8String.cs b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8String.cs index 734132be4..592fe1825 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8String.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8String.cs @@ -8,10 +8,10 @@ namespace UniJSON { public static readonly System.Text.Encoding Encoding = new System.Text.UTF8Encoding(false); - public readonly ArraySegment Bytes; + public readonly ReadOnlyMemory Bytes; public int ByteLength { - get { return Bytes.Count; } + get { return Bytes.Length; } } public Utf8Iterator GetIterator() @@ -49,20 +49,27 @@ namespace UniJSON public Byte this[int i] { - get { return Bytes.Array[Bytes.Offset + i]; } + get { return Bytes.Span[i]; } } - public Utf8String(ArraySegment bytes) + public Utf8String(ReadOnlyMemory bytes) { Bytes = bytes; } - public Utf8String(Byte[] bytes, int offset, int count) : this(new ArraySegment(bytes, offset, count)) + public Utf8String(ArraySegment bytes) { + Bytes = new ReadOnlyMemory(bytes.Array, bytes.Offset, bytes.Count); } - public Utf8String(Byte[] bytes) : this(bytes, 0, bytes.Length) + public Utf8String(Byte[] bytes, int offset, int count) { + Bytes = new ReadOnlyMemory(bytes, offset, count); + } + + public Utf8String(Byte[] bytes) + { + Bytes = new ReadOnlyMemory(bytes); } public static Utf8String From(string src) @@ -99,14 +106,14 @@ namespace UniJSON bytes[pos++] = (byte)(Utf8Iterator.Head1 | Utf8Iterator.Mask6 & (c)); } } - return new Utf8String(new ArraySegment(bytes, 0, pos)); + return new Utf8String(bytes, 0, pos); } public Utf8String Concat(Utf8String rhs) { var bytes = new Byte[ByteLength + rhs.ByteLength]; - Buffer.BlockCopy(Bytes.Array, Bytes.Offset, bytes, 0, ByteLength); - Buffer.BlockCopy(rhs.Bytes.Array, rhs.Bytes.Offset, bytes, ByteLength, rhs.ByteLength); + Bytes.Span.CopyTo(bytes); + rhs.Bytes.Span.CopyTo(bytes.AsSpan(ByteLength)); return new Utf8String(bytes); } @@ -115,13 +122,13 @@ namespace UniJSON public override string ToString() { if (ByteLength == 0) return ""; - return Encoding.GetString(Bytes.Array, Bytes.Offset, Bytes.Count); + return Encoding.GetString(Bytes.Span); } public string ToAscii() { if (ByteLength == 0) return ""; - return System.Text.Encoding.ASCII.GetString(Bytes.Array, Bytes.Offset, Bytes.Count); + return System.Text.Encoding.ASCII.GetString(Bytes.Span); } public bool IsEmpty @@ -175,12 +182,12 @@ namespace UniJSON public int IndexOf(int offset, Byte code) { - var pos = offset + Bytes.Offset; - for (int i = 0; i < Bytes.Count; ++i, ++pos) + var span = Bytes.Span; + for (int i = offset; i < span.Length; ++i) { - if (Bytes.Array[pos] == code) + if (span[i] == code) { - return pos - Bytes.Offset; + return i; } } return -1; @@ -193,7 +200,7 @@ namespace UniJSON public Utf8String Subbytes(int offset, int count) { - return new Utf8String(Bytes.Array, Bytes.Offset + offset, count); + return new Utf8String(Bytes.Slice(offset, count)); } static bool IsSpace(Byte b) @@ -283,7 +290,7 @@ namespace UniJSON public static Utf8String operator +(Utf8String l, Utf8String r) { - return new Utf8String(l.Bytes.Concat(r.Bytes)); + return l.Concat(r); } public bool IsInt diff --git a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8StringExtensions.cs b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8StringExtensions.cs index 8222a258a..c9530bd1c 100644 --- a/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8StringExtensions.cs +++ b/Packages/UniGLTF/Runtime/UniJSON/Utf8String/Utf8StringExtensions.cs @@ -11,7 +11,7 @@ namespace UniJSON { public static void WriteTo(this Utf8String src, Stream dst) { - dst.Write(src.Bytes.Array, src.Bytes.Offset, src.Bytes.Count); + dst.Write(src.Bytes.Span); } public static Utf8Iterator GetFirst(this Utf8String src) diff --git a/Packages/UniGLTF/Tests/UniJSON/Json/JsonParserTest.cs b/Packages/UniGLTF/Tests/UniJSON/Json/JsonParserTest.cs index 34da625b5..4b4f546c5 100644 --- a/Packages/UniGLTF/Tests/UniJSON/Json/JsonParserTest.cs +++ b/Packages/UniGLTF/Tests/UniJSON/Json/JsonParserTest.cs @@ -26,8 +26,7 @@ namespace UniJSON { { var node = JsonParser.Parse("null"); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(4, node.Value.Bytes.Count); + Assert.AreEqual(4, node.Value.Bytes.Length); Assert.True(node.IsNull()); } } @@ -37,16 +36,14 @@ namespace UniJSON { { var node = JsonParser.Parse("true"); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(4, node.Value.Bytes.Count); + Assert.AreEqual(4, node.Value.Bytes.Length); Assert.True(node.IsBoolean()); Assert.AreEqual(true, node.GetBoolean()); Assert.Catch(typeof(FormatException), () => node.GetDouble()); } { var node = JsonParser.Parse(" false "); - Assert.AreEqual(1, node.Value.Bytes.Offset); - Assert.AreEqual(5, node.Value.Bytes.Count); + Assert.AreEqual(5, node.Value.Bytes.Length); Assert.True(node.IsBoolean()); Assert.AreEqual(false, node.GetBoolean()); } @@ -57,23 +54,20 @@ namespace UniJSON { { var node = JsonParser.Parse("1"); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(1, node.Value.Bytes.Count); + Assert.AreEqual(1, node.Value.Bytes.Length); Assert.True(node.IsInteger()); Assert.AreEqual(1, (int)node.GetDouble()); Assert.Catch(typeof(DeserializationException), () => node.GetBoolean()); } { var node = JsonParser.Parse(" 22 "); - Assert.AreEqual(1, node.Value.Bytes.Offset); - Assert.AreEqual(2, node.Value.Bytes.Count); + Assert.AreEqual(2, node.Value.Bytes.Length); Assert.True(node.IsInteger()); Assert.AreEqual(22, (int)node.GetDouble()); } { var node = JsonParser.Parse(" 3.3 "); - Assert.AreEqual(1, node.Value.Bytes.Offset); - Assert.AreEqual(3, node.Value.Bytes.Count); + Assert.AreEqual(3, node.Value.Bytes.Length); Assert.True(node.IsFloat()); Assert.AreEqual(3, (int)node.GetDouble()); Assert.AreEqual(3.3f, (float)node.GetDouble()); @@ -115,8 +109,8 @@ namespace UniJSON var quoted = "\"hoge\""; Assert.AreEqual(quoted, JsonString.Quote(value)); var node = JsonParser.Parse(quoted); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(quoted.Length, node.Value.Bytes.Count); + + Assert.AreEqual(quoted.Length, node.Value.Bytes.Length); Assert.True(node.IsString()); Assert.AreEqual("hoge", node.GetString()); } @@ -126,8 +120,8 @@ namespace UniJSON var quoted = "\"fuga\\n hoge\""; Assert.AreEqual(quoted, JsonString.Quote(value)); var node = JsonParser.Parse(quoted); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(quoted.Length, node.Value.Bytes.Count); + + Assert.AreEqual(quoted.Length, node.Value.Bytes.Length); Assert.True(node.IsString()); Assert.AreEqual(value, node.GetString()); } @@ -192,9 +186,9 @@ namespace UniJSON { var json = "{}"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(2, node.Value.Bytes.Count); + + Assert.AreEqual(2, node.Value.Bytes.Length); Assert.True(node.IsMap()); Assert.AreEqual(0, node.ObjectItems().Count()); @@ -203,8 +197,8 @@ namespace UniJSON { var json = "{\"key\":\"value\"}"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(json.Length, node.Value.Bytes.Count); + + Assert.AreEqual(json.Length, node.Value.Bytes.Length); Assert.True(node.IsMap()); var it = node.ObjectItems().GetEnumerator(); @@ -219,8 +213,8 @@ namespace UniJSON { var json = "{\"key\":\"value\"}"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - Assert.AreEqual(json.Length, node.Value.Bytes.Count); + + Assert.AreEqual(json.Length, node.Value.Bytes.Length); Assert.True(node.IsMap()); var it = node.ObjectItems().GetEnumerator(); @@ -277,10 +271,10 @@ namespace UniJSON { var json = "[]"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - //Assert.Catch(() => { var result = node.Value.Bytes.Count; }, "raise exception"); - Assert.AreEqual(2, node.Value.Bytes.Count); + + //Assert.Catch(() => { var result = node.Value.Bytes.Length; }, "raise exception"); + Assert.AreEqual(2, node.Value.Bytes.Length); Assert.True(node.IsArray()); @@ -290,9 +284,9 @@ namespace UniJSON { var json = "[1,2,3]"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - //Assert.Catch(() => { var result = node.Value.Bytes.Count; }, "raise exception"); + + //Assert.Catch(() => { var result = node.Value.Bytes.Length; }, "raise exception"); Assert.True(node.IsArray()); Assert.AreEqual(1, node[0].GetDouble()); @@ -305,10 +299,10 @@ namespace UniJSON { var json = "[\"key\",1]"; var node = JsonParser.Parse(json); - Assert.AreEqual(0, node.Value.Bytes.Offset); - //Assert.Catch(() => { var result = node.Value.Bytes.Count; }, "raise exception"); - Assert.AreEqual(json.Length, node.Value.Bytes.Count); + + //Assert.Catch(() => { var result = node.Value.Bytes.Length; }, "raise exception"); + Assert.AreEqual(json.Length, node.Value.Bytes.Length); Assert.True(node.IsArray());