svperbeast/struct

is it possible to unpack strings in place ?

Closed this issue · 3 comments

Is it possible to pack/unpack strings in place (I mean source buffer = destination buffer) ? Like this for example:

 char str[32] = {'\0', };
 char fmt[32] = {'\0', };
 
 strcpy(str, "test");
 sprintf(fmt, "%ds", strlen(str));

 struct_pack(str, fmt, str);
 struct_unpack(str, fmt, str);

In my case I am receiving a character string from a TCP socket in a buffer. Then I have to unpack it, and assign it to a std::string object. So I was wondering if I had to recreate a new buffer or if I could just reuse the one that I had.

Hi, @hugoc7

Yes, it's possible to pack/unpack strings in the same buffer.
In case of using s and p format character, it's like the following:

char buf[] = { ... };

char *src = buf;
char *dst = buf;

for (int i = 0; i < sizeof(buf); i++) {
    *dst++ = src[i];
}

I added a test case:

TEST_F(Struct, PackUnpackingStringUsingSameBuffer)
{
       char str[32];
       char fmt[32];

       memset(str, 0, sizeof(str));
       memset(fmt, 0, sizeof(fmt));

       strcpy(str, "test");
       snprintf(fmt, sizeof(fmt), "%ds", (int)strlen(str));
       // checking the result of snprintf() omitted..

       struct_pack(str, fmt, str);
       struct_unpack(str, fmt, str);
       EXPECT_STREQ(str, "test");
}

If you run into any issues, please let me know.

Ok thanks! And by the way, is it useful to pack/unpack 8-bits unsigned char (B) ? It seems that there no work done in that case?

Hi @hugoc7
sorry for the late reply.
you're right, no work is done practically.
all bits of unsigned char and char are the same but interpretation is different ('b' or 'B').

    char *b;
    unsigned char *B;
...
        case 'b':
            BEGIN_REPETITION();
                b = va_arg(args, char*);
                *b = *bp++;
            END_REPETITION();
            break;
        case 'B':
            BEGIN_REPETITION();
                B = va_arg(args, unsigned char*);
                *B = *bp++;
            END_REPETITION();
            break;