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