#include #include #include #include #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) #include #endif #ifdef _WIN32 #include #endif #include "includes/serialization.h" /* Takes in float values, casts them to uint16_t and creates a Serial_Data struct */ Serial_Data Serial_create_data(float pad_x, float pad_y, float ball_x, float ball_y, bool should_quit) { Serial_Data data; data.pad_x = (uint16_t)pad_x; data.pad_y = (uint16_t)pad_y; data.ball_x = (uint16_t)ball_x; data.ball_y = (uint16_t)ball_y; data.should_quit = should_quit; return data; } /* Serializes a 'Data' struct into a byte array, converted to network-byte order */ uint8_t* Serial_serialize(Serial_Data data) { /* Create a pointer that can fit the entire struct */ uint8_t* serialized = malloc(sizeof(Serial_Data) + 1); uint8_t* pad_x_ptr; uint8_t* pad_y_ptr; uint8_t* ball_x_ptr; uint8_t* ball_y_ptr; uint8_t* should_quit_ptr; memset(serialized, 0, sizeof(Serial_Data) + 1); // Zero out the memory pad_x_ptr = serialized; pad_y_ptr = pad_x_ptr + sizeof(uint16_t); ball_x_ptr = pad_y_ptr + sizeof(uint16_t); ball_y_ptr = ball_x_ptr + sizeof(uint16_t); should_quit_ptr = ball_y_ptr + sizeof(uint16_t); *((uint16_t *)pad_x_ptr) = data.pad_x; *((uint16_t *)pad_x_ptr) = htons(*((uint16_t *)pad_x_ptr)); *((uint16_t *)pad_y_ptr) = data.pad_y; *((uint16_t *)pad_y_ptr) = htons(*((uint16_t *)pad_y_ptr)); *((uint16_t *)ball_x_ptr) = data.ball_x; *((uint16_t *)ball_x_ptr) = htons(*((uint16_t *)ball_x_ptr)); *((uint16_t *)ball_y_ptr) = data.ball_y; *((uint16_t *)ball_y_ptr) = htons(*((uint16_t *)ball_y_ptr)); *((bool *)should_quit_ptr) = data.should_quit; *(should_quit_ptr + sizeof(bool)) = '\0'; return serialized; } /* Deserialize a byte array into a 'Data' struct, converted to host byte order */ Serial_Data Serial_deserialize(uint8_t* serialized) { Serial_Data deserialized; /* Use successive chunks of memory address to create pointers to the data */ uint8_t* pad_x_ptr = serialized; uint8_t* pad_y_ptr = serialized + sizeof(uint16_t); uint8_t* ball_x_ptr = pad_y_ptr + sizeof(uint16_t); uint8_t* ball_y_ptr = ball_x_ptr + sizeof(uint16_t); uint8_t* should_quit_ptr = ball_y_ptr + sizeof(uint16_t); /* Dereference (and cast) the pointers, and store them into the struct */ deserialized.pad_x = *((uint16_t *)pad_x_ptr); deserialized.pad_x = ntohs(deserialized.pad_x); deserialized.pad_y = *((uint16_t *)pad_y_ptr); deserialized.pad_y = ntohs(deserialized.pad_y); deserialized.ball_x = *((uint16_t *)ball_x_ptr); deserialized.ball_x = ntohs(deserialized.ball_x); deserialized.ball_y = *((uint16_t *)ball_y_ptr); deserialized.ball_y = ntohs(deserialized.ball_y); deserialized.should_quit = *((bool *)should_quit_ptr); return deserialized; }