Skip to content

Instantly share code, notes, and snippets.

@gromgit
Created November 27, 2017 13:43
Show Gist options
  • Save gromgit/29e0db416b08f70dce89a8f180c35a73 to your computer and use it in GitHub Desktop.
Save gromgit/29e0db416b08f70dce89a8f180c35a73 to your computer and use it in GitHub Desktop.
PackedArray serialization test
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "PackedArray.h"
/*
PackedArray serialization test
BUILD:
1. Grab PackedArray.[ch] from https://github.com/gpakosz/PackedArray, drop them in this dir
2. gcc -g -Wall -Werror -pedantic -std=c11 -o pa_serial_test pa_serial_test.c PackedArray.c
*/
#define N 1000000
/*
PackedArray serialization format:
|----------------------------------------------------------------|
| bitsPerItem (8 bits) | arrayCount (32 bits) | <packedData> ... |
|----------------------------------------------------------------|
*/
void PackedArray_fwrite(PackedArray* a, FILE* stream) {
// First write out the metadata
uint8_t bpi = a->bitsPerItem;
fwrite(&bpi, sizeof(bpi), 1, stream);
fwrite(&(a->count), sizeof(a->count), 1, stream);
// Now write the actual bytes
fwrite(a->buffer, sizeof(a->buffer[0]), PackedArray_bufferSize(a), stream);
}
PackedArray* PackedArray_fread(FILE* stream) {
// First read in the metadata
uint8_t bpi;
uint32_t cnt;
fread(&bpi, sizeof(bpi), 1, stream);
fread(&cnt, sizeof(cnt), 1, stream);
// Create a new PackedArray
PackedArray* a = PackedArray_create(bpi, cnt);
// Copy the raw bytes into buffer
fread(a->buffer, sizeof(a->buffer[0]), PackedArray_bufferSize(a), stream);
return a;
}
uint32_t a[N], b[N], c[N], d[N];
int main() {
// Fill two arrays with random unsigned integers (0-15)
for (int i = 0; i < N; i++) {
a[i] = rand() % 16;
b[i] = rand() % 16;
}
// Dynamically-sized PackedArray(a) (should be 4 bits)
uint32_t bpi = PackedArray_computeBitsPerItem(a, N);
printf("bpi = %d (expected 4)\n", bpi);
PackedArray *pa = PackedArray_create(bpi, N);
PackedArray_pack(pa, 0, a, N);
printf("sizeof(pa) = %d\n", PackedArray_bufferSize(pa));
// Fixed-sized PackedArray(b) (6 bits)
PackedArray *pb = PackedArray_create(6, N);
PackedArray_pack(pb, 0, b, N);
printf("sizeof(pb) = %d\n", PackedArray_bufferSize(pb));
// Write them both out to a file sequentially
FILE *fp = fopen("test.packed", "w");
// Dump out both arrays
PackedArray_fwrite(pa, fp);
PackedArray_fwrite(pb, fp);
fclose(fp);
// Read them back in
fp = fopen("test.packed", "r");
PackedArray *pc = PackedArray_fread(fp);
PackedArray *pd = PackedArray_fread(fp);
fclose(fp);
// Do some sanity checks
assert(pc->bitsPerItem == pa->bitsPerItem);
assert(pc->count == pa->count);
assert(pd->bitsPerItem == pd->bitsPerItem);
assert(pd->count == pb->count);
// Now unpack them
PackedArray_unpack(pc, 0, c, N);
PackedArray_unpack(pd, 0, d, N);
// And check against the originals
for (int i = 0; i < N; i++) {
assert(a[i] == c[i]);
assert(b[i] == d[i]);
}
// Clean up, because it's the Right Thing.
PackedArray_destroy(pa);
PackedArray_destroy(pb);
PackedArray_destroy(pc);
PackedArray_destroy(pd);
// Done.
puts("YAY! All done!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment