Added packing/unpacking for vstr and vstr arrays
This commit is contained in:
parent
7092a57b67
commit
434993ea34
@ -6,8 +6,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct Vstr {
|
struct Vstr {
|
||||||
char *buf; // String data
|
|
||||||
size_t len; // String len
|
size_t len; // String len
|
||||||
|
char *buf; // String data
|
||||||
};
|
};
|
||||||
typedef struct Vstr Vstr;
|
typedef struct Vstr Vstr;
|
||||||
|
|
||||||
@ -16,6 +16,10 @@ typedef struct Vstr Vstr;
|
|||||||
#define VSTR(cstr) vstr_n(cstr, sizeof(cstr) - 1)
|
#define VSTR(cstr) vstr_n(cstr, sizeof(cstr) - 1)
|
||||||
#define VSTR_NULL vstr_n(NULL, 0)
|
#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_s(const char *s);
|
||||||
Vstr vstr_n(const char *s, size_t n);
|
Vstr vstr_n(const char *s, size_t n);
|
||||||
bool vstr_cmp(const Vstr v1, const Vstr v2);
|
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(Vstr v);
|
||||||
Vstr vstr_trim_left(Vstr v);
|
Vstr vstr_trim_left(Vstr v);
|
||||||
Vstr vstr_trim_right(Vstr v);
|
Vstr vstr_trim_right(Vstr v);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
115
src/vstr.c
115
src/vstr.c
@ -1,11 +1,122 @@
|
|||||||
#include "../include/vstr.h"
|
#include "../include/vstr.h"
|
||||||
#include <stdlib.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 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;
|
return v;
|
||||||
}
|
}
|
||||||
Vstr vstr_n(const char *s, size_t n){
|
Vstr vstr_n(const char *s, size_t n){
|
||||||
Vstr v = {(char *)s, n};
|
Vstr v = {n,(char *)s};
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
bool vstr_cmp(const Vstr v1, const Vstr v2){
|
bool vstr_cmp(const Vstr v1, const Vstr v2){
|
||||||
|
@ -39,7 +39,45 @@ int main(void){
|
|||||||
TEST(vstr_cmp(b,bc) == 0);
|
TEST(vstr_cmp(b,bc) == 0);
|
||||||
TEST(vstr_cmp(a,ac) == 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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user