Created
November 27, 2017 13:43
-
-
Save gromgit/29e0db416b08f70dce89a8f180c35a73 to your computer and use it in GitHub Desktop.
PackedArray serialization test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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