Introduce bincode.h and scaffold.h. The former is for bincode-specific reading from a data bufer, the latter is for common reusable components (scaffolding) across the project
Y26WT3ZFN7KSVXOZ26B5Y2OR4M4VQYQLPMAHPC4O5VIT3ENBISXAC WMFNGOYTKIZ7L25V3KMJPSWK23DTN6G3ESP6M55YIH6UTHFKL2XAC PEUS54XQ5KJQYAVUYBG5MWLEHIOVPMZ3ANVC7HPQP6JUWWPRDW5AC VKLGQREYOZDV46F672RFE5XJO3OEOP4EHTCWZYOJY24HVPQX3L6QC Q7TKZCJP2Z75EICZYKCEZDHKGERSOKZGMTSU3UXETBHTF663T66AC RIWSVVASWLJQQTSVRHIIUPENOZWOMHQLZMTQVGJUS2ZUGDPSWWIQC OBKF6SIIFFHHY7YWKPPX75N23NAVUD5662DKIHXSSIDPKKXQ5ZDQC X36ICMJNYKJF35ZUEVCCR33JOZPCPZQ6KSGEQI3RZND2P5EDASLQC B3XLVPNC4COLLC3FUE34Y7HIKTMF6CJZUASZOU3YM2YGPZKJZP7QC 3OHR6ZPHN53SVWJL4GUKKUC223IPXA73UPBFJCM4ENGS27AKHN6AC #ifndef SCAFFOLD_H#define SCAFFOLD_H/* Various scaffolding functions around stdlib functions */void *xmalloc(size_t size);#endif
#include <stdio.h>#include <stdlib.h>#include "scaffold.h"/*** Expand to support varargs like a regular printf*/void die(const char *msg){fprintf(stderr, msg);exit(57);}void *xmalloc(size_t size){void *ret;ret = malloc(size);if (!ret)die("Unable to allocate memory");return ret;}
/* TODO Decode into 'struct hashed' */
p = buf;dump_buf("hashed", p, hashed_len);hashed.version = bincode_getu64(p);printf("version = %lu\n", hashed.version);p += sizeof(uint64_t);len = bincode_getu64(p);p += sizeof(uint64_t);hashed.header.message = bincode_getstr(p, len);p += len;printf("message = '%s'\n", hashed.header.message);/*** Description! This is like the commit "body", and is optional, so we* have a byte indicating its presence, '0' = None, '1' =* Some(description)*/if (*p++) {len = bincode_getu64(p);p += sizeof(uint64_t);hashed.header.description = bincode_getstr(p, len);p += len;printf("description = '%s'\n", hashed.header.description);} elseprintf("description = (none)\n");len = bincode_getu64(p);p += sizeof(uint64_t);
#ifndef BINCODE_H#define BINCODE_H/** Requires: <stdint.h> *//*** Definitions for the bincode encode/decode routines.** Generally, the idea here is that you open a file, get a file descriptor and* use the encode/decode routines to get components read from the fd and and* decoded as the type you want.*//*** Some notes regarding the bincode format:** Enum types: The order of the variants matter, as the encoding indicates the* variant with a u32.*/uint16_t bincode_getu16(uint8_t *);uint32_t bincode_getu32(uint8_t *);uint64_t bincode_getu64(uint8_t *);/*** Allocate and return a string of the given length.** The memory allocated shall be the given length plus one, to hold the* terminating zero.** Returns the allocated string. The caller is responsible for deallocating.*/char *bincode_getstr(uint8_t *, size_t);/* void bincode_putu16(uint8_t *, uint16_t); *//* void bincode_putu32(uint8_t *, uint32_t); *//* void bincode_putu64(uint8_t *, uint64_t); */#endif
#include <stdint.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include "scaffold.h"#include "bincode.h"uint16_tbincode_getu16(uint8_t *b){return (uint16_t)b[1] << 8 | (uint16_t)b[0];}uint32_tbincode_getu32(uint8_t *b){return (uint32_t)b[3] << 24| (uint32_t)b[2] << 16| (uint32_t)b[1] << 8| (uint32_t)b[0];}uint64_tbincode_getu64(uint8_t *b){return (uint64_t)b[7] << 56| (uint64_t)b[6] << 48| (uint64_t)b[5] << 40| (uint64_t)b[4] << 32| (uint64_t)b[3] << 24| (uint64_t)b[2] << 16| (uint64_t)b[1] << 8| (uint64_t)b[0];}char *bincode_getstr(uint8_t *b, size_t len){char *str;str = xmalloc(len + 1);memcpy(str, b, len);str[len] = '\0';return str;}