1515//
1616
1717using System ;
18+ using System . Buffers ;
1819using System . IO ;
1920using System . Text ;
2021
2122namespace bhl . MsgPack
2223{
2324 public class MsgPackReader
2425 {
25- Stream _strm ;
26+ readonly Stream _strm ;
2627 byte [ ] _tmp0 = new byte [ 8 ] ;
2728 byte [ ] _tmp1 = new byte [ 8 ] ;
29+ readonly byte [ ] _singleByte = new byte [ 1 ] ;
2830
2931 Encoding _encoding = Encoding . UTF8 ;
3032 //Decoder _decoder = Encoding.UTF8.GetDecoder ();
@@ -83,7 +85,9 @@ public bool IsUnsigned64 ()
8385
8486 public bool IsRaw ( )
8587 {
86- return this . Type == TypePrefixes . FixRaw || this . Type == TypePrefixes . Raw16 || this . Type == TypePrefixes . Raw32 ;
88+ return this . Type == TypePrefixes . FixRaw || this . Type == TypePrefixes . Raw8 || this . Type == TypePrefixes . Raw16 || this . Type == TypePrefixes . Raw32 ||
89+ this . Type == TypePrefixes . Bin8 || this . Type == TypePrefixes . Bin16 || this . Type == TypePrefixes . Bin32
90+ ;
8791 }
8892
8993 public bool IsArray ( )
@@ -99,7 +103,7 @@ public bool IsMap ()
99103 public bool Read ( )
100104 {
101105 byte [ ] tmp0 = _tmp0 , tmp1 = _tmp1 ;
102- int x = _strm . ReadByte ( ) ;
106+ int x = ReadStreamByteNoAlloc ( ) ;
103107 if ( x < 0 )
104108 return false ; // EOS
105109
@@ -162,7 +166,7 @@ public bool Read ()
162166 ValueUnsigned = ( uint ) ValueSigned ;
163167 break ;
164168 case TypePrefixes . UInt8 :
165- x = _strm . ReadByte ( ) ;
169+ x = ReadStreamByteNoAlloc ( ) ;
166170 if ( x < 0 )
167171 throw new FormatException ( ) ;
168172 ValueUnsigned = ( uint ) x ;
@@ -183,7 +187,7 @@ public bool Read ()
183187 ValueUnsigned64 = ( ( ulong ) tmp0 [ 0 ] << 56 ) | ( ( ulong ) tmp0 [ 1 ] << 48 ) | ( ( ulong ) tmp0 [ 2 ] << 40 ) | ( ( ulong ) tmp0 [ 3 ] << 32 ) | ( ( ulong ) tmp0 [ 4 ] << 24 ) | ( ( ulong ) tmp0 [ 5 ] << 16 ) | ( ( ulong ) tmp0 [ 6 ] << 8 ) | ( ulong ) tmp0 [ 7 ] ;
184188 break ;
185189 case TypePrefixes . Int8 :
186- x = _strm . ReadByte ( ) ;
190+ x = ReadStreamByteNoAlloc ( ) ;
187191 if ( x < 0 )
188192 throw new FormatException ( ) ;
189193 ValueSigned = ( sbyte ) x ;
@@ -210,14 +214,22 @@ public bool Read ()
210214 case TypePrefixes . FixMap :
211215 Length = ( uint ) ( x & 0xf ) ;
212216 break ;
217+ case TypePrefixes . Raw8 :
218+ case TypePrefixes . Bin8 :
219+ if ( _strm . Read ( tmp0 , 0 , 1 ) != 1 )
220+ throw new FormatException ( ) ;
221+ Length = ( uint ) tmp0 [ 0 ] ;
222+ break ;
213223 case TypePrefixes . Raw16 :
224+ case TypePrefixes . Bin16 :
214225 case TypePrefixes . Array16 :
215226 case TypePrefixes . Map16 :
216227 if ( _strm . Read ( tmp0 , 0 , 2 ) != 2 )
217228 throw new FormatException ( ) ;
218229 Length = ( ( uint ) tmp0 [ 0 ] << 8 ) | ( uint ) tmp0 [ 1 ] ;
219230 break ;
220231 case TypePrefixes . Raw32 :
232+ case TypePrefixes . Bin32 :
221233 case TypePrefixes . Array32 :
222234 case TypePrefixes . Map32 :
223235 if ( _strm . Read ( tmp0 , 0 , 4 ) != 4 )
@@ -242,17 +254,33 @@ public string ReadRawString ()
242254
243255 public string ReadRawString ( byte [ ] buf )
244256 {
245- if ( this . Length < buf . Length ) {
246- if ( ReadValueRaw ( buf , 0 , ( int ) this . Length ) != this . Length )
257+ int length = ( int ) this . Length ;
258+ if ( length < buf . Length ) {
259+ if ( ReadValueRaw ( buf , 0 , length ) != length )
247260 throw new FormatException ( ) ;
248- return _encoding . GetString ( buf , 0 , ( int ) this . Length ) ;
261+ return _encoding . GetString ( buf , 0 , length ) ;
249262 }
250263
251264 // Poor implementation
252- byte [ ] tmp = new byte [ ( int ) this . Length ] ;
253- if ( ReadValueRaw ( tmp , 0 , tmp . Length ) != tmp . Length )
254- throw new FormatException ( ) ;
255- return _encoding . GetString ( tmp ) ;
265+ byte [ ] tmp = ArrayPool < byte > . Shared . Rent ( length ) ;
266+ try
267+ {
268+ if ( ReadValueRaw ( tmp , 0 , length ) != length )
269+ throw new FormatException ( ) ;
270+ return _encoding . GetString ( tmp , 0 , length ) ;
271+ }
272+ finally
273+ {
274+ ArrayPool < byte > . Shared . Return ( tmp ) ;
275+ }
276+ }
277+
278+ int ReadStreamByteNoAlloc ( )
279+ {
280+ int bytesRead = _strm . Read ( _singleByte , 0 , 1 ) ;
281+ if ( bytesRead < 1 )
282+ return - 1 ;
283+ return _singleByte [ 0 ] ;
256284 }
257285 }
258286}
0 commit comments