1+ using System . Buffers ;
12using System . Text ;
23using ValveKeyValue . Abstraction ;
34using ValveKeyValue . KeyValues1 ;
@@ -84,7 +85,7 @@ string ReadKeyForNextValue()
8485 return stringTable [ index ] ;
8586 }
8687
87- return Encoding . UTF8 . GetString ( ReadNullTerminatedBytes ( ) ) ;
88+ return ReadNullTerminatedUtf8String ( ) ;
8889 }
8990
9091 void ReadValue ( KV1BinaryNodeType type )
@@ -102,7 +103,7 @@ void ReadValue(KV1BinaryNodeType type)
102103
103104 case KV1BinaryNodeType . String :
104105 // UTF8 encoding is used for string values
105- value = new KVObjectValue < string > ( Encoding . UTF8 . GetString ( ReadNullTerminatedBytes ( ) ) , KVValueType . String ) ;
106+ value = new KVObjectValue < string > ( ReadNullTerminatedUtf8String ( ) , KVValueType . String ) ;
106107 break ;
107108
108109 case KV1BinaryNodeType . WideString :
@@ -137,16 +138,41 @@ void ReadValue(KV1BinaryNodeType type)
137138 listener . OnKeyValuePair ( name , value ) ;
138139 }
139140
140- byte [ ] ReadNullTerminatedBytes ( )
141+ string ReadNullTerminatedUtf8String ( )
141142 {
142- using var mem = new MemoryStream ( ) ;
143- byte nextByte ;
144- while ( ( nextByte = reader . ReadByte ( ) ) != 0 )
143+ var buffer = ArrayPool < byte > . Shared . Rent ( 32 ) ;
144+
145+ try
145146 {
146- mem . WriteByte ( nextByte ) ;
147+ var position = 0 ;
148+
149+ do
150+ {
151+ var b = reader . ReadByte ( ) ;
152+
153+ if ( b <= 0 ) // null byte or stream ended
154+ {
155+ break ;
156+ }
157+
158+ if ( position >= buffer . Length )
159+ {
160+ var newBuffer = ArrayPool < byte > . Shared . Rent ( buffer . Length * 2 ) ;
161+ Buffer . BlockCopy ( buffer , 0 , newBuffer , 0 , buffer . Length ) ;
162+ ArrayPool < byte > . Shared . Return ( buffer ) ;
163+ buffer = newBuffer ;
164+ }
165+
166+ buffer [ position ++ ] = b ;
167+ }
168+ while ( true ) ;
169+
170+ return Encoding . UTF8 . GetString ( buffer [ ..position ] ) ;
171+ }
172+ finally
173+ {
174+ ArrayPool < byte > . Shared . Return ( buffer ) ;
147175 }
148-
149- return mem . ToArray ( ) ;
150176 }
151177
152178 void DetectMagicHeader ( )
0 commit comments