im trying to make my own Serialization library but I have some problems with the following.

I have a package wich I serialize to a t_stream and then I need to serialize the t_stream to a
char * again. This is the complete code:

    typedef struct{
        int16_t port;
        int16_t priority;
        char * ip;
        char * code;
    }__attribute__((__packed__)) t_file_package;

    typedef struct {
        int8_t packageType;
        int32_t length;
        char *data;
    }__attribute__((__packed__)) t_stream;


    //
    t_stream * package_file_serializer(t_file_package *self)
    {
        char *data = malloc(  strlen(self->ip) + 1 + sizeof(int16_t) + sizeof(int16_t) + strlen(self->code)  + 1);
        t_stream *stream = malloc(sizeof(t_stream));
        int32_t offset = 0 , tmp_size = 0;


        memcpy(data + offset, &self->port, tmp_size = sizeof(int16_t));

        offset = tmp_size;
        memcpy(data + offset, &self->priority, tmp_size = sizeof(int16_t));

        offset += tmp_size;
        memcpy(data + offset , self->ip , tmp_size = strlen(self->ip)+1);

        offset += tmp_size;
        memcpy(data + offset , self->code , tmp_size = strlen(self->code)+1);
        stream->packageType = 1;
        stream->length = offset + tmp_size;
        stream->data = data;

        return stream;
    }


    t_file_package * package_file_deserializer(t_stream *stream)
    {
        t_file_package *self = malloc(sizeof(t_file_package));
        int32_t offset = 0, tmp_size = 0;


        memcpy(&self->port, stream->data + offset, tmp_size = sizeof(int16_t));

        offset = tmp_size;
        memcpy(&self->priority, stream->data + offset, tmp_size = sizeof(int16_t));

        offset += tmp_size;
        for(tmp_size = 1 ; (stream->data + offset)[tmp_size - 1] != '\0'; tmp_size++);
        self->ip = malloc(tmp_size);
        memcpy(self->ip, stream->data + offset, tmp_size);

        offset += tmp_size;
        for(tmp_size = 1 ; (stream->data + offset)[tmp_size - 1] != '\0'; tmp_size++);
        self->code = malloc(tmp_size);
        memcpy(self->code, stream->data + offset, tmp_size);

        return self;
    }


    char * stream_serializer (t_stream *self)
    {
        char *buffer= malloc(strlen(self->data)+1+sizeof(int8_t)+sizeof(int32_t));
        int32_t offset = 0 , tmp_size = 0;

        memcpy(buffer + offset,&self->packageType,tmp_size = sizeof(int8_t));

        offset = tmp_size;
        memcpy(buffer + offset,&self->length,tmp_size = sizeof(int32_t));

        offset += tmp_size;
        memcpy(buffer + offset,self->data,tmp_size = strlen(self->data)+1);

        return buffer;}

    t_stream * stream_deserializer (char * self)
    {
        t_stream *stream = malloc(sizeof(t_stream));
        int32_t offset = 0, tmp_size = 0;


        memcpy(&stream->packageType, self + offset, tmp_size = sizeof(int8_t));

        offset =tmp_size;
        memcpy(&stream->length,self + offset, tmp_size = sizeof(int32_t));

        offset +=tmp_size;
        for(tmp_size = 1 ; (self + offset)[tmp_size - 1] != '\0' ; tmp_size++);
        stream->data=malloc(tmp_size);
        memcpy(stream->data, self + offset, tmp_size);

        return stream;
    }



    void free_package_file (t_file_package *self)
    {
        free(self->ip);
        free(self->code);
        free(self);
    }

    void free_stream (t_stream *self)
    {
        free(self->data);
        free(self);
    }

    void free_buffer(char * self)
    {
        free(self);
    }


    t_file_package * create_package_file ( int16_t port,int16_t priority,char * ip, char *code)
    {
        t_file_package *paq = malloc(sizeof(t_file_package));

        paq->priority = port;
        paq->port =priority;
        paq->ip = malloc(strlen(ip)+1);
        strcpy(paq->ip,ip);
        paq->code = malloc(strlen(code)+1);
        strcpy(paq->code,code);
        return paq;
    }



    int main(void) {

                t_file_package *p1 = create_package_file(23,1,"1.2.3.4.2","SOME NICE CODE");
                t_file_package *p2;
                t_stream *stream,*stream2;
                char * sStream;

                stream = package_file_serializer(p1);
                sStream = stream_serializer(stream);
                stream2 = stream_deserializer(sStream);
                p2 = package_file_deserializer(stream2);


                assert(p1->port==p2->port);
                assert(p1->priority==p2->priority);
                assert(strcmp(p1->code,p2->code)==0);
                assert(strcmp(p1->ip,p2->ip)==0);

                free_package_file(p1);
                free_package_file(p2);
                free_stream(stream);


                return 0;

    }

I know that the problem is with the second serialization...

 stream = package_file_serializer(p1);
 sStream = stream_serializer(stream);
 stream2 = stream_deserializer(sStream);
 p2 = package_file_deserializer(stream2);

Because if you change that line to this ones it works perfect:

  stream = package_file_serializer(p1);
  p2 = package_file_deserializer(stream);

Id been for hours looking for the problem but i cant still find it...

Any ideas!?

Thanx in advanced!!!

You have to be really careful when treating strings as raw memory and vice versa because raw memory can have legit embedded null characters. The problem you're having is basically you stop processing on a null when you should keep going. I made a few changes that fix your problem. Compare and contrast to see what I did and try to figure out why I did it:

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef struct{
    int16_t port;
    int16_t priority;
    char * ip;
    char * code;
}  t_file_package;

typedef struct {
    int8_t packageType;
    int32_t length;
    char *data;
}  t_stream;

t_stream * package_file_serializer(t_file_package *self)
{
    t_stream *stream = malloc(sizeof(t_stream));
    int32_t offset = 0 , tmp_size = 0;

    stream->data = malloc(strlen(self->ip) + 1 + sizeof(int16_t) + sizeof(int16_t) + strlen(self->code) + 1);

    memcpy(stream->data + offset, &self->port, tmp_size = sizeof(int16_t));

    offset = tmp_size;
    memcpy(stream->data + offset, &self->priority, tmp_size = sizeof(int16_t));

    offset += tmp_size;
    memcpy(stream->data + offset , self->ip , tmp_size = strlen(self->ip)+1);

    offset += tmp_size;
    memcpy(stream->data + offset , self->code , tmp_size = strlen(self->code)+1);

    stream->packageType = 1;
    stream->length = offset + tmp_size;

    return stream;
}

t_file_package * package_file_deserializer(t_stream *stream)
{
    t_file_package *self = malloc(sizeof(t_file_package));
    int32_t offset = 0, tmp_size = 0;

    memcpy(&self->port, stream->data + offset, tmp_size = sizeof(int16_t));

    offset = tmp_size;
    memcpy(&self->priority, stream->data + offset, tmp_size = sizeof(int16_t));

    offset += tmp_size;
    tmp_size = strlen(stream->data + offset) + 1;
    self->ip = malloc(tmp_size);
    memcpy(self->ip, stream->data + offset, tmp_size);

    offset += tmp_size;
    tmp_size = strlen(stream->data + offset) + 1;
    self->code = malloc(tmp_size);
    memcpy(self->code, stream->data + offset, tmp_size);

    return self;
}

char * stream_serializer (t_stream *self)
{
    char *buffer= malloc(self->length+sizeof(int8_t)+sizeof(int32_t));
    int32_t offset = 0 , tmp_size = 0;

    memcpy(buffer + offset,&self->packageType,tmp_size = sizeof(int8_t));

    offset = tmp_size;
    memcpy(buffer + offset,&self->length,tmp_size = sizeof(int32_t));

    offset += tmp_size;
    memcpy(buffer + offset,self->data,tmp_size = self->length);

    return buffer;
}

t_stream * stream_deserializer (char * self)
{
    t_stream *stream = malloc(sizeof(t_stream));
    int32_t offset = 0, tmp_size = 0;

    memcpy(&stream->packageType, self + offset, tmp_size = sizeof(int8_t));

    offset =tmp_size;
    memcpy(&stream->length,self + offset, tmp_size = sizeof(int32_t));

    offset += tmp_size;
    stream->data = malloc(stream->length);
    memcpy(stream->data, self + offset, stream->length);

    return stream;
}

void free_package_file (t_file_package *self)
{
    free(self->ip);
    free(self->code);
    free(self);
}

void free_stream (t_stream *self)
{
    free(self->data);
    free(self);
}

void free_buffer(char * self)
{
    free(self);
}

t_file_package * create_package_file ( int16_t port,int16_t priority,char * ip, char *code)
{
    t_file_package *paq = malloc(sizeof(t_file_package));

    paq->priority = port;
    paq->port =priority;
    paq->ip = malloc(strlen(ip)+1);
    strcpy(paq->ip,ip);
    paq->code = malloc(strlen(code)+1);
    strcpy(paq->code,code);
    return paq;
}

int main(void) {

    t_file_package *p1 = create_package_file(23,1,"1.2.3.4.2","SOME NICE CODE");
    t_file_package *p2;
    t_stream *stream,*stream2;
    char * sStream;

    stream = package_file_serializer(p1);
    sStream = stream_serializer(stream);
    stream2 = stream_deserializer(sStream);
    p2 = package_file_deserializer(stream2);

    assert(p1->port==p2->port);
    assert(p1->priority==p2->priority);
    assert(strcmp(p1->code,p2->code)==0);
    assert(strcmp(p1->ip,p2->ip)==0);

    free_package_file(p1);
    free_package_file(p2);
    free_stream(stream);

    return 0;
}
This article has been dead for over six months. Start a new discussion instead.