Skip to content

Commit 6b8ac09

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 6b8ac09

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

src/flamenco/types/fd_bincode.h

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

0 commit comments

Comments
 (0)