Line data Source code
1 : #ifndef HEADER_fd_src_waltz_h2_fd_hpack_private_h 2 : #define HEADER_fd_src_waltz_h2_fd_hpack_private_h 3 : 4 : #include "fd_hpack.h" 5 : 6 : #if FD_HAS_X86 7 : #if defined(__GNUC__) && !defined(__clang__) 8 : #include <x86gprintrin.h> 9 : #else 10 : #include <immintrin.h> 11 : #endif 12 : #endif 13 : 14 : /* Simple HPACK static table. 15 : FIXME could be made faster/smaller */ 16 : 17 : struct fd_hpack_static_entry { 18 : char const * entry; 19 : uchar name_len; 20 : uchar value_len; 21 : }; 22 : 23 : typedef struct fd_hpack_static_entry fd_hpack_static_entry_t; 24 : 25 : FD_PROTOTYPES_BEGIN 26 : 27 : extern fd_hpack_static_entry_t const 28 : fd_hpack_static_table[ 62 ]; 29 : 30 : /* fd_hpack_rd_varint reads a varint with up to 8 bytes encoded length 31 : (not including prefix). addend is (2^n)-1 where n is the varint 32 : prefix bit count. prefix is the actual value of the varint prefix. 33 : Returns a value in [0,2^56) on success. Returns ULONG_MAX on decode 34 : failure. */ 35 : 36 : static inline ulong 37 : fd_hpack_rd_varint( fd_hpack_rd_t * rd, 38 : uint prefix, 39 72 : uint addend ) { 40 72 : prefix &= addend; 41 : /* FIXME does not detect overflow */ 42 : 43 : /* Length is 0 */ 44 72 : if( prefix<addend ) return prefix; 45 : 46 : /* Read encoded word */ 47 0 : ulong enc = 0UL; 48 0 : if( FD_LIKELY( rd->src+8 <= rd->src_end ) ) { 49 : /* happy path: speculatively read oob */ 50 0 : enc = fd_ulong_load_8( rd->src ); 51 0 : } else { 52 : /* slow path: carefully memcpy, handle potentially corrupt src_end */ 53 0 : ulong sz = fd_ulong_min( (ulong)rd->src_end - (ulong)rd->src, 8UL ); 54 0 : if( FD_UNLIKELY( !sz ) ) return ULONG_MAX; /* eof */ 55 0 : fd_memcpy( &enc, rd->src, sz ); 56 0 : } 57 : 58 : /* sz_run is a bit pattern indicating: 59 : 60 : length 1 => least-significant one bit is at index 7 61 : length 2 => - " - 15 62 : ... 63 : length n => - " - (8*n)-1 */ 64 0 : ulong sz_run = ~( enc | 0x7f7f7f7f7f7f7f7fUL ); 65 0 : if( FD_UNLIKELY( sz_run==0 ) ) return ULONG_MAX; /* unterminated varint */ 66 0 : int sz_bits = fd_ulong_find_lsb( sz_run )+1; 67 0 : ulong sz = (ulong)sz_bits>>3; 68 : 69 : /* Mask off garbage bits */ 70 0 : enc &= fd_ulong_shift_left( 1UL, sz_bits )-1UL; 71 : 72 : /* Remove varint length bits */ 73 0 : #if FD_HAS_X86 && defined(__BMI2__) 74 0 : ulong result = _pext_u64( enc, 0x7f7f7f7f7f7f7f7fUL ); 75 : #else 76 : ulong result = 77 : ( ( enc&0x000000000000007fUL )>>0 ) | 78 : ( ( enc&0x0000000000007f00UL )>>1 ) | 79 : ( ( enc&0x00000000007f0000UL )>>2 ) | 80 : ( ( enc&0x000000007f000000UL )>>3 ) | 81 : ( ( enc&0x0000007f00000000UL )>>4 ) | 82 : ( ( enc&0x00007f0000000000UL )>>5 ) | 83 : ( ( enc&0x007f000000000000UL )>>6 ) | 84 : ( ( enc&0x7f00000000000000UL )>>7 ); 85 : #endif 86 : 87 0 : uchar const * src_end = rd->src+sz; 88 0 : if( FD_UNLIKELY( src_end>rd->src_end ) ) return ULONG_MAX; /* eof */ 89 0 : rd->src = src_end; 90 0 : return result+addend; 91 0 : } 92 : 93 : FD_PROTOTYPES_END 94 : 95 : #endif /* HEADER_fd_src_waltz_h2_fd_hpack_private_h */