Files

45 lines
1.3 KiB
C

/*
* pb_decode_string — protobuf-like string decoder.
* Pre-fix; internal RPC layer.
*
* Wire format: <varint length> <length bytes of data>
* Caller passes a buffer; this writes the decoded length-prefixed string
* into a heap buffer allocated based on the wire-supplied length.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
static int read_varint(const uint8_t **p, const uint8_t *end, uint64_t *out) {
uint64_t v = 0; int shift = 0;
while (*p < end) {
uint8_t b = *(*p)++;
v |= ((uint64_t)(b & 0x7f)) << shift;
if ((b & 0x80) == 0) { *out = v; return 0; }
shift += 7;
if (shift > 63) return -1;
}
return -1;
}
/* Returns a newly malloc'd copy of the decoded string. *out_len gets length. */
char *pb_decode_string(const uint8_t *buf, size_t buf_len, size_t *out_len) {
const uint8_t *p = buf, *end = buf + buf_len;
uint64_t declared_len = 0;
if (read_varint(&p, end, &declared_len) != 0) return NULL;
/* allocate +1 for nul terminator */
char *s = (char *)malloc((size_t)declared_len + 1);
if (s == NULL) return NULL;
/* copy declared_len bytes from the wire */
memcpy(s, p, (size_t)declared_len);
s[declared_len] = '\0';
*out_len = (size_t)declared_len;
return s;
}