#pragma once #ifdef Plan9 #include #include typedef vlong int64_t; typedef uvlong uint64_t; typedef int int32_t; typedef uint uint32_t; typedef short int16_t; typedef ushort uint16_t; typedef schar int8_t; typedef uchar uint8_t; #define NULL nil #define stderr 2 #define fprintf fprint #define vfprintf vfprint #define PRIu64 "ull" #define PRId64 "ll" #endif #ifdef __GNUC__ #define PB_GNUC_ATTR(a) __attribute__((a)) #else #define PB_GNUC_ATTR(a) #endif /* callback return codes */ enum { PB_CALLBACK_ERROR = -1, /* parsing should fail */ PB_CALLBACK_THROW_AWAY, /* throw away the value */ PB_CALLBACK_OK, }; enum { PB_FLAG_MASK_TYPE = 3, /* PB_TYPE_* */ PB_FLAG_POINTER = 1<<2, PB_FLAG_TRUNCATE = 1<<3, PB_FLAG_CONST_SIZE = 1<<4, PB_FLAG_REQUIRED = 1<<5, PB_FLAG_SIGNED = 1<<6, PB_FLAG_NO_PRINT = 1<<7, PB_FLAG_IS_CONST = 1<<8, PB_FLAG_TYPE_UNSIGNED = 1<<9, }; enum { PB_TYPE_STRING, PB_TYPE_BYTES, PB_TYPE_INTEGER, PB_TYPE_MSG, }; struct pb_default { /* default value */ uint64_t integer; void *pointer; uint16_t size; }; struct pb_field { #ifdef PB_PRINTERS const char *name; char *(*seprint)(const void *in, char *s, char *e, int left, int indent, const struct pb_field *field); #endif uint16_t offset; /* offset in the parent data struct, bytes */ int16_t num_at; /* offset in the parent data struct of the "int num" related to this field, bytes */ uint16_t num; /* number of entries in the array */ uint16_t size; /* sizeof() of the field if not array, sizeof(a[0]) if array */ uint16_t flags; uint8_t index; /* [1,255], 0 is used for non-protobuf fields */ uint8_t dfltidx; /* points to the array of default values, [1,255] */ uint8_t msgidx; /* points to the array of message types, [1,255] */ uint8_t cbidx; /* points to the array of callbacks, [1,255] */ }; struct pb_msg { const struct pb_field *fields; #ifdef PB_PRINTERS const char *name; const int *indices; #endif /* buffer to store strings by pointers */ int16_t buffer_at; uint16_t buffer_size; /* stuff that is not used goes into the "rest" buffer */ int16_t rest_at; uint16_t rest_size; uint8_t num_fields; }; struct pb_data { const struct pb_msg *msgs; const struct pb_default *dflts; const void **cbs; }; void pb_reset(void *out, const struct pb_msg *msg, const struct pb_data *pb); const uint8_t *pb_decode(void *out, const uint8_t *s, const uint8_t *e, const struct pb_msg *msg, const struct pb_data *pb); uint8_t *pb_encode(const void *in, uint8_t *s, uint8_t *e, const struct pb_msg *msg, const struct pb_data *pb); char *pb_seprint(const void *in, char *s, char *e, const struct pb_msg *msg, const struct pb_data *pb, int left, int indent); #ifdef PB_PRINTERS char *seprintf(char *s, char *e, char *fmt, ...) PB_GNUC_ATTR(format(printf, 3, 4)); #endif