Added packing/unpacking for vstr and vstr arrays

This commit is contained in:
Randy Jordan 2024-11-22 18:10:58 -06:00
parent 7092a57b67
commit 434993ea34
Signed by: Randy-Jordan
GPG Key ID: D57FA29E3B54663E
3 changed files with 159 additions and 4 deletions

View File

@ -6,8 +6,8 @@
#include <string.h>
struct Vstr {
char *buf; // String data
size_t len; // String len
char *buf; // String data
};
typedef struct Vstr Vstr;
@ -16,6 +16,10 @@ typedef struct Vstr Vstr;
#define VSTR(cstr) vstr_n(cstr, sizeof(cstr) - 1)
#define VSTR_NULL vstr_n(NULL, 0)
size_t pack_vstr(unsigned char *buffer, Vstr *vstr);
void unpack_vstr(unsigned char *buffer, Vstr *vstr);
size_t pack_vstr_array(unsigned char *buffer, Vstr *array, size_t count);
Vstr *unpack_vstr_array(unsigned char *buffer, size_t *count);
Vstr vstr_s(const char *s);
Vstr vstr_n(const char *s, size_t n);
bool vstr_cmp(const Vstr v1, const Vstr v2);
@ -26,4 +30,6 @@ Vstr vstr_substr(Vstr v, size_t start, size_t stop);
Vstr vstr_trim(Vstr v);
Vstr vstr_trim_left(Vstr v);
Vstr vstr_trim_right(Vstr v);
#endif

View File

@ -1,11 +1,122 @@
#include "../include/vstr.h"
#include <stdlib.h>
size_t pack_vstr(unsigned char *buffer, Vstr *vstr) {
size_t offset = 0;
// Pack the length of the string first (size_t)
buffer[offset++] = (vstr->len >> 56) & 0xFF;
buffer[offset++] = (vstr->len >> 48) & 0xFF;
buffer[offset++] = (vstr->len >> 40) & 0xFF;
buffer[offset++] = (vstr->len >> 32) & 0xFF;
buffer[offset++] = (vstr->len >> 24) & 0xFF;
buffer[offset++] = (vstr->len >> 16) & 0xFF;
buffer[offset++] = (vstr->len >> 8) & 0xFF;
buffer[offset++] = vstr->len & 0xFF;
// Pack the string data
memcpy(&buffer[offset], vstr->buf, vstr->len);
offset += vstr->len;
return offset; // Return the total packed size
}
void unpack_vstr(unsigned char *buffer, Vstr *vstr) {
unsigned int offset = 0;
// Unpack the length of the string (size_t)
vstr->len = 0;
for (int i = 0; i < 8; i++) {
vstr->len = (vstr->len << 8) | buffer[offset++];
}
// Allocate memory for the string and copy it from the buffer
vstr->buf = (char *)malloc(vstr->len + 1); // +1 for null terminator
if (vstr->buf != NULL) {
memcpy(vstr->buf, &buffer[offset], vstr->len);
vstr->buf[vstr->len] = '\0'; // Null-terminate the string
} else {
vstr->len = 0; // If memory allocation fails, set len to 0
}
}
size_t pack_vstr_array(unsigned char *buffer, Vstr *array, size_t count) {
size_t offset = 0;
// Pack the number of elements in the array
buffer[offset++] = (count >> 56) & 0xFF;
buffer[offset++] = (count >> 48) & 0xFF;
buffer[offset++] = (count >> 40) & 0xFF;
buffer[offset++] = (count >> 32) & 0xFF;
buffer[offset++] = (count >> 24) & 0xFF;
buffer[offset++] = (count >> 16) & 0xFF;
buffer[offset++] = (count >> 8) & 0xFF;
buffer[offset++] = count & 0xFF;
// Pack each Vstr in the array
for (size_t i = 0; i < count; i++) {
// Pack the length of the string
buffer[offset++] = (array[i].len >> 56) & 0xFF;
buffer[offset++] = (array[i].len >> 48) & 0xFF;
buffer[offset++] = (array[i].len >> 40) & 0xFF;
buffer[offset++] = (array[i].len >> 32) & 0xFF;
buffer[offset++] = (array[i].len >> 24) & 0xFF;
buffer[offset++] = (array[i].len >> 16) & 0xFF;
buffer[offset++] = (array[i].len >> 8) & 0xFF;
buffer[offset++] = array[i].len & 0xFF;
// Pack the string data
memcpy(&buffer[offset], array[i].buf, array[i].len);
offset += array[i].len;
}
return offset; // Return the total packed size
}
Vstr *unpack_vstr_array(unsigned char *buffer, size_t *count) {
size_t offset = 0;
// Unpack the number of elements in the array
*count = 0;
for (int i = 0; i < 8; i++) {
*count = (*count << 8) | buffer[offset++];
}
// Allocate memory for the Vstr array
Vstr *array = malloc(*count * sizeof(Vstr));
if (!array) return NULL; // Memory allocation failure
// Unpack each Vstr in the array
for (size_t i = 0; i < *count; i++) {
// Unpack the length of the string
array[i].len = 0;
for (int j = 0; j < 8; j++) {
array[i].len = (array[i].len << 8) | buffer[offset++];
}
// Allocate memory for the string
array[i].buf = malloc(array[i].len + 1); // +1 for null terminator
if (!array[i].buf) {
// Free previously allocated memory in case of failure
for (size_t k = 0; k < i; k++) {
free(array[k].buf);
}
free(array);
return NULL;
}
// Copy the string data
memcpy(array[i].buf, &buffer[offset], array[i].len);
array[i].buf[array[i].len] = '\0'; // Null-terminate the string
offset += array[i].len;
}
return array;
}
Vstr vstr_s(const char *s){
Vstr v = {(char *)s, s == NULL ? 0 : strlen(s)};
Vstr v = {s == NULL ? 0 : strlen(s), (char *)s};
return v;
}
Vstr vstr_n(const char *s, size_t n){
Vstr v = {(char *)s, n};
Vstr v = {n,(char *)s};
return v;
}
bool vstr_cmp(const Vstr v1, const Vstr v2){

View File

@ -39,7 +39,45 @@ int main(void){
TEST(vstr_cmp(b,bc) == 0);
TEST(vstr_cmp(a,ac) == 0);
unsigned char buffer[256];
size_t packed_size = pack_vstr(buffer, &v);
printf("Packed size: %lu bytes\n", packed_size);
Vstr unpacked_vstr;
unpack_vstr(buffer, &unpacked_vstr);
printf("Unpacked string: %s\n", unpacked_vstr.buf);
printf("Unpacked length: %zu\n", unpacked_vstr.len);
free(unpacked_vstr.buf);
Vstr array[] = {
{5, "Hello"},
{7, "World!"},
{6, "Buffer"}
};
size_t count = 3;
unsigned char arr_buffer[1024];
size_t arr_packed_size = pack_vstr_array(arr_buffer, array, count);
printf("Packed size: %lu bytes\n", arr_packed_size);
size_t unpacked_count;
Vstr *unpacked_array = unpack_vstr_array(arr_buffer, &unpacked_count);
if (!unpacked_array) {
printf("Failed to unpack the array.\n");
return 1;
}
printf("Unpacked %zu Vstr elements:\n", unpacked_count);
for (size_t i = 0; i < unpacked_count; i++) {
printf(" [%zu]: %s (len=%zu)\n", i, unpacked_array[i].buf, unpacked_array[i].len);
free(unpacked_array[i].buf); // Free the string data
}
free(unpacked_array);
return EXIT_SUCCESS;
}