Store Structs and Arrays from C
Numstore types have no padding: a struct is the sum of its members and a strict array is the product of its dimensions. A C struct you read into must therefore be packed, or the compiler's padding will shift every field.
#include "numstore.h"
#include <inttypes.h>
#include <stdio.h>
// Numstore types have no padding, so the C struct must have none either.
#ifdef _MSC_VER
# define PACK_PUSH __pragma (pack (push, 1))
# define PACK_POP __pragma (pack (pop))
# define PACKED
#else
# define PACK_PUSH
# define PACK_POP
# define PACKED __attribute__ ((packed))
#endif
PACK_PUSH
struct frame
{
uint64_t timestamp;
uint8_t pixels[4][4];
} PACKED;
PACK_POP
int
main (void)
{
ns_cleanup ("frames.db");
nsdb_t *db = ns_open ("frames.db");
if (ns_execute (
db, NULL, "create frames struct { timestamp u64, pixels [4][4] u8 }"
) != 0) {
fprintf (stderr, "create failed: %s\n", ns_strerror (db, false));
ns_close (db);
return 1;
}
printf ("sizeof (struct frame) = %zu\n", sizeof (struct frame));
struct frame in[2] = {0};
for (int f = 0; f < 2; f++) {
in[f].timestamp = 1000 + f;
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
in[f].pixels[r][c] = (uint8_t)(f * 16 + r * 4 + c);
}
}
}
sb_size wrote = ns_write (db, NULL, in, sizeof (in), "insert frames 0 2");
printf ("wrote %" PRId64 " frames\n", wrote);
struct frame out[2] = {0};
sb_size read = ns_read (db, NULL, out, sizeof (out), "read frames[0:]");
printf ("read %" PRId64 " frames\n", read);
for (sb_size i = 0; i < read; i++) {
printf (
"frame %" PRId64 ": timestamp=%" PRIu64
" pixels[0][0]=%u pixels[3][3]=%u\n",
i,
out[i].timestamp,
out[i].pixels[0][0],
out[i].pixels[3][3]
);
}
nsdb_var_t *var = ns_get_var (db, NULL, "get frames");
printf ("variable holds %" PRIu64 " elements\n", ns_var_len (var));
ns_var_free (var);
return ns_close (db);
}sizeof (struct frame) = 24
wrote 2 frames
read 2 frames
frame 0: timestamp=1000 pixels[0][0]=0 pixels[3][3]=15
frame 1: timestamp=1001 pixels[0][0]=16 pixels[3][3]=31
variable holds 2 elements
8 + 4 x 4 = 24 bytes, which is what both
Numstore and the packed struct agree on. Arrays are stored
in C order, so pixels[r][c] lines up element
for element. The sizing rules for every type are in the type system.