Created
November 8, 2022 22:46
-
-
Save ijustlovemath/0a518a3b857e1d9eb8033e119106acb0 to your computer and use it in GitHub Desktop.
A very simple example of how you can make a serializer in C using a packed binary format
This file contains hidden or 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 <string.h> | |
#include <unistd.h> | |
struct simple_header { | |
char kind; /* I arbitrarily chose a char, which could use something like 's' for string, 'i' for int, etc. Commonly you will see an enum used here */ | |
int length; /* You could use a negative length to indicate errors of some kind, or just use a simple size_t */ | |
}; | |
struct simple_payload { | |
unsigned char *data; | |
}; | |
int serialize_string(int fd, const char *payload) { | |
// Automatically find the size, for convenience | |
size_t length = strlen(payload); | |
// Set aside a header and populate it | |
struct simple_header header; | |
header.kind = 's'; | |
header.length = (int) length; // This could be checked better, but also just a simple example | |
// Send the header over the wire, doing minimal error checking | |
int ret = write(fd, &header, sizeof(header)); | |
if(ret < 0) return ret; | |
// Send the payload | |
ret = write(fd, payload, length); | |
return ret; | |
} | |
int deserialize(int fd, struct simple_payload *destination) { | |
struct simple_header received_header; | |
int ret = read(fd, &received_header, sizeof(received_header)); | |
if(ret < 0) return ret; | |
// This solution totally ignores endianness, which you will need to consider if sending and receiving on different computers | |
// Always work with zeroed buffers when you can, leave room for NULL bytes | |
destination->data = calloc(received_header.length + 1, 1); | |
ret = read(fd, destination->data, received_header.length); | |
if(ret < 0) { | |
free(destination->data); | |
return ret; | |
} | |
switch(received_header.kind) { | |
case 's': | |
/* do something special for strings */ | |
; | |
default: | |
return -1; /* unsupported format */ | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment