Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 8008cfb

Browse files
committed
reading toml tables
1 parent e9c4f8f commit 8008cfb

6 files changed

Lines changed: 422 additions & 78 deletions

File tree

source/TOML/TOMLKeyValue.cs

Lines changed: 96 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public readonly ReadOnlySpan<char> Key
1414
{
1515
MemoryAddress.ThrowIfDefault(keyValue);
1616

17-
return keyValue->key.GetSpan<char>(keyValue->keyLength);
17+
return keyValue->data.GetSpan<char>(keyValue->keyLength);
1818
}
1919
}
2020

@@ -28,6 +28,39 @@ public readonly ValueType ValueType
2828
}
2929
}
3030

31+
public readonly ReadOnlySpan<char> Text
32+
{
33+
get
34+
{
35+
MemoryAddress.ThrowIfDefault(keyValue);
36+
ThrowIfNotTypeOf(ValueType.Text);
37+
38+
return keyValue->data.AsSpan<char>(keyValue->keyLength, keyValue->valueLength);
39+
}
40+
}
41+
42+
public readonly ref double Number
43+
{
44+
get
45+
{
46+
MemoryAddress.ThrowIfDefault(keyValue);
47+
ThrowIfNotTypeOf(ValueType.Number);
48+
49+
return ref keyValue->data.Read<double>(keyValue->keyLength * sizeof(char));
50+
}
51+
}
52+
53+
public readonly ref bool Boolean
54+
{
55+
get
56+
{
57+
MemoryAddress.ThrowIfDefault(keyValue);
58+
ThrowIfNotTypeOf(ValueType.Boolean);
59+
60+
return ref keyValue->data.Read<bool>(keyValue->keyLength * sizeof(char));
61+
}
62+
}
63+
3164
public readonly bool IsDisposed => keyValue == default;
3265

3366
#if NET
@@ -42,34 +75,44 @@ public TOMLKeyValue(ReadOnlySpan<char> key, ReadOnlySpan<char> text)
4275
keyValue = MemoryAddress.AllocatePointer<Implementation>();
4376
keyValue->valueType = ValueType.Text;
4477
keyValue->keyLength = key.Length;
45-
keyValue->key = MemoryAddress.Allocate(key);
4678
keyValue->valueLength = text.Length;
47-
keyValue->value = MemoryAddress.Allocate(text);
79+
80+
int keyByteLength = sizeof(char) * key.Length;
81+
int textByteLength = sizeof(char) * text.Length;
82+
keyValue->data = MemoryAddress.Allocate(keyByteLength + textByteLength);
83+
keyValue->data.CopyFrom(key, 0);
84+
keyValue->data.CopyFrom(text, keyByteLength);
4885
}
4986

5087
public TOMLKeyValue(ReadOnlySpan<char> key, double number)
5188
{
5289
keyValue = MemoryAddress.AllocatePointer<Implementation>();
5390
keyValue->valueType = ValueType.Number;
5491
keyValue->keyLength = key.Length;
55-
keyValue->key = MemoryAddress.Allocate(key);
56-
keyValue->valueLength = sizeof(double);
57-
keyValue->value = MemoryAddress.AllocateValue(number);
92+
keyValue->valueLength = 1;
93+
94+
int keyByteLength = sizeof(char) * key.Length;
95+
keyValue->data = MemoryAddress.Allocate(keyByteLength + sizeof(double));
96+
keyValue->data.CopyFrom(key, 0);
97+
keyValue->data.Write(keyByteLength, number);
5898
}
5999

60100
public TOMLKeyValue(ReadOnlySpan<char> key, bool boolean)
61101
{
62102
keyValue = MemoryAddress.AllocatePointer<Implementation>();
63103
keyValue->valueType = ValueType.Boolean;
64104
keyValue->keyLength = key.Length;
65-
keyValue->key = MemoryAddress.Allocate(key);
66-
keyValue->valueLength = sizeof(bool);
67-
keyValue->value = MemoryAddress.AllocateValue(boolean);
105+
keyValue->valueLength = 1;
106+
107+
int keyByteLength = sizeof(char) * key.Length;
108+
keyValue->data = MemoryAddress.Allocate(keyByteLength + 1);
109+
keyValue->data.CopyFrom(key, 0);
110+
keyValue->data.Write(keyByteLength, boolean);
68111
}
69112

70113
public readonly override string ToString()
71114
{
72-
using Text destination = new(32);
115+
using Text destination = new(0);
73116
ToString(destination);
74117
return destination.ToString();
75118
}
@@ -82,8 +125,7 @@ public void Dispose()
82125
{
83126
MemoryAddress.ThrowIfDefault(keyValue);
84127

85-
keyValue->key.Dispose();
86-
keyValue->value.Dispose();
128+
keyValue->data.Dispose();
87129
MemoryAddress.Free(ref keyValue);
88130
}
89131

@@ -95,37 +137,62 @@ void ISerializable.Read(ByteReader byteReader)
95137
{
96138
keyValue = MemoryAddress.AllocatePointer<Implementation>();
97139
TOMLReader tomlReader = new(byteReader);
98-
Token token = tomlReader.ReadToken();
99-
Span<char> buffer = stackalloc char[token.length * 4];
100-
keyValue->keyLength = tomlReader.GetText(token, buffer);
101-
keyValue->key = MemoryAddress.Allocate(buffer.Slice(0, keyValue->keyLength));
102-
103-
token = tomlReader.ReadToken();
104-
ThrowIfNotEqualsAfterKey(token.type);
105-
106-
token = tomlReader.ReadToken();
107-
buffer = stackalloc char[token.length * 4];
108-
keyValue->valueLength = tomlReader.GetText(token, buffer);
109-
ReadOnlySpan<char> valueText = buffer.Slice(0, keyValue->valueLength);
140+
141+
//read text
142+
Token keyToken = tomlReader.ReadToken();
143+
Span<char> keyBuffer = stackalloc char[keyToken.length * 4];
144+
keyValue->keyLength = tomlReader.GetText(keyToken, keyBuffer);
145+
ReadOnlySpan<char> keyText = keyBuffer.Slice(0, keyValue->keyLength);
146+
147+
//read equals
148+
Token equalsToken = tomlReader.ReadToken();
149+
ThrowIfNotEqualsAfterKey(equalsToken.type);
150+
151+
//read text
152+
Token valueToken = tomlReader.ReadToken();
153+
Span<char> valueBuffer = stackalloc char[valueToken.length * 4];
154+
int valueLength = tomlReader.GetText(valueToken, valueBuffer);
155+
ReadOnlySpan<char> valueText = valueBuffer.Slice(0, valueLength);
156+
157+
//build data
158+
int keyByteLength = sizeof(char) * keyValue->keyLength;
110159
if (double.TryParse(valueText, out double number))
111160
{
112161
keyValue->valueType = ValueType.Number;
113-
keyValue->value = MemoryAddress.AllocateValue(number);
162+
keyValue->valueLength = 1;
163+
keyValue->data = MemoryAddress.Allocate(keyByteLength + sizeof(double));
164+
keyValue->data.CopyFrom(keyText, 0);
165+
keyValue->data.Write(keyByteLength, number);
114166
}
115167
else if (bool.TryParse(valueText, out bool boolean))
116168
{
117169
keyValue->valueType = ValueType.Boolean;
118-
keyValue->value = MemoryAddress.AllocateValue(boolean);
170+
keyValue->valueLength = 1;
171+
keyValue->data = MemoryAddress.Allocate(keyByteLength + 1);
172+
keyValue->data.CopyFrom(keyText, 0);
173+
keyValue->data.Write(keyByteLength, boolean);
119174
}
120175
else
121176
{
122177
keyValue->valueType = ValueType.Text;
123-
keyValue->value = MemoryAddress.Allocate(valueText);
178+
keyValue->valueLength = valueLength;
179+
keyValue->data = MemoryAddress.Allocate(keyByteLength + (sizeof(char) * valueLength));
180+
keyValue->data.CopyFrom(keyText, 0);
181+
keyValue->data.CopyFrom(valueText, keyByteLength);
182+
}
183+
}
184+
185+
[Conditional("DEBUG")]
186+
private readonly void ThrowIfNotTypeOf(ValueType type)
187+
{
188+
if (keyValue->valueType != type)
189+
{
190+
throw new InvalidOperationException($"Expected value type `{type}`, but got `{keyValue->valueType}`");
124191
}
125192
}
126193

127194
[Conditional("DEBUG")]
128-
private readonly void ThrowIfNotEqualsAfterKey(Token.Type type)
195+
private static void ThrowIfNotEqualsAfterKey(Token.Type type)
129196
{
130197
if (type != Token.Type.Equals)
131198
{
@@ -137,9 +204,8 @@ private struct Implementation
137204
{
138205
public ValueType valueType;
139206
public int keyLength;
140-
public MemoryAddress key;
141207
public int valueLength;
142-
public MemoryAddress value;
208+
public MemoryAddress data;
143209
}
144210
}
145211
}

0 commit comments

Comments
 (0)