Skip to content

Instantly share code, notes, and snippets.

@zambony
Last active February 29, 2020 07:47
Show Gist options
  • Save zambony/064ea18f63803f78d30c1d7c385a65c1 to your computer and use it in GitHub Desktop.
Save zambony/064ea18f63803f78d30c1d7c385a65c1 to your computer and use it in GitHub Desktop.
Basic non-portable example of serialization in C using void* buffers
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_INIT 32
typedef struct SerializedBuffer
{
void* data;
size_t index;
size_t size;
size_t read;
} SerializedBuffer;
SerializedBuffer* makeBuffer()
{
SerializedBuffer* buffer = malloc(sizeof(SerializedBuffer));
buffer->data = malloc(BUFFER_INIT);
buffer->size = BUFFER_INIT;
buffer->index = 0;
buffer->read = 0;
return buffer;
}
void padBuffer(SerializedBuffer* buffer, size_t bytes)
{
if ((buffer->index + bytes) > buffer->size)
{
buffer->data = realloc(buffer->data, buffer->size * 2);
buffer->size *= 2;
}
}
void pack_int(SerializedBuffer *buffer, int x)
{
padBuffer(buffer, sizeof(int));
memcpy(((char*)buffer->data) + buffer->index, &x, sizeof(int));
buffer->index += sizeof(int);
}
void pack_string(SerializedBuffer *buffer, char *text)
{
size_t len = strlen(text) + 1;
padBuffer(buffer, sizeof(char) * len);
memcpy(((char*)buffer->data) + buffer->index, text, sizeof(char) * len);
buffer->index += sizeof(char) * len;
}
int unpack_int(SerializedBuffer* buffer)
{
int out;
memcpy(&out, ((char*)buffer->data) + (buffer->read), sizeof(int));
buffer->read += sizeof(int);
return out;
}
char* unpack_string(SerializedBuffer* buffer)
{
int size = 32;
char* out = malloc(sizeof(char) * size);
int i = 0;
char c;
while ((c = ((char*)buffer->data)[buffer->read++]) != '\0')
{
out[i++] = c;
if (i > size)
{
out = realloc(out, size * 2);
size *= 2;
}
}
out[i] = '\0';
out = realloc(out, i + 1);
return out;
}
typedef struct test
{
int x;
char* y;
} test;
SerializedBuffer* pack_test(test* obj)
{
SerializedBuffer* buffer = makeBuffer();
pack_int(buffer, obj->x);
pack_string(buffer, obj->y);
return buffer;
}
int unpack_test(SerializedBuffer* buffer, test* out)
{
out->x = unpack_int(buffer);
out->y = unpack_string(buffer);
return 1;
}
int main()
{
test start = {3, "1"};
SerializedBuffer* buffer = pack_test(&start);
test out;
unpack_test(buffer, &out);
printf("%d\n", buffer->size);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment