Line data Source code
1 : #include "fd_pb_tokenize.h" 2 : #include "fd_pb_wire.h" 3 : 4 : static fd_pb_inbuf_t * 5 : read_varint( fd_pb_inbuf_t * buf, 6 2788 : ulong * out ) { 7 2788 : ulong sz = (ulong)( buf->end - buf->cur ); 8 2788 : ulong var = 0UL; 9 2788 : int shift = 0; 10 4504 : for( ulong i=0UL;; i++ ) { 11 4504 : if( FD_UNLIKELY( i>=10 || i>=sz ) ) return NULL; 12 : /* FIXME check if one bits are shifted out of bounds */ 13 4504 : var |= (ulong)( buf->cur[i] & 0x7f ) << shift; 14 4504 : shift += 7; 15 4504 : if( !( buf->cur[i] & 0x80 ) ) { 16 2788 : buf->cur += i+1; 17 2788 : *out = var; 18 2788 : return buf; 19 2788 : } 20 4504 : } 21 2788 : } 22 : 23 : static fd_pb_tlv_t * 24 : fd_pb_read_tlv_slow( fd_pb_inbuf_t * buf, 25 1394 : fd_pb_tlv_t * tlv ) { 26 1394 : fd_pb_inbuf_t buf2 = *buf; 27 1394 : ulong tag; 28 1394 : if( FD_UNLIKELY( !read_varint( &buf2, &tag ) ) ) return NULL; 29 1394 : if( FD_UNLIKELY( tag>UINT_MAX ) ) return NULL; 30 1394 : uint wire_type = fd_pb_tag_wire_type( (uint)tag ); 31 1394 : uint field_id = fd_pb_tag_field_id ( (uint)tag ); 32 1394 : ulong val; 33 1394 : switch( wire_type ) { 34 711 : case FD_PB_WIRE_TYPE_VARINT: 35 1394 : case FD_PB_WIRE_TYPE_LEN: 36 1394 : if( FD_UNLIKELY( !read_varint( &buf2, &val ) ) ) return NULL; 37 1394 : break; 38 1394 : case FD_PB_WIRE_TYPE_I64: 39 0 : if( FD_UNLIKELY( (ulong)( buf2.end - buf2.cur )<8UL ) ) return NULL; 40 0 : val = FD_LOAD( ulong, buf2.cur ); 41 0 : buf2.cur += 8UL; 42 0 : break; 43 0 : case FD_PB_WIRE_TYPE_I32: 44 0 : if( FD_UNLIKELY( (ulong)( buf2.end - buf2.cur )<4UL ) ) return NULL; 45 0 : val = (ulong)FD_LOAD( uint, buf2.cur ); 46 0 : buf2.cur += 4UL; 47 0 : break; 48 0 : default: 49 0 : return NULL; 50 1394 : } 51 1394 : *tlv = (fd_pb_tlv_t) { 52 1394 : .wire_type = wire_type, 53 1394 : .field_id = field_id, 54 1394 : .varint = val 55 1394 : }; 56 1394 : *buf = buf2; 57 1394 : return tlv; 58 1394 : } 59 : 60 : fd_pb_tlv_t * 61 : fd_pb_read_tlv( fd_pb_inbuf_t * buf, 62 1394 : fd_pb_tlv_t * tlv ) { 63 : /* FIXME plenty of optimization opportunities here */ 64 1394 : return fd_pb_read_tlv_slow( buf, tlv ); 65 1394 : }