LCOV - code coverage report
Current view: top level - ballet/txn - fd_compact_u16.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 39 39 100.0 %
Date: 2026-06-29 05:51:35 Functions: 13 84 15.5 %

          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 10603653594 :                    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 10603653594 :   FD_DCHECK_CRIT( (1<=sz) & (sz<=3), "invalid compact-u16 size" );
      46 10603653594 :   if( FD_LIKELY( sz==1 ) )
      47  7357158123 :       return (ushort)buf[0];
      48  3246495471 :   if( FD_LIKELY( sz==2 ) )
      49  3208599267 :       return (ushort)((ulong)(buf[0]&0x7F) + (((ulong)buf[1])<<7));
      50    37896204 :   return (ushort)((ulong)(buf[0]&0x7F) + (((ulong)buf[1]&0x7F)<<7) + (((ulong)buf[2])<<14));
      51  3246495471 : }
      52             : 
      53             : /*fd_cu16_dec_sz: Returns the number of bytes in the compact-u16.  Also
      54             :   validates that it is a legally-encoded compact-u16 and that it is stored in
      55             :   no more than bytes_avail bytes.  buf points to the first byte of the encoded
      56             :   value.  Result will be in {0, 1, 2, 3}, where 0 indicates validation failed
      57             :   (not enough bytes avail, illegal encoding, or number is larger than a u16).*/
      58             : static inline ulong
      59             : fd_cu16_dec_sz( uchar const * buf,
      60 13824890238 :                 ulong         bytes_avail ) {
      61 13824890238 :   if( FD_LIKELY( bytes_avail>=1 && !(0x80UL & buf[0]) ) ) {
      62  7357158123 :     return 1UL;
      63  7357158123 :   }
      64  6467732115 :   if( FD_LIKELY( bytes_avail>=2 && !(0x80UL & buf[1]) ) ) {
      65  3233863788 :     if( FD_UNLIKELY( !buf[1] ) ) return 0UL; /* Detect non-minimal encoding */
      66  3208599267 :     return 2UL;
      67  3233863788 :   }
      68  3233868327 :   if( FD_LIKELY( bytes_avail>=3 && !(0xFCUL & buf[2]) ) ) {
      69    50528268 :     if( FD_UNLIKELY( !buf[2] ) ) return 0UL; /* Detect non-minimal encoding */
      70    37896204 :     return 3UL;
      71    50528268 :   }
      72  3183340059 :   return 0UL;
      73  3233868327 : }
      74             : 
      75             : /* fd_cu16_dec: Reads a compact-u16.  buf points to the first byte of the
      76             :    encoded value.  Validates that the compact-u16 is legally encoded, and
      77             :    returns 0 to indicate that validation failed.  If the compact-u16 is valid,
      78             :    the decoded value is stored in the location pointed to by result_out.  On
      79             :    success, returns the length of the encoded compact-u16. */
      80             : static inline ulong
      81             : fd_cu16_dec( uchar const * buf,
      82             :              ulong         bytes_avail,
      83 12935430915 :              ushort *      result_out ) {
      84 12935430915 :   ulong sz = fd_cu16_dec_sz( buf, bytes_avail );
      85 12935430915 :   if( sz ) *result_out = fd_cu16_dec_fixed( buf, sz );
      86 12935430915 :   return sz;
      87 12935430915 : }
      88             : 
      89             : static inline uint
      90      198843 : fd_cu16_enc( ushort val, uchar * out ) {
      91      198843 :   ulong v = (ulong)val;
      92      198843 :   ulong byte0 = (v    )&0x7FUL;
      93      198843 :   ulong byte1 = (v>> 7)&0x7FUL;
      94      198843 :   ulong byte2 = (v>>14);
      95      198843 :   int needs_byte1 = (v>0x007FUL);
      96      198843 :   int needs_byte2 = (v>0x3FFFUL);
      97      198843 :   fd_uchar_store_if( 1,           out + 0, (uchar)(byte0 | ((ulong)needs_byte1<<7)) );
      98      198843 :   fd_uchar_store_if( needs_byte1, out + 1, (uchar)(byte1 | ((ulong)needs_byte2<<7)) );
      99      198843 :   fd_uchar_store_if( needs_byte2, out + 2, (uchar)(byte2                          ) );
     100      198843 :   return (uint)(1+needs_byte1+needs_byte2);
     101      198843 : }
     102             : 
     103             : FD_PROTOTYPES_END
     104             : #endif /* HEADER_fd_src_ballet_txn_fd_compact_u16_h */

Generated by: LCOV version 1.14