Added packing and unpacking operations

This commit is contained in:
2025-10-18 16:34:13 -05:00
parent 095d98d0ba
commit 644e059aa5
4 changed files with 85 additions and 3 deletions

View File

@@ -28,5 +28,7 @@ extern struct String_View sv_after_delim(const struct String_View sv,
const char *delims);
extern struct String_View sv_str_str(const struct String_View haystack,
const struct String_View needle);
extern size_t sv_pack_size(const struct String_View sv);
extern void sv_pack(unsigned char *buf, const struct String_View sv);
extern struct String_View sv_unpack(unsigned char *buf);
#endif

View File

@@ -1,7 +1,8 @@
#include "../include/sv.h"
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
static bool sv_is_space(int c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
@@ -9,7 +10,26 @@ static bool sv_is_space(int c) {
static int sv_tolc(char c) {
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
}
static void sv_pack_u64(uint64_t i, unsigned char *buf){
*buf++ = i>>56;
*buf++ = i>>48;
*buf++ = i>>40;
*buf++ = i>>32;
*buf++ = i>>24;
*buf++ = i>>16;
*buf++ = i>>8;
*buf++ = i;
}
static uint64_t sv_unpack_u64(unsigned char *buf){
return ((unsigned long long int)buf[0]<<56) |
((unsigned long long int)buf[1]<<48) |
((unsigned long long int)buf[2]<<40) |
((unsigned long long int)buf[3]<<32) |
((unsigned long long int)buf[4]<<24) |
((unsigned long long int)buf[5]<<16) |
((unsigned long long int)buf[6]<<8) |
buf[7];
}
struct String_View sv_str(const char *s) {
struct String_View str = {s == NULL ? 0 : strlen(s), (char *) s };
return str;
@@ -115,3 +135,18 @@ struct String_View sv_str_str(const struct String_View haystack, const struct St
return sv_strn(NULL,0);
}
size_t sv_pack_size(const struct String_View sv){
size_t result = 0;
result += sv.len;
result += sizeof(uint64_t);
return result;
}
void sv_pack(unsigned char *buf, const struct String_View sv){
sv_pack_u64(sv.len, buf);
size_t offset = sizeof(uint64_t);
memcpy(buf+offset, sv.buf, sv.len);
}
struct String_View sv_unpack(unsigned char *buf){
size_t len = sv_unpack_u64(buf);
return sv_strn((const char *)buf+sizeof(uint64_t),len);
}

24
tests/11_sv_pack.c Normal file
View File

@@ -0,0 +1,24 @@
#define DEBUG
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "../include/sv.h"
int main(void){
const char *s = "Hello";
struct String_View sv = sv_strn(s, strlen(s));
size_t offset = sv_pack_size(sv);
unsigned char *buf = malloc(offset);
sv_pack(buf, sv);
struct String_View out = sv_unpack(buf);
assert(out.len == strlen(s));
assert( memcmp(out.buf, s, out.len) == 0);
assert( sv_eq(sv, out));
assert( sv_casecmp(sv, out ) == 0);
free(buf);
return EXIT_SUCCESS;
}

21
tests/12_sv_pack2.c Normal file
View File

@@ -0,0 +1,21 @@
#define DEBUG
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "../include/sv.h"
int main(void){
const char *s = "Hello";
size_t offset = strlen(s) + sizeof(uint64_t);
unsigned char *buf = malloc(offset);
struct String_View sv = sv_strn(s, strlen(s));
sv_pack(buf, sv);
struct String_View out = sv_unpack(buf);
assert(out.len == strlen(s));
assert( memcmp(out.buf, s, out.len) == 0);
free(buf);
return EXIT_SUCCESS;
}