LCOV - code coverage report
Current view: top level - ballet/pb - fd_pb_wire.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 75 0.0 %
Date: 2026-01-24 04:58:51 Functions: 0 48 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_pb_fd_pb_wire_h
       2             : #define HEADER_fd_src_ballet_pb_fd_pb_wire_h
       3             : 
       4             : /* fd_pb_wire.h provides Protobuf wire format definitions and pure
       5             :    functions. */
       6             : 
       7             : #include "../../util/bits/fd_bits.h"
       8             : #include "../../util/log/fd_log.h"
       9             : 
      10             : /* Select a varint coding strategy */
      11             : 
      12             : #if defined(__BMI2__) && __LZCNT__
      13             : #include <immintrin.h>
      14             : #define FD_PB_VARINT_CORE 1 /* x86 PDEP and LZCNT */
      15             : #else
      16             : #define FD_PB_VARINT_CORE 0 /* portable */
      17             : #endif
      18             : 
      19             : /* Message structure */
      20             : 
      21           0 : #define FD_PB_WIRE_TYPE_VARINT (0U)
      22           0 : #define FD_PB_WIRE_TYPE_I64    (1U)
      23           0 : #define FD_PB_WIRE_TYPE_LEN    (2U)
      24           0 : #define FD_PB_WIRE_TYPE_I32    (5U)
      25             : 
      26             : static inline uint
      27             : fd_pb_tag( uint wire_type,
      28           0 :            uint field_id ) {
      29           0 :   return ( field_id<<3 ) | wire_type;
      30           0 : }
      31             : 
      32             : static inline uint
      33           0 : fd_pb_tag_wire_type( uint tag ) {
      34           0 :   return tag & 0x7U;
      35           0 : }
      36             : 
      37             : static inline uint
      38           0 : fd_pb_tag_field_id( uint tag ) {
      39           0 :   return tag >> 3;
      40           0 : }
      41             : 
      42             : /* Max value sizes (template friendly) */
      43             : 
      44             : #define fd_pb_bool_max_sz      (1U)
      45           0 : #define fd_pb_varint32_sz_max  (5U)
      46             : #define fd_pb_varint64_sz_max (10U)
      47             : #define fd_pb_int32_sz_max    fd_pb_varint32_sz_max
      48             : #define fd_pb_int64_sz_max    fd_pb_varint64_sz_max
      49             : #define fd_pb_uint32_sz_max   fd_pb_varint32_sz_max
      50             : #define fd_pb_uint64_sz_max   fd_pb_varint64_sz_max
      51             : #define fd_pb_sint32_sz_max   fd_pb_varint32_sz_max
      52             : #define fd_pb_sint64_sz_max   fd_pb_varint64_sz_max
      53           0 : #define fd_pb_fixed32_sz_max  sizeof(uint)
      54           0 : #define fd_pb_fixed64_sz_max  sizeof(ulong)
      55             : 
      56             : /* Value encoders */
      57             : 
      58             : static inline uchar *
      59             : fd_pb_append_bool( uchar buf[ fd_pb_bool_max_sz ],
      60           0 :                    int   value ) {
      61           0 :   buf[0] = !!value;
      62           0 :   return buf+1;
      63           0 : }
      64             : 
      65             : #if FD_PB_VARINT_CORE==0 /* portable */
      66             : 
      67             : static inline uchar *
      68             : fd_pb_append_varint32( uchar buf[ fd_pb_varint32_sz_max ],
      69             :                        uint  value ) {
      70             :   int msb = fd_uint_find_msb( value|1U )+1;
      71             :   buf[ 0 ] = (uchar)( ( msb> 7 ? 0x80 : 0 ) | ( (value>> 0) & 0x7f ) );
      72             :   buf[ 1 ] = (uchar)( ( msb>14 ? 0x80 : 0 ) | ( (value>> 7) & 0x7f ) );
      73             :   buf[ 2 ] = (uchar)( ( msb>21 ? 0x80 : 0 ) | ( (value>>14) & 0x7f ) );
      74             :   buf[ 3 ] = (uchar)( ( msb>28 ? 0x80 : 0 ) | ( (value>>21) & 0x7f ) );
      75             :   buf[ 4 ] = (uchar)(                         ( (value>>28) & 0x7f ) );
      76             :   return buf+((msb+6)/7);
      77             : }
      78             : 
      79             : static inline uchar *
      80             : fd_pb_append_varint32_sz5( uchar buf[ fd_pb_varint32_sz_max ],
      81             :                            uint  value ) {
      82             :   buf[ 0 ] = (uchar)( 0x80 | ( (value>> 0) & 0x7f ) );
      83             :   buf[ 1 ] = (uchar)( 0x80 | ( (value>> 7) & 0x7f ) );
      84             :   buf[ 2 ] = (uchar)( 0x80 | ( (value>>14) & 0x7f ) );
      85             :   buf[ 3 ] = (uchar)( 0x80 | ( (value>>21) & 0x7f ) );
      86             :   buf[ 4 ] = (uchar)(        ( (value>>28) & 0x7f ) );
      87             :   return buf+5;
      88             : }
      89             : 
      90             : static inline uchar *
      91             : fd_pb_append_varint64( uchar buf[ fd_pb_varint64_sz_max ],
      92             :                        ulong value ) {
      93             :   int msb = fd_ulong_find_msb( value|1U )+1;
      94             :   buf[ 0 ] = (uchar)( ( msb> 7 ? 0x80 : 0 ) | ( (value>> 0) & 0x7f ) );
      95             :   buf[ 1 ] = (uchar)( ( msb>14 ? 0x80 : 0 ) | ( (value>> 7) & 0x7f ) );
      96             :   buf[ 2 ] = (uchar)( ( msb>21 ? 0x80 : 0 ) | ( (value>>14) & 0x7f ) );
      97             :   buf[ 3 ] = (uchar)( ( msb>28 ? 0x80 : 0 ) | ( (value>>21) & 0x7f ) );
      98             :   buf[ 4 ] = (uchar)( ( msb>35 ? 0x80 : 0 ) | ( (value>>28) & 0x7f ) );
      99             :   buf[ 5 ] = (uchar)( ( msb>42 ? 0x80 : 0 ) | ( (value>>35) & 0x7f ) );
     100             :   buf[ 6 ] = (uchar)( ( msb>49 ? 0x80 : 0 ) | ( (value>>42) & 0x7f ) );
     101             :   buf[ 7 ] = (uchar)( ( msb>56 ? 0x80 : 0 ) | ( (value>>49) & 0x7f ) );
     102             :   buf[ 8 ] = (uchar)( ( msb>63 ? 0x80 : 0 ) | ( (value>>56) & 0x7f ) );
     103             :   buf[ 9 ] = (uchar)(                         ( (value>>63) & 0x7f ) );
     104             :   return buf+((msb+6)/7);
     105             : }
     106             : 
     107             : #elif FD_PB_VARINT_CORE==1 /* x86 PDEP and LZCNT */
     108             : 
     109             : static inline uchar *
     110             : fd_pb_append_varint32( uchar buf[ fd_pb_varint32_sz_max ],
     111           0 :                        uint  value ) {
     112             :   /* Scatter bits */
     113           0 :   ulong enc  = _pdep_u64( value, 0x7f7f7f7f7f7f7f7fUL );
     114             :   /* Count leading zeros */
     115           0 :   uint  lzc  = (uint)_lzcnt_u64( enc|1 );
     116             :   /* Generate continuation bits */
     117           0 :   ulong cont = 0x80808080808080UL >> (lzc&0x38);
     118             :   /* Store result */
     119           0 :   ulong res  = enc|cont;
     120           0 :   FD_STORE( uint, buf, (uint)res );
     121           0 :   buf[4] = (uchar)( res>>32 );
     122           0 :   return buf+( 8-(lzc>>3) );
     123           0 : }
     124             : 
     125             : static inline uchar *
     126             : fd_pb_append_varint32_sz5( uchar buf[ fd_pb_varint32_sz_max ],
     127           0 :                            uint  value ) {
     128           0 :   FD_STORE( uint, buf, 0x80808080 | _pdep_u32( value, 0x7f7f7f7f ) );
     129           0 :   buf[ 4 ] = (uchar)( (value>>28) & 0x7f );
     130           0 :   return buf+5;
     131           0 : }
     132             : 
     133             : static inline uchar *
     134             : fd_pb_append_varint64( uchar buf[ fd_pb_varint64_sz_max ],
     135           0 :                        ulong value ) {
     136             :   /* Number of continuation bytes */
     137           0 :   int  len    = fd_ulong_find_msb( value|1U )/7;
     138             :   /* Scatter bits */
     139           0 :   ulong const scatter = 0x7f7f7f7f7f7f7f7fUL;
     140           0 :   ulong enc0  = _pdep_u64( value,     scatter );
     141           0 :   ulong enc1  = _pdep_u64( value>>56, scatter );
     142             :   /* Generate continuation bits */
     143           0 :   ulong const pattern = 0x8080808080808080UL;
     144           0 :   ulong cont0 = _bzhi_u64( pattern, (uint)fd_uint_min( (uint)(  len   <<3 ), 64 ) );
     145           0 :   ulong cont1 = _bzhi_u64( pattern,                    (uint)( (len-8)<<3 )       );
     146             :   /* Store result */
     147           0 :   FD_STORE( ulong,  buf,             enc0|cont0   );
     148           0 :   FD_STORE( ushort, buf+8, (ushort)( enc1|cont1 ) );
     149           0 :   return buf+len+1;
     150           0 : }
     151             : 
     152             : #endif /* varint cores */
     153             : 
     154             : static inline uchar *
     155             : fd_pb_append_tag( uchar buf[ fd_pb_int32_sz_max ],
     156           0 :                   ulong tag ) {
     157           0 :   return fd_pb_append_varint32( buf, (uint)tag );
     158           0 : }
     159             : 
     160             : static inline uchar *
     161             : fd_pb_append_int32( uchar buf[ fd_pb_varint32_sz_max ],
     162           0 :                     int   value ) {
     163           0 :   return fd_pb_append_varint32( buf, (uint)value );
     164           0 : }
     165             : 
     166             : static inline uchar *
     167             : fd_pb_append_int64( uchar buf[ fd_pb_int64_sz_max ],
     168           0 :                     long  value ) {
     169           0 :   return fd_pb_append_varint64( buf, (ulong)value );
     170           0 : }
     171             : 
     172             : static inline uchar *
     173             : fd_pb_append_uint32( uchar buf[ fd_pb_uint32_sz_max ],
     174           0 :                      uint  value ) {
     175           0 :   return fd_pb_append_varint32( buf, value );
     176           0 : }
     177             : 
     178             : static inline uchar *
     179             : fd_pb_append_uint64( uchar buf[ fd_pb_uint64_sz_max ],
     180           0 :                      ulong value ) {
     181           0 :   return fd_pb_append_varint64( buf, value );
     182           0 : }
     183             : 
     184             : static inline uchar *
     185             : fd_pb_append_sint32( uchar buf[ fd_pb_sint32_sz_max ],
     186           0 :                      int   value ) {
     187           0 :   return fd_pb_append_varint32( buf, fd_int_zz_enc( value ) );
     188           0 : }
     189             : 
     190             : static inline uchar *
     191             : fd_pb_append_sint64( uchar buf[ fd_pb_sint64_sz_max ],
     192           0 :                      long  value ) {
     193           0 :   return fd_pb_append_varint64( buf, fd_long_zz_enc( value ) );
     194           0 : }
     195             : 
     196             : static inline uchar *
     197             : fd_pb_append_fixed32( uchar buf[ sizeof(uint) ],
     198           0 :                       uint  value ) {
     199           0 :   FD_STORE( uint, buf, value );
     200           0 :   return buf+sizeof(uint);
     201           0 : }
     202             : 
     203             : static inline uchar *
     204             : fd_pb_append_fixed64( uchar buf[ sizeof(ulong) ],
     205           0 :                       ulong value ) {
     206           0 :   FD_STORE( ulong, buf, value );
     207           0 :   return buf+sizeof(ulong);
     208           0 : }
     209             : 
     210             : #endif /* HEADER_fd_src_ballet_pb_fd_pb_wire_h */

Generated by: LCOV version 1.14