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

Generated by: LCOV version 1.14