LCOV - code coverage report
Current view: top level - ballet/txn - fd_compact_u16.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 18 38 47.4 %
Date: 2026-03-19 18:19:27 Functions: 2 32 6.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_txn_fd_compact_u16_h
       2             : #define HEADER_fd_src_ballet_txn_fd_compact_u16_h
       3             : 
       4             : /* This file declares some utility methods for decoding compact-u16, a variable
       5             :    length encoding format for unsigned 16 bit numbers that Solana transactions
       6             :    use in the wireline format.
       7             :    The format is documented at
       8             :    https://docs.solana.com/developing/programming-model/transactions#compact-u16-format
       9             :    but briefly:
      10             :      If the 16 bit number has (big endian bits) ponmlkji hgfedcba
      11             :      [  0x00,    0x80)   (implies [h..p] = 0) ->  0gfedcba                      (1 byte )
      12             :      [  0x80,  0x4000)   (implies [o..p] = 0) ->  1gfedcba 0nmlkjih             (2 bytes)
      13             :      [0x4000, 0x10000)                        ->  1gfedcba 1nmlkjih 000000po    (3 bytes)
      14             :    Numbers must be encoded with the minimal number of bytes possible.
      15             : 
      16             :    This encoding format is filled with sadness, some of which this API
      17             :    reflects.  To limit the sadness, this header is for internal use in fd_txn
      18             :    and not exported more widely. */
      19             : 
      20             : #include "../fd_ballet_base.h"
      21             : 
      22             : 
      23             : FD_PROTOTYPES_BEGIN
      24             : /* fd_cu16_dec_fixed: Reads a compact-u16 whose width is known.  High
      25             :    performance API that does no error checking, and as such, it's designed to
      26             :    be used with fd_cu16_dec_sz, which performs all necessary validation to
      27             :    ensure this is safe.  buf points to the first byte of the encoded value.
      28             :    sz in {1, 2, 3}. Reads exactly sz bytes. */
      29             : static inline ushort
      30             : fd_cu16_dec_fixed( uchar const * buf,
      31       38421 :                    ulong         sz ) {
      32             :   /* Branch-free hardware friendly format that is slower on a CPU. If you
      33             :      switch to this version, be sure to update the documentation to note that
      34             :      it reads more than sz bytes. */
      35             :   /*
      36             :      ulong w   = (ulong)*(uint *)buf;
      37             :      ulong b0  = (w & 0x00007FUL);
      38             :      ulong b1  = (w & 0x007F00UL)>>1UL;
      39             :      ulong b2  = (w & 0xFF0000UL)>>2UL;
      40             :      ulong m0  = (ulong)(((long)(1UL-sz))>>63); *//* Maps [0,1] to 0; [2,3] to 0xFF..FF */
      41             :   /* ulong m01 = (ulong)(((long)(2UL-sz))>>63); *//* Maps [0,2] to 0; [3,3] to 0xFF..FF */
      42             :   /* return (ushort)((b0) | (b1 & m0) | (b2 & m01)); */
      43             : 
      44             :   /* This version is actually substantially faster */
      45             : #if FD_TXN_HANDHOLDING
      46             :   FD_TEST( (1<=sz) & (sz<=3) );
      47             : #endif
      48       38421 :   if( FD_LIKELY( sz==1 ) )
      49       36620 :       return (ushort)buf[0];
      50        1801 :   if( FD_LIKELY( sz==2 ) )
      51        1811 :       return (ushort)((ulong)(buf[0]&0x7F) + (((ulong)buf[1])<<7));
      52 >1844*10^16 :   return (ushort)((ulong)(buf[0]&0x7F) + (((ulong)buf[1]&0x7F)<<7) + (((ulong)buf[2])<<14));
      53        1801 : }
      54             : 
      55             : /*fd_cu16_dec_sz: Returns the number of bytes in the compact-u16.  Also
      56             :   validates that it is a legally-encoded compact-u16 and that it is stored in
      57             :   no more than bytes_avail bytes.  buf points to the first byte of the encoded
      58             :   value.  Result will be in {0, 1, 2, 3}, where 0 indicates validation failed
      59             :   (not enough bytes avail, illegal encoding, or number is larger than a u16).*/
      60             : static inline ulong
      61             : fd_cu16_dec_sz( uchar const * buf,
      62       38419 :                 ulong         bytes_avail ) {
      63       38419 :   if( FD_LIKELY( bytes_avail>=1 && !(0x80UL & buf[0]) ) ) {
      64       36625 :     return 1UL;
      65       36625 :   }
      66        1811 :   if( FD_LIKELY( bytes_avail>=2 && !(0x80UL & buf[1]) ) ) {
      67        1811 :     if( FD_UNLIKELY( !buf[1] ) ) return 0UL; /* Detect non-minimal encoding */
      68        1811 :     return 2UL;
      69        1811 :   }
      70 >1844*10^16 :   if( FD_LIKELY( bytes_avail>=3 && !(0xFCUL & buf[2]) ) ) {
      71           0 :     if( FD_UNLIKELY( !buf[2] ) ) return 0UL; /* Detect non-minimal encoding */
      72           0 :     return 3UL;
      73           0 :   }
      74 >1844*10^16 :   return 0UL;
      75 >1844*10^16 : }
      76             : 
      77             : /* fd_cu16_dec: Reads a compact-u16.  buf points to the first byte of the
      78             :    encoded value.  Validates that the compact-u16 is legally encoded, and
      79             :    returns 0 to indicate that validation failed.  If the compact-u16 is valid,
      80             :    the decoded value is stored in the location pointed to by result_out.  On
      81             :    success, returns the length of the encoded compact-u16. */
      82             : static inline ulong
      83             : fd_cu16_dec( uchar const * buf,
      84             :              ulong         bytes_avail,
      85           0 :              ushort *      result_out ) {
      86           0 :   ulong sz = fd_cu16_dec_sz( buf, bytes_avail );
      87           0 :   if( sz ) *result_out = fd_cu16_dec_fixed( buf, sz );
      88           0 :   return sz;
      89           0 : }
      90             : 
      91             : static inline uint
      92           0 : fd_cu16_enc( ushort val, uchar * out ) {
      93           0 :   ulong v = (ulong)val;
      94           0 :   ulong byte0 = (v    )&0x7FUL;
      95           0 :   ulong byte1 = (v>> 7)&0x7FUL;
      96           0 :   ulong byte2 = (v>>14);
      97           0 :   int needs_byte1 = (v>0x007FUL);
      98           0 :   int needs_byte2 = (v>0x3FFFUL);
      99           0 :   fd_uchar_store_if( 1,           out + 0, (uchar)(byte0 | ((ulong)needs_byte1<<7)) );
     100           0 :   fd_uchar_store_if( needs_byte1, out + 1, (uchar)(byte1 | ((ulong)needs_byte2<<7)) );
     101           0 :   fd_uchar_store_if( needs_byte2, out + 2, (uchar)(byte2                          ) );
     102           0 :   return (uint)(1+needs_byte1+needs_byte2);
     103           0 : }
     104             : 
     105             : FD_PROTOTYPES_END
     106             : #endif /* HEADER_fd_src_ballet_txn_fd_compact_u16_h */

Generated by: LCOV version 1.14