A
Alfonso Morra
Hi,
I am at the end of my tether now - after spending several days trying to
figure how to do this. I have finally written a simple "proof of
concept" program to test serializing a structure containing pointers
into a "flattened" bit stream.
Here is my code (it dosen't work - compiles fine, pack appears to work,
but unpack retrieves jibberish and causes program to crash).
I would be grateful for any feedback that helps fix this. My intention
is to build on this example, and use the ideas here, to be able to
persist any data structure (I'll write different pack/unpack routines
for different data stuctures, just to keep things simple). Anyway,
here's the code:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
typedef struct {
int l ;
double d ;
char* s; /* Null terminated string */
} MyStruct ;
void * pack(size_t *size, MyStruct* m);
MyStruct *unpack(void* block);
int main(int argc, char* argv[]) {
MyStruct *in = (MyStruct*)malloc(sizeof(*in)), *out = NULL;
unsigned char *memblock = NULL ;
size_t size ;
in->l = 1000 ;
in->d = 3.142857;
in->s = strdup("Simple Text" ); /*did I need to strdup? */
memblock = (unsigned char*)pack(&size, in) ;
out = unpack(memblock) ;
printf("Int member has value : %d (expected : %d)", out->l, in->l ) ;
printf("Double member has value : %f (expected : %f)", out->d,
in->d ) ;
printf("Int member has value : %s (expected : %s)", out->s, in->s ) ;
free(in->s) ;
free(in) ;
free(out->s) ;
free(out) ;
}
void * pack(size_t *size, MyStruct* m) {
unsigned char *buff = NULL ;
size_t len, length ;
length = strlen(m->s) ;
len = sizeof(int) + sizeof(double) + sizeof(size_t) +
(length+1)*sizeof(char) ;
buff = (unsigned char*)malloc(len) ;
/*copy int*/
memmove(buff, &(m->l), sizeof(int)) ;
/*copy double*/
memmove(buff + sizeof(int), &(m->d), sizeof(double)) ;
/*store length of string*/
memmove(buff + sizeof(int) + sizeof(int), &length, sizeof(size_t));
/*copy string*/
memmove(buff + sizeof(int) + sizeof(double), m->s,
(strlen(m->s)+1)*sizeof(char)) ;
*size = len ;
return buff ;
}
MyStruct *unpack(void* block) {
int l, len ;
double d ;
char * s = NULL ;
MyStruct *p = NULL ;
/* get int*/
memcpy(&l, block, sizeof(int)) ;
/* get double*/
memcpy(&d, (unsigned char*)block + sizeof(int), sizeof(double)) ;
/* get string length*/
memcpy(&len, (unsigned char*)block + sizeof(int) + sizeof(double),
sizeof(size_t)) ;
/* get string*/
s = (char*)malloc(len+1) ;
memcpy(s,(unsigned char*)block + sizeof(int) + sizeof(double)+
sizeof(size_t),len) ;
p = (MyStruct*)malloc(sizeof(*p)) ;
p->l = l ;
p->d = d ;
p->s = s ;
/* free resource */
free(block) ;
block = NULL ;
return p ;
}
I am at the end of my tether now - after spending several days trying to
figure how to do this. I have finally written a simple "proof of
concept" program to test serializing a structure containing pointers
into a "flattened" bit stream.
Here is my code (it dosen't work - compiles fine, pack appears to work,
but unpack retrieves jibberish and causes program to crash).
I would be grateful for any feedback that helps fix this. My intention
is to build on this example, and use the ideas here, to be able to
persist any data structure (I'll write different pack/unpack routines
for different data stuctures, just to keep things simple). Anyway,
here's the code:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
typedef struct {
int l ;
double d ;
char* s; /* Null terminated string */
} MyStruct ;
void * pack(size_t *size, MyStruct* m);
MyStruct *unpack(void* block);
int main(int argc, char* argv[]) {
MyStruct *in = (MyStruct*)malloc(sizeof(*in)), *out = NULL;
unsigned char *memblock = NULL ;
size_t size ;
in->l = 1000 ;
in->d = 3.142857;
in->s = strdup("Simple Text" ); /*did I need to strdup? */
memblock = (unsigned char*)pack(&size, in) ;
out = unpack(memblock) ;
printf("Int member has value : %d (expected : %d)", out->l, in->l ) ;
printf("Double member has value : %f (expected : %f)", out->d,
in->d ) ;
printf("Int member has value : %s (expected : %s)", out->s, in->s ) ;
free(in->s) ;
free(in) ;
free(out->s) ;
free(out) ;
}
void * pack(size_t *size, MyStruct* m) {
unsigned char *buff = NULL ;
size_t len, length ;
length = strlen(m->s) ;
len = sizeof(int) + sizeof(double) + sizeof(size_t) +
(length+1)*sizeof(char) ;
buff = (unsigned char*)malloc(len) ;
/*copy int*/
memmove(buff, &(m->l), sizeof(int)) ;
/*copy double*/
memmove(buff + sizeof(int), &(m->d), sizeof(double)) ;
/*store length of string*/
memmove(buff + sizeof(int) + sizeof(int), &length, sizeof(size_t));
/*copy string*/
memmove(buff + sizeof(int) + sizeof(double), m->s,
(strlen(m->s)+1)*sizeof(char)) ;
*size = len ;
return buff ;
}
MyStruct *unpack(void* block) {
int l, len ;
double d ;
char * s = NULL ;
MyStruct *p = NULL ;
/* get int*/
memcpy(&l, block, sizeof(int)) ;
/* get double*/
memcpy(&d, (unsigned char*)block + sizeof(int), sizeof(double)) ;
/* get string length*/
memcpy(&len, (unsigned char*)block + sizeof(int) + sizeof(double),
sizeof(size_t)) ;
/* get string*/
s = (char*)malloc(len+1) ;
memcpy(s,(unsigned char*)block + sizeof(int) + sizeof(double)+
sizeof(size_t),len) ;
p = (MyStruct*)malloc(sizeof(*p)) ;
p->l = l ;
p->d = d ;
p->s = s ;
/* free resource */
free(block) ;
block = NULL ;
return p ;
}