@@ -292,33 +292,34 @@ private static ushort[] GenerateDecodingLookupTree()
292
292
// -----------------------------------------------------------------
293
293
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
294
294
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
295
- // | 0 | next_lookup_table_index | not_used |
295
+ // | 1 | next_lookup_table_index | not_used |
296
296
// +---+---------------------------+-------------------------------+
297
297
// or
298
298
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
299
- // | 1 | number_of_used_bits | octet |
299
+ // | 0 | number_of_used_bits | octet |
300
300
// +---+---------------------------+-------------------------------+
301
301
302
- // Bit 15 set indicates a leaf value of decoding tree.
303
- // For example value 0x8241 means that we have reached end of huffman code
304
- // with result byte 0x41 'A' and from lookup bits count only rightmost 2 bites was used
302
+ // Bit 15 unset indicates a leaf value of decoding tree.
303
+ // For example value 0x0241 means that we have reached end of huffman code
304
+ // with result byte 0x41 'A' and from lookup bits only rightmost 2 bits were used
305
305
// and rest of bits are part of next huffman code.
306
306
307
- // Bit 15 unset indicates that code is not yet decoded and next lookup table index shall be used
307
+ // Bit 15 set indicates that code is not yet decoded and next lookup table index shall be used
308
308
// for next n bits of huffman code.
309
309
// 0 in 'next lookup table index' is considered as decoding error - invalid huffman code
310
310
311
311
// Because HPack uses static huffman code defined in RFC https://httpwg.org/specs/rfc7541.html#huffman.code
312
- // it is guaranteed that for this huffman code generated decoding lookup tree MUST consist of 15 lookup tables
313
- var lut = new ushort [ 15 * 256 ] ;
312
+ // it is guaranteed that for this huffman code generated decoding lookup tree MUST consist of exactly 15 lookup tables
313
+ var decodingTree = new ushort [ 15 * 256 ] ;
314
314
315
315
int allocatedLookupTableIndex = 0 ;
316
316
// Create traverse path for all 0..256 octets, 256 is EOS, see: http://httpwg.org/specs/rfc7541.html#rfc.section.5.2
317
317
for ( int octet = 0 ; octet <= 256 ; octet ++ )
318
318
{
319
- ( uint code , int bitsLeft ) = Encode ( octet ) ;
319
+ ( uint code , int bitLength ) = Encode ( octet ) ;
320
320
321
321
int lookupTableIndex = 0 ;
322
+ int bitsLeft = bitLength ;
322
323
while ( bitsLeft > 0 )
323
324
{
324
325
// read next 8 bits from huffman code
@@ -349,39 +350,39 @@ private static ushort[] GenerateDecodingLookupTree()
349
350
350
351
// Invalid huffman code - EOS
351
352
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
352
- // | 0 | 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 |
353
+ // | 1 | 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 |
353
354
// +---+---------------------------+-------------------------------+
354
- lut [ ( lookupTableIndex << 8 ) + ( indexInLookupTable | suffix ) ] = 0x00ff ;
355
+ decodingTree [ ( lookupTableIndex << 8 ) + ( indexInLookupTable | suffix ) ] = 0x80ff ;
355
356
}
356
357
else
357
358
{
358
359
// Leaf lookup value
359
360
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
360
- // | 1 | number_of_used_bits | code |
361
+ // | 0 | number_of_used_bits | code |
361
362
// +---+---------------------------+-------------------------------+
362
- lut [ ( lookupTableIndex << 8 ) + ( indexInLookupTable | suffix ) ] = ( ushort ) ( ( ( 0x80 | bitsLeft ) << 8 ) | octet ) ;
363
+ decodingTree [ ( lookupTableIndex << 8 ) + ( indexInLookupTable | suffix ) ] = ( ushort ) ( ( bitsLeft << 8 ) | octet ) ;
363
364
}
364
365
}
365
366
}
366
367
else
367
368
{
368
369
// More than 8 bits left in huffman code means that we need to traverse to another lookup table for next 8 bits
369
- ushort lookupValue = lut [ ( lookupTableIndex << 8 ) + indexInLookupTable ] ;
370
+ ushort lookupValue = decodingTree [ ( lookupTableIndex << 8 ) + indexInLookupTable ] ;
370
371
371
372
// Because next_lookup_table_index can not be 0, as 0 is index of root table, default value of array element
372
373
// means that we have not initialized it yet => lookup table MUST be allocated and its index assigned to that lookup value
373
374
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
374
- // | 0 | next_lookup_table_index | not_used |
375
+ // | 1 | next_lookup_table_index | not_used |
375
376
// +---+---------------------------+-------------------------------+
376
377
if ( lookupValue == default ( ushort ) )
377
378
{
378
379
++ allocatedLookupTableIndex ;
379
- lut [ ( lookupTableIndex << 8 ) + indexInLookupTable ] = ( ushort ) ( allocatedLookupTableIndex << 8 ) ;
380
+ decodingTree [ ( lookupTableIndex << 8 ) + indexInLookupTable ] = ( ushort ) ( ( 0x80 | allocatedLookupTableIndex ) << 8 ) ;
380
381
lookupTableIndex = allocatedLookupTableIndex ;
381
382
}
382
383
else
383
384
{
384
- lookupTableIndex = lookupValue >> 8 ;
385
+ lookupTableIndex = ( lookupValue & 0x7f00 ) >> 8 ;
385
386
}
386
387
}
387
388
@@ -390,7 +391,7 @@ private static ushort[] GenerateDecodingLookupTree()
390
391
}
391
392
}
392
393
393
- return lut ;
394
+ return decodingTree ;
394
395
}
395
396
396
397
/// <summary>
@@ -444,11 +445,11 @@ public static int Decode(ReadOnlySpan<byte> src, ref byte[] dstArray)
444
445
445
446
ushort lookupValue = decodingTree [ ( lookupTableIndex << 8 ) + lookupIndex ] ;
446
447
447
- if ( lookupValue >= 0x80_00 )
448
+ if ( lookupValue < 0x80_00 )
448
449
{
449
450
// Octet found.
450
451
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
451
- // | 1 | number_of_used_bits | octet |
452
+ // | 0 | number_of_used_bits | octet |
452
453
// +---+---------------------------+-------------------------------+
453
454
if ( j >= dst . Length )
454
455
{
@@ -459,15 +460,15 @@ public static int Decode(ReadOnlySpan<byte> src, ref byte[] dstArray)
459
460
460
461
// Start lookup of next symbol
461
462
lookupTableIndex = 0 ;
462
- bitsInAcc -= ( lookupValue & 0x7f00 ) >> 8 ;
463
+ bitsInAcc -= lookupValue >> 8 ;
463
464
}
464
465
else
465
466
{
466
467
// Traverse to next lookup table.
467
468
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
468
- // | 0 | next_lookup_table_index | not_used |
469
+ // | 1 | next_lookup_table_index | not_used |
469
470
// +---+---------------------------+-------------------------------+
470
- lookupTableIndex = lookupValue >> 8 ;
471
+ lookupTableIndex = ( lookupValue & 0x7f00 ) >> 8 ;
471
472
if ( lookupTableIndex == 0 )
472
473
{
473
474
// No valid symbol could be decoded or EOS was decoded
@@ -504,13 +505,13 @@ public static int Decode(ReadOnlySpan<byte> src, ref byte[] dstArray)
504
505
505
506
ushort lookupValue = decodingTree [ ( lookupTableIndex << 8 ) + lookupIndex ] ;
506
507
507
- if ( lookupValue >= 0x80_00 )
508
+ if ( lookupValue < 0x80_00 )
508
509
{
509
510
// Octet found.
510
511
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
511
- // | 1 | number_of_used_bits | octet |
512
+ // | 0 | number_of_used_bits | octet |
512
513
// +---+---------------------------+-------------------------------+
513
- bitsInAcc -= ( lookupValue & 0x7f00 ) >> 8 ;
514
+ bitsInAcc -= lookupValue >> 8 ;
514
515
515
516
if ( bitsInAcc < 0 )
516
517
{
0 commit comments