LCOV - code coverage report
Current view: top level - flamenco/types - fd_bincode.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 167 285 58.6 %
Date: 2024-11-13 11:58:15 Functions: 35 10339 0.3 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_encoders_fd_bincode_h
       2             : #define HEADER_fd_src_util_encoders_fd_bincode_h
       3             : 
       4             : #include "../../util/fd_util.h"
       5             : #include "../../util/valloc/fd_valloc.h"
       6             : 
       7             : typedef void
       8             : (* fd_types_walk_fn_t)( void *       self,
       9             :                         void const * arg,
      10             :                         char const * name,
      11             :                         int          type,
      12             :                         char const * type_name,
      13             :                         uint         level );
      14             : 
      15             : typedef void
      16             : (* fd_types_walk_fn_t)( void *       self,
      17             :                         void const * arg,
      18             :                         char const * name,
      19             :                         int          type,
      20             :                         char const * type_name,
      21             :                         uint         level );
      22             : 
      23             : /* Context argument used for encoding */
      24             : struct fd_bincode_encode_ctx {
      25             :   /* Current position in data buffer */
      26             :   void * data;
      27             :   /* End of buffer */
      28             :   void * dataend;
      29             : };
      30             : typedef struct fd_bincode_encode_ctx fd_bincode_encode_ctx_t;
      31             : 
      32             : /* Context argument used for decoding */
      33             : struct fd_bincode_decode_ctx {
      34             :   /* Current position in data buffer */
      35             :   void const *   data;
      36             :   /* End of buffer */
      37             :   void const *   dataend;
      38             :   /* Allocator for dynamic memory */
      39             :   fd_valloc_t    valloc;
      40             : };
      41             : typedef struct fd_bincode_decode_ctx fd_bincode_decode_ctx_t;
      42             : 
      43             : /* Context argument used for calling "destroy" on a structure */
      44             : struct fd_bincode_destroy_ctx {
      45             :   /* Allocator for dynamic memory */
      46             :   fd_valloc_t valloc;
      47             : };
      48             : typedef struct fd_bincode_destroy_ctx fd_bincode_destroy_ctx_t;
      49             : 
      50   315037677 : #define FD_BINCODE_SUCCESS         (    0)
      51      112695 : #define FD_BINCODE_ERR_UNDERFLOW   (-1001) /* Attempted to read past end of buffer */
      52           3 : #define FD_BINCODE_ERR_OVERFLOW    (-1002) /* Attempted to write past end of buffer */
      53       50262 : #define FD_BINCODE_ERR_ENCODING    (-1003) /* Invalid encoding */
      54             : 
      55             : #define FD_BINCODE_PRIMITIVE_STUBS( name, type ) \
      56             :   static inline int \
      57             :   fd_bincode_##name##_decode( type *                    self, \
      58      416292 :                               fd_bincode_decode_ctx_t * ctx ) { \
      59      416292 :     uchar const * ptr = (uchar const *) ctx->data; \
      60      416292 :     if ( FD_UNLIKELY((void const *)(ptr + sizeof(type)) > ctx->dataend ) ) \
      61      416292 :       return FD_BINCODE_ERR_UNDERFLOW; \
      62      416292 :     memcpy( self, ptr, sizeof(type) );  /* unaligned */ \
      63      369732 :     ctx->data = ptr + sizeof(type); \
      64      369732 :     return FD_BINCODE_SUCCESS; \
      65      416292 :   } \
      66             :   static inline int \
      67    14098332 :   fd_bincode_##name##_decode_preflight( fd_bincode_decode_ctx_t * ctx ) { \
      68    14098332 :     uchar const * ptr = (uchar const *) ctx->data; \
      69    14098332 :     if ( FD_UNLIKELY((void const *)(ptr + sizeof(type)) > ctx->dataend ) ) \
      70    14098332 :       return FD_BINCODE_ERR_UNDERFLOW; \
      71    14098332 :     ctx->data = ptr + sizeof(type); \
      72    14082582 :     return FD_BINCODE_SUCCESS; \
      73    14098332 :   } \
      74             :   static inline void \
      75             :   fd_bincode_##name##_decode_unsafe( type *                    self, \
      76    15072714 :                                      fd_bincode_decode_ctx_t * ctx ) { \
      77    15072714 :     uchar const * ptr = (uchar const *) ctx->data; \
      78    15072714 :     memcpy( self, ptr, sizeof(type) );  /* unaligned */ \
      79    15072714 :     ctx->data = ptr + sizeof(type); \
      80    15072714 :   } \
      81             :   static inline int \
      82             :   fd_bincode_##name##_encode( type                      self, \
      83    72427050 :                               fd_bincode_encode_ctx_t * ctx ) { \
      84    72427050 :     uchar * ptr = (uchar *)ctx->data; \
      85    72427050 :     if ( FD_UNLIKELY((void *)(ptr + sizeof(type)) > ctx->dataend ) ) \
      86    72427050 :       return FD_BINCODE_ERR_OVERFLOW; \
      87    72427050 :     memcpy( ptr, &self, sizeof(type) );  /* unaligned */ \
      88    72427047 :     ctx->data = ptr + sizeof(type); \
      89    72427047 :     return FD_BINCODE_SUCCESS; \
      90    72427050 :   }
      91             : 
      92             : FD_BINCODE_PRIMITIVE_STUBS( uint8,   uchar   )
      93             : FD_BINCODE_PRIMITIVE_STUBS( uint16,  ushort  )
      94             : FD_BINCODE_PRIMITIVE_STUBS( uint32,  uint    )
      95             : FD_BINCODE_PRIMITIVE_STUBS( uint64,  ulong   )
      96             : FD_BINCODE_PRIMITIVE_STUBS( int64,   long   )
      97             : #if FD_HAS_INT128
      98             : FD_BINCODE_PRIMITIVE_STUBS( uint128, uint128 )
      99             : #endif
     100             : FD_BINCODE_PRIMITIVE_STUBS( double,  double  )
     101             : 
     102             : static inline int
     103             : fd_bincode_bool_decode( uchar *                   self,
     104       63714 :                         fd_bincode_decode_ctx_t * ctx ) {
     105             : 
     106       63714 :   uchar const * ptr = (uchar const *)ctx->data;
     107       63714 :   if( FD_UNLIKELY( ptr+1 > (uchar const *)ctx->dataend ) )
     108        3489 :     return FD_BINCODE_ERR_UNDERFLOW;
     109             : 
     110       60225 :   if( FD_UNLIKELY( *ptr & (~1U) ) )
     111        4224 :     return FD_BINCODE_ERR_ENCODING;
     112             : 
     113       56001 :   *self = *ptr;
     114       56001 :   ctx->data = ptr + 1;
     115             : 
     116       56001 :   return FD_BINCODE_SUCCESS;
     117       60225 : }
     118             : 
     119             : static inline int
     120      278469 : fd_bincode_bool_decode_preflight( fd_bincode_decode_ctx_t * ctx ) {
     121             : 
     122      278469 :   uchar const * ptr = (uchar const *)ctx->data;
     123      278469 :   if( FD_UNLIKELY( ptr+1 > (uchar const *)ctx->dataend ) )
     124         108 :     return FD_BINCODE_ERR_UNDERFLOW;
     125             : 
     126      278361 :   if( FD_UNLIKELY( *ptr & (~1U) ) )
     127        2274 :     return FD_BINCODE_ERR_ENCODING;
     128             : 
     129      276087 :   ctx->data = ptr + 1;
     130             : 
     131      276087 :   return FD_BINCODE_SUCCESS;
     132      278361 : }
     133             : 
     134             : static inline void
     135             : fd_bincode_bool_decode_unsafe( uchar *                   self,
     136      320115 :                                fd_bincode_decode_ctx_t * ctx ) {
     137      320115 :   fd_bincode_uint8_decode_unsafe( self, ctx );
     138      320115 : }
     139             : 
     140             : static inline int
     141             : fd_bincode_bool_encode( uchar                     self,
     142       15720 :                         fd_bincode_encode_ctx_t * ctx ) {
     143             : 
     144       15720 :   uchar * ptr = (uchar *)ctx->data;
     145       15720 :   if ( FD_UNLIKELY( (void *)(ptr + 1) > ctx->dataend ) )
     146           0 :     return FD_BINCODE_ERR_OVERFLOW;
     147             : 
     148       15720 :   *ptr = !!self;
     149       15720 :   ctx->data = ptr + 1;
     150             : 
     151       15720 :   return FD_BINCODE_SUCCESS;
     152       15720 : }
     153             : 
     154             : static inline int
     155             : fd_bincode_bytes_decode( uchar *                   self,
     156             :                          ulong                     len,
     157           0 :                          fd_bincode_decode_ctx_t * ctx ) {
     158           0 :   uchar * ptr = (uchar *) ctx->data;
     159           0 :   if ( FD_UNLIKELY((ulong)( (uchar *) ctx->dataend - ptr) < len ) ) // Get wrap-around case right
     160           0 :     return FD_BINCODE_ERR_UNDERFLOW;
     161           0 : 
     162           0 :   fd_memcpy(self, ptr, len);
     163           0 :   ctx->data = ptr + len;
     164           0 : 
     165           0 :   return FD_BINCODE_SUCCESS;
     166           0 : }
     167             : 
     168             : static inline int
     169             : fd_bincode_bytes_decode_preflight( ulong                     len,
     170     4267272 :                                    fd_bincode_decode_ctx_t * ctx ) {
     171     4267272 :   uchar * ptr = (uchar *) ctx->data;
     172     4267272 :   if ( FD_UNLIKELY((ulong)( (uchar *) ctx->dataend - ptr) < len ) ) // Get wrap-around case right
     173       45468 :     return FD_BINCODE_ERR_UNDERFLOW;
     174             : 
     175     4221804 :   ctx->data = ptr + len;
     176             : 
     177     4221804 :   return FD_BINCODE_SUCCESS;
     178     4267272 : }
     179             : 
     180             : static inline void
     181             : fd_bincode_bytes_decode_unsafe( uchar *                   self,
     182             :                                 ulong                     len,
     183     4114614 :                                 fd_bincode_decode_ctx_t * ctx ) {
     184     4114614 :   uchar * ptr = (uchar *) ctx->data;
     185     4114614 :   fd_memcpy(self, ptr, len);
     186     4114614 :   ctx->data = ptr + len;
     187     4114614 : }
     188             : 
     189             : static inline int
     190             : fd_bincode_bytes_encode( uchar const *             self,
     191             :                          ulong                     len,
     192    71231883 :                          fd_bincode_encode_ctx_t * ctx ) {
     193    71231883 :   uchar *ptr = (uchar *) ctx->data;
     194    71231883 :   if ( FD_UNLIKELY((void *) (ptr + len) > ctx->dataend ) )
     195           0 :     return FD_BINCODE_ERR_OVERFLOW;
     196             : 
     197    71231883 :   fd_memcpy(ptr, self, len);
     198    71231883 :   ctx->data = ptr + len;
     199             : 
     200    71231883 :   return FD_BINCODE_SUCCESS;
     201    71231883 : }
     202             : 
     203             : /* Alternate versions of fd_cu16_dec to make the function signature more consistent with the
     204             :    other fd_bincode_decode functions.  */
     205             : static inline int
     206             : fd_bincode_compact_u16_decode( ushort *                  self,
     207       16998 :                                fd_bincode_decode_ctx_t * ctx ) {
     208       16998 :   const uchar * ptr = (const uchar*) ctx->data;
     209       16998 :   if( FD_UNLIKELY( ptr==NULL ) ) {
     210           0 :     return FD_BINCODE_ERR_UNDERFLOW;
     211           0 :   }
     212             : 
     213       16998 :   if( FD_LIKELY( (void *) (ptr + 1) <= ctx->dataend && !(0x80U & ptr[0]) ) ) {
     214       14973 :     *self = (ushort)ptr[0];
     215       14973 :     ctx->data = ptr + 1;
     216       14973 :     return FD_BINCODE_SUCCESS;
     217       14973 :   }
     218             : 
     219        2025 :   if( FD_LIKELY( (void *) (ptr + 2) <= ctx->dataend && !(0x80U & ptr[1]) ) ) {
     220         867 :     if( FD_UNLIKELY( !ptr[1] ) ) /* Detect non-minimal encoding */
     221         129 :       return FD_BINCODE_ERR_ENCODING;
     222         738 :     *self = (ushort)((ulong)(ptr[0]&0x7FUL) + (((ulong)ptr[1])<<7));
     223         738 :     ctx->data = ptr + 2;
     224         738 :     return FD_BINCODE_SUCCESS;
     225         867 :   }
     226             : 
     227        1158 :   if( FD_LIKELY( (void *) (ptr + 3) <= ctx->dataend && !(0xFCU & ptr[2]) ) ) {
     228          96 :     if( FD_UNLIKELY( !ptr[2] ) ) /* Detect non-minimal encoding */
     229          30 :       return FD_BINCODE_ERR_ENCODING;
     230          66 :     *self = (ushort)((ulong)(ptr[0]&0x7FUL) + (((ulong)(ptr[1]&0x7FUL))<<7) + (((ulong)ptr[2])<<14));
     231          66 :     ctx->data = ptr + 3;
     232          66 :     return FD_BINCODE_SUCCESS;
     233          96 :   }
     234             : 
     235        1062 :   return FD_BINCODE_ERR_UNDERFLOW;
     236        1158 : }
     237             : 
     238             : static inline void
     239             : fd_bincode_compact_u16_decode_unsafe( ushort *                  self,
     240       11952 :                                       fd_bincode_decode_ctx_t * ctx ) {
     241       11952 :   const uchar * ptr = (const uchar*) ctx->data;
     242             : 
     243       11952 :   if( !(0x80U & ptr[0]) ) {
     244       11940 :     *self = (ushort)ptr[0];
     245       11940 :     ctx->data = ptr + 1;
     246       11940 :     return;
     247       11940 :   }
     248             : 
     249          12 :   if( !(0x80U & ptr[1]) ) {
     250          12 :     *self = (ushort)((ulong)(ptr[0]&0x7FUL) + (((ulong)ptr[1])<<7));
     251          12 :     ctx->data = ptr + 2;
     252          12 :     return;
     253          12 :   }
     254             : 
     255           0 :   *self = (ushort)((ulong)(ptr[0]&0x7FUL) + (((ulong)(ptr[1]&0x7FUL))<<7) + (((ulong)ptr[2])<<14));
     256           0 :   ctx->data = ptr + 3;
     257           0 : }
     258             : 
     259             : static inline int
     260             : fd_bincode_compact_u16_encode( ushort const *            self,
     261       82608 :                                fd_bincode_encode_ctx_t * ctx ) {
     262       82608 :   uchar * ptr = (uchar*) ctx->data;
     263       82608 :   ulong val = *self;
     264             : 
     265       82608 :   if ( val < 0x80UL ) {
     266       78456 :     if ( FD_UNLIKELY((void *) (ptr + 1) > ctx->dataend ) )
     267           0 :       return FD_BINCODE_ERR_OVERFLOW;
     268       78456 :     *ptr = (uchar)val;
     269       78456 :     ctx->data = ptr + 1;
     270       78456 :     return FD_BINCODE_SUCCESS;
     271       78456 :   }
     272             : 
     273        4152 :   else if ( val < 0x4000UL ) {
     274        4152 :     if ( FD_UNLIKELY((void *) (ptr + 2) > ctx->dataend ) )
     275           0 :       return FD_BINCODE_ERR_OVERFLOW;
     276        4152 :     ptr[0] = (uchar)((val&0x7FUL)|0x80UL);
     277        4152 :     ptr[1] = (uchar)(val>>7);
     278        4152 :     ctx->data = ptr + 2;
     279        4152 :     return FD_BINCODE_SUCCESS;
     280        4152 :   }
     281             : 
     282           0 :   else {
     283           0 :     if ( FD_UNLIKELY((void *) (ptr + 3) > ctx->dataend ) )
     284           0 :       return FD_BINCODE_ERR_OVERFLOW;
     285           0 :     ptr[0] = (uchar)((val&0x7FUL)|0x80UL);
     286           0 :     ptr[1] = (uchar)(((val>>7)&0x7FUL)|0x80UL);
     287           0 :     ptr[2] = (uchar)(val>>14);
     288           0 :     ctx->data = ptr + 3;
     289           0 :     return FD_BINCODE_SUCCESS;
     290           0 :   }
     291       82608 : }
     292             : 
     293             : static inline ulong
     294           0 : fd_bincode_compact_u16_size( ushort const * self ) {
     295           0 :   ulong val = *self;
     296             : 
     297           0 :   if ( val < 0x80UL ) {
     298           0 :     return 1;
     299           0 :   }
     300           0 :   else if ( val < 0x4000UL ) {
     301           0 :     return 2;
     302           0 :   }
     303           0 :   else {
     304           0 :     return 3;
     305           0 :   }
     306           0 : }
     307             : 
     308             : /* Decodes an integer encoded using the serde_varint algorithm:
     309             :    https://github.com/solana-labs/solana/blob/master/sdk/program/src/serde_varint.rs
     310             : 
     311             :    A variable number of bytes could have been used to encode the integer.
     312             :    The most significant bit of each byte indicates if more bytes have been used, so we keep consuming until
     313             :    we reach a byte where the most significant bit is 0.
     314             : */
     315             : static inline int
     316             : fd_bincode_varint_decode( ulong *                   self,
     317           0 :                           fd_bincode_decode_ctx_t * ctx ) {
     318           0 :   ulong out   = 0UL;
     319           0 :   uint  shift = 0U;
     320           0 : 
     321           0 :   while( FD_LIKELY( shift < 64U ) ) {
     322           0 : 
     323           0 :     if( FD_UNLIKELY( ctx->data >= ctx->dataend ) )
     324           0 :       return FD_BINCODE_ERR_UNDERFLOW;
     325           0 : 
     326           0 :     uint byte = *(uchar const *)ctx->data;
     327           0 :     ctx->data = (uchar const *)ctx->data + 1;
     328           0 :     out |= (byte & 0x7FUL) << shift;
     329           0 : 
     330           0 :     if( (byte & 0x80U) == 0U ) {
     331           0 :       if( (out>>shift) != byte )
     332           0 :         return FD_BINCODE_ERR_ENCODING;
     333           0 :       if( byte==0U && (shift!=0U || out!=0UL) )
     334           0 :         return FD_BINCODE_ERR_ENCODING;
     335           0 :       *self = out;
     336           0 :       return FD_BINCODE_SUCCESS;
     337           0 :     }
     338           0 : 
     339           0 :     shift += 7U;
     340           0 : 
     341           0 :   }
     342           0 : 
     343           0 :   return FD_BINCODE_ERR_ENCODING;
     344           0 : }
     345             : 
     346             : static inline int
     347       77856 : fd_bincode_varint_decode_preflight( fd_bincode_decode_ctx_t * ctx ) {
     348       77856 :   ulong out   = 0UL;
     349       77856 :   uint  shift = 0U;
     350             : 
     351      215550 :   while( FD_LIKELY( shift < 64U ) ) {
     352             : 
     353      215538 :     if( FD_UNLIKELY( ctx->data >= ctx->dataend ) )
     354         132 :       return FD_BINCODE_ERR_UNDERFLOW;
     355             : 
     356      215406 :     uint byte = *(uchar const *)ctx->data;
     357      215406 :     ctx->data = (uchar const *)ctx->data + 1;
     358      215406 :     out |= (byte & 0x7FUL) << shift;
     359             : 
     360      215406 :     if( (byte & 0x80U) == 0U ) {
     361       77712 :       if( (out>>shift) != byte )
     362          15 :         return FD_BINCODE_ERR_ENCODING;
     363       77697 :       if( byte==0U && (shift!=0U || out!=0UL) )
     364         117 :         return FD_BINCODE_ERR_ENCODING;
     365       77580 :       return FD_BINCODE_SUCCESS;
     366       77697 :     }
     367             : 
     368      137694 :     shift += 7U;
     369             : 
     370      137694 :   }
     371             : 
     372          12 :   return FD_BINCODE_ERR_ENCODING;
     373       77856 : }
     374             : 
     375             : static inline void
     376             : fd_bincode_varint_decode_unsafe( ulong *                   self,
     377       11703 :                                  fd_bincode_decode_ctx_t * ctx ) {
     378       11703 :   ulong out   = 0UL;
     379       11703 :   uint  shift = 0U;
     380             : 
     381       41541 :   for(;;) {
     382       41541 :     uint byte = *(uchar const *)ctx->data;
     383       41541 :     ctx->data = (uchar const *)ctx->data + 1;
     384       41541 :     out |= (byte & 0x7FUL) << shift;
     385             : 
     386       41541 :     if( (byte & 0x80U) == 0U ) {
     387       11703 :       *self = out;
     388       11703 :       return;
     389       11703 :     }
     390             : 
     391       29838 :     shift += 7U;
     392       29838 :   }
     393       11703 : }
     394             : 
     395             : static inline int
     396             : fd_bincode_varint_encode( ulong                     val,
     397           0 :                           fd_bincode_encode_ctx_t * ctx ) {
     398           0 :   uchar * ptr = (uchar *) ctx->data;
     399           0 :   while (1) {
     400           0 :     if ( FD_UNLIKELY((void *) (ptr + 1) > ctx->dataend ) )
     401           0 :       return FD_BINCODE_ERR_OVERFLOW;
     402           0 :     if ( val < 0x80UL ) {
     403           0 :       *(ptr++) = (uchar)val;
     404           0 :       ctx->data = ptr;
     405           0 :       return FD_BINCODE_SUCCESS;
     406           0 :     }
     407           0 :     *(ptr++) = (uchar)((val&0x7FUL)|0x80UL);
     408           0 :     val >>= 7;
     409           0 :   }
     410           0 : }
     411             : 
     412             : static inline ulong
     413           0 : fd_bincode_varint_size( ulong val ) {
     414           0 :   ulong sz = 0;
     415           0 :   while (1) {
     416           0 :     if ( val < 0x80UL ) {
     417           0 :       return sz+1;
     418           0 :     }
     419           0 :     sz++;
     420           0 :     val >>= 7;
     421           0 :   }
     422           0 : }
     423             : 
     424             : enum {
     425             :   /* All meta tags must fit in 6 bits */
     426             : 
     427             :   /* Primitive types with an implicit encoding length */
     428             :   FD_ARCHIVE_META_CHAR = 0x1,
     429             :   FD_ARCHIVE_META_STRING = 0x2,
     430             :   FD_ARCHIVE_META_CHAR32 = 0x3,
     431             :   FD_ARCHIVE_META_DOUBLE = 0x4,
     432             :   FD_ARCHIVE_META_LONG = 0x5,
     433             :   FD_ARCHIVE_META_UINT = 0x6,
     434             :   FD_ARCHIVE_META_UINT128 = 0x7,
     435             :   FD_ARCHIVE_META_BOOL = 0x8,
     436             :   FD_ARCHIVE_META_UCHAR = 0x9,
     437             :   FD_ARCHIVE_META_UCHAR32 = 0xa,
     438             :   FD_ARCHIVE_META_UCHAR128 = 0xb,
     439             :   FD_ARCHIVE_META_UCHAR2048 = 0xc,
     440             :   FD_ARCHIVE_META_ULONG = 0xd,
     441             :   FD_ARCHIVE_META_USHORT = 0xe,
     442             : 
     443             :   /* Meta types which have an encoding length after the short tag */
     444             :   FD_ARCHIVE_META_STRUCT = 0x21,
     445             :   FD_ARCHIVE_META_VECTOR = 0x22,
     446             :   FD_ARCHIVE_META_DEQUE = 0x23,
     447             :   FD_ARCHIVE_META_MAP = 0x24,
     448             :   FD_ARCHIVE_META_TREAP = 0x25,
     449             :   FD_ARCHIVE_META_OPTION = 0x26,
     450             :   FD_ARCHIVE_META_ARRAY = 0x27,
     451             : };
     452             : 
     453           0 : #define FD_ARCHIVE_META_SENTINAL (ushort)0 /* End of structure */
     454             : 
     455           0 : static inline int fd_archive_encode_setup_length( fd_bincode_encode_ctx_t * ctx, void ** offset_out ) {
     456           0 :   uchar * ptr = (uchar *)ctx->data;
     457           0 :   if ( FD_UNLIKELY((void *)(ptr + sizeof(uint)) > ctx->dataend ) )
     458           0 :     return FD_BINCODE_ERR_OVERFLOW;
     459             :   /* Skip over length for now but make space for it */
     460           0 :   *offset_out = ptr;
     461           0 :   ctx->data = ptr + sizeof(uint);
     462           0 :   return FD_BINCODE_SUCCESS;
     463           0 : }
     464             : 
     465           0 : static inline int fd_archive_encode_set_length( fd_bincode_encode_ctx_t * ctx, void * offset ) {
     466           0 :   *(uint *)offset = (uint)((uchar *)ctx->data - ((uchar *)offset + sizeof(uint)));
     467           0 :   return FD_BINCODE_SUCCESS;
     468           0 : }
     469             : 
     470           0 : static inline int fd_archive_decode_setup_length( fd_bincode_decode_ctx_t * ctx, void ** offset_out ) {
     471           0 :   uchar * ptr = (uchar *)ctx->data;
     472           0 :   if ( FD_UNLIKELY((void *)(ptr + sizeof(uint)) > ctx->dataend ) )
     473           0 :     return FD_BINCODE_ERR_UNDERFLOW;
     474             :   /* Skip over length for now and verify it later */
     475           0 :   *offset_out = ptr;
     476           0 :   ctx->data = ptr + sizeof(uint);
     477           0 :   return FD_BINCODE_SUCCESS;
     478           0 : }
     479             : 
     480           0 : static inline int fd_archive_decode_check_length( fd_bincode_decode_ctx_t * ctx, void * offset ) {
     481           0 :   if( *(uint *)offset != (uint)((uchar *)ctx->data - ((uchar *)offset + sizeof(uint))) )
     482           0 :     return FD_BINCODE_ERR_ENCODING;
     483           0 :   return FD_BINCODE_SUCCESS;
     484           0 : }
     485             : 
     486             : int fd_archive_decode_skip_field( fd_bincode_decode_ctx_t * ctx, ushort tag );
     487             : 
     488             : #endif /* HEADER_fd_src_util_encoders_fd_bincode_h */

Generated by: LCOV version 1.14