JsonValueおよびUtf8Stringが保持する配列をArraySegmentからReadOnlyMemoryに変更

This commit is contained in:
momoma-null
2026-06-10 15:54:38 +09:00
committed by hadashiA
parent 39531b1ce6
commit 5860a7940e
15 changed files with 108 additions and 71 deletions

View File

@@ -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<KeyValuePair<JsonNode, JsonNode>> 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);
}
}

View File

@@ -67,6 +67,13 @@ namespace UniJSON
m_used += buffer.Count;
}
public void Push(ReadOnlyMemory<Byte> buffer)
{
Ensure(buffer.Length);
buffer.Span.CopyTo(new Span<Byte>(m_buffer, m_used, buffer.Length));
m_used += buffer.Length;
}
public void Unshift(int size)
{
if (size > m_used)

View File

@@ -93,6 +93,13 @@ namespace UniJSON
m_pos += bytes.Count;
}
public void Write(ReadOnlySpan<byte> bytes)
{
Require(bytes.Length);
bytes.CopyTo(new Span<byte>(m_buffer, m_pos, bytes.Length));
m_pos += bytes.Length;
}
public void Write(sbyte value)
{
Require(Marshal.SizeOf(value));

View File

@@ -33,6 +33,7 @@ namespace UniJSON
void WriteLittleEndian(Double value);
void Write(ArraySegment<Byte> bytes);
void Write(ReadOnlySpan<Byte> bytes) => Write(new ArraySegment<Byte>(bytes.ToArray()));
void Write(string src);
void Write(char c);
@@ -55,6 +56,11 @@ namespace UniJSON
s.Write(new ArraySegment<Byte>(bytes.ToArray()));
}
public static void Write(this IStore s, ReadOnlyMemory<Byte> bytes)
{
s.Write(bytes.Span);
}
public static Utf8String ToUtf8String(this IStore s)
{
return new Utf8String(s.Bytes);

View File

@@ -62,6 +62,11 @@ namespace UniJSON
m_w.Write(bytes.Array, bytes.Offset, bytes.Count);
}
public void Write(ReadOnlySpan<byte> bytes)
{
m_s.Write(bytes);
}
#region BigEndian
public void WriteBigEndian(int value)
{

View File

@@ -40,6 +40,11 @@ namespace UniJSON
Write(text);
}
public void Write(ReadOnlySpan<byte> bytes)
{
Write(Encoding.UTF8.GetString(bytes));
}
public void Write(byte value)
{
throw new NotImplementedException();

View File

@@ -266,6 +266,12 @@ namespace UniJSON
m_w.Write(x);
}
public void Raw(ReadOnlySpan<Byte> x)
{
CommaCheck();
m_w.Write(x);
}
// ISO-8601: YYYY-MM-DD“T”hh:mm:ss“Z”
public void Value(DateTimeOffset x)
{

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -6,10 +6,10 @@ namespace UniJSON
public struct JsonValue
{
public Utf8String Segment;
public ArraySegment<Byte> Bytes { get { return Segment.Bytes; } }
public ReadOnlyMemory<Byte> Bytes { get { return Segment.Bytes; } }
public void SetBytesCount(int count)
{
Segment = new Utf8String(new ArraySegment<byte>(Bytes.Array, Bytes.Offset, count));
Segment = new Utf8String(Segment.Bytes.Slice(0, count));
}
public ValueNodeType ValueType

View File

@@ -332,6 +332,11 @@ namespace UniJSON
return AddValue(default(JsonValue).New(bytes, valueType, ValueIndex));
}
public JsonNode AddValue(ReadOnlyMemory<byte> bytes, ValueNodeType valueType)
{
return AddValue(new JsonValue(new Utf8String(bytes), valueType, ValueIndex));
}
public JsonNode AddValue(JsonValue value)
{
if (m_Values == null)

View File

@@ -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>
{
Byte[] m_bytes;
int m_offset;
ReadOnlyMemory<byte> m_memory;
int m_start;
int m_position;
int m_end;
public Utf8Iterator(ArraySegment<Byte> range, int start = 0)
public Utf8Iterator(ReadOnlyMemory<Byte> 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()

View File

@@ -8,10 +8,10 @@ namespace UniJSON
{
public static readonly System.Text.Encoding Encoding = new System.Text.UTF8Encoding(false);
public readonly ArraySegment<Byte> Bytes;
public readonly ReadOnlyMemory<Byte> 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<Byte> bytes)
public Utf8String(ReadOnlyMemory<Byte> bytes)
{
Bytes = bytes;
}
public Utf8String(Byte[] bytes, int offset, int count) : this(new ArraySegment<Byte>(bytes, offset, count))
public Utf8String(ArraySegment<Byte> bytes)
{
Bytes = new ReadOnlyMemory<Byte>(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<Byte>(bytes, offset, count);
}
public Utf8String(Byte[] bytes)
{
Bytes = new ReadOnlyMemory<Byte>(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<byte>(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

View File

@@ -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)

View File

@@ -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());