Skip to content

Commit 037dd12

Browse files
committed
types: add APIs for zero alloc decoding
- Add helper for converting between pointer and flat option representation - Add decode_flat helper
1 parent 12f8437 commit 037dd12

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

src/flamenco/types/fd_bincode.h

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#define HEADER_fd_src_util_encoders_fd_bincode_h
33

44
#include "../../util/fd_util.h"
5-
#include "../../util/valloc/fd_valloc.h"
65

76
typedef void
87
(* fd_types_walk_fn_t)( void * self,
@@ -552,4 +551,57 @@ static inline int fd_archive_decode_check_length( fd_bincode_decode_ctx_t * ctx,
552551
#define fd_bincode_decode_scratch( type, buf, buf_sz, perr ) \
553552
fd_bincode_decode1_scratch( type, buf, buf_sz, perr, NULL )
554553

554+
/* fd_bincode_decode_flat decodes a bincode type without dynamic
555+
allocations. */
556+
557+
#define fd_bincode_decode_flat( outp, type, buf, buf_sz, perr ) \
558+
__extension__({ \
559+
__typeof__ (outp) * out = NULL; \
560+
void const * const buf_ = (buf); \
561+
ulong const buf_sz_ = (buf_sz); \
562+
int * perr_ = (perr); \
563+
fd_bincode_decode_ctx_t ctx = {0}; \
564+
if( perr_ ) *perr_ = -1; \
565+
ctx.data = (void const *)( buf_ ); \
566+
ctx.dataend = (void const *)( (ulong)ctx.data + buf_sz_ ); \
567+
ulong total_sz = 0UL; \
568+
int err = fd_##type##_decode_footprint( &ctx, &total_sz ); \
569+
if( FD_LIKELY( err==FD_BINCODE_SUCCESS ) ) { \
570+
if( FD_UNLIKELY( sizeof( (*out) )!=total_sz ) ) { \
571+
FD_LOG_ERR(( "fd_bincode_" #type "_decode failed: decode requires %lu bytes, but out var is only %lu bytes", sizeof( (*out) ), total_sz )); \
572+
} \
573+
out = fd_##type##_decode( (outp), &ctx ); \
574+
} \
575+
if( perr_ ) *perr_ = err; \
576+
out; \
577+
})
578+
579+
#define fd_bincode_decode_scratch( type, buf, buf_sz, perr ) \
580+
fd_bincode_decode1_scratch( type, buf, buf_sz, perr, NULL )
581+
582+
/* Helpers for dealing with option types */
583+
584+
/* fd_types_option_flat_from_nullable populates a flat option from a
585+
pointer. Sets target.has_name = 0 if pointer is NULL, otherwise sets
586+
target.has_name = 1, and sets target.name = *pointer */
587+
588+
#define fd_types_option_flat_from_nullable( target, name, pointer ) \
589+
{ \
590+
__typeof__ (pointer) ptr = (pointer); \
591+
(target . has_##name) = !!ptr; \
592+
if( ptr ) (target . name) = *ptr; \
593+
}
594+
595+
/* fd_types_option_flat_to_nullable creates a nullable pointer to a flat
596+
option. Returns NULL if target.has_name == 0, otherwise returns
597+
&target.name */
598+
599+
#define fd_types_option_flat_to_nullable( target, name ) \
600+
__extension__({ \
601+
__typeof__( &( (target . name) ) ) ptr; \
602+
if( (target . has_##name) ) ptr = &(target . name); \
603+
else ptr = NULL; \
604+
ptr; \
605+
})
606+
555607
#endif /* HEADER_fd_src_util_encoders_fd_bincode_h */

0 commit comments

Comments
 (0)