0

I'm strying to serialize a structure in byte-streams. Basically, I've to work with a structure of this type:

typedef struct { 
   unsigned a, b;
   unsigned c, d;
} struct_t;

I've to convert the elements of this structure into the characters of a string. For example, I'm given the following:

struct_t *structure; /* pointer to the structure due to be converted */
char *s; /* array of char where to write the string result of the conversion */
int len; /* lenght of the array s */

I'm having some issues understanding how to do so through serialization. Thanks in advance for any help.

8
  • It seems you need to convert the contents of the struct into a printable string. Come up with a format and use snprintf to write the string. Commented Nov 27, 2017 at 16:04
  • Where is the serialized data going to be used? How much flexibility do you want? There are endless possibilities — and they're mostly pretty simple. Do you need to mark the start and end? snprintf(buf, len, "[%u,%u,%u,%u]", structure->a, structure->b, structure->c, structure->d) might be sufficient (if you check that the output was not truncated — capture and test the return value from snprintf()). Commented Nov 27, 2017 at 16:07
  • wikipedia did a good job explaining serialization. Nowadays I would get away from XML, and rather use a JSON library (pros/cons discussed everywhere on the web). Commented Nov 27, 2017 at 16:08
  • Beware of serializing simply by casting it to a byte pointer. You can run into endianness issues if you end up reading data back in on a system with a different endianness. Commented Nov 27, 2017 at 16:09
  • What I've to do is implement a function which heading is the following: char * struct_to_string (struct_t* structure, char* s, int len); This function creates the representation of the structure as a string. \retval must be s if the conversion has been successful, otherwise \retval must be NULL. I'm working on a project which requires both the conversion of a string (call it string[i]) into a structure (done, it's working fine) and then again the conversion of this structure into a new string, which obviously will be basically the same of string[i]. Commented Nov 27, 2017 at 16:14

1 Answer 1

2

Given the requirements, it looks as though this could work, as mentioned in my comment:

char *serialize_struct_t(const struct_t structure, char *s, int len)
{
    if (snprintf(s, len, "[%u,%u,%u,%u]", structure->a, structure->b,
                 structure->c, structure->d) < len)
        return s;
    return 0;
}

This produces output such as [23,45,67,90]. Clearly, there are many other possible formats, with blanks as separators and without the beginning or end markers. Any such changes will require consequential changes in the deserialization code shown below.

Assuming that you use the format shown above, you might then deserialize such data using a function like:

int deserialize(const char *buffer, struct_t *structure)
{
    char c;
    int  len;
    if (sscanf(buffer, " [%u ,%u ,%u ,%u %c%n", &structure->a,
               &structure->b, &structure->c, &structure->d, &c, &len) != 5 ||
        c != ']')
        return -1;
    return len;
}

You can debate the details of the interface, but it returns -1 if the string doesn't match the output from serialize_struct_t(), or the length of the string which did match (so you know where to continue searching from). The blanks in the format indicate optional white space; %u skips optional white anyway. The %c allows you to detect something other than a ] at the end; you'd not be able to spot a problem if you used a litera ] in the format string. And the %n tells you the offset where it is matched, which is at the end. The %n conversion isn't counted.

Clearly, depending on the serialization format that's chosen, you will need to alter the deserialization scanner to match.

This is the way serialization and deserialization work — the serialization format (which should be strictly defined) controls what the deserialization code needs to recognize. The deserialization code can be more flexible (you could argue against all the blanks in the format string shown, for example, but that would make the accepted format more rigid), but should certainly recognize anything that the serialization code produces. See Wikipedia on the Robustness Principle, aka Postel's Law.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.