struct icon indicating copy to clipboard operation
struct copied to clipboard

is it possible to unpack strings in place ?

Open hugoc7 opened this issue 4 years ago • 2 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.

hugoc7 avatar Nov 28 '21 13:11 hugoc7

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.

svperbeast avatar Nov 29 '21 00:11 svperbeast

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?

hugoc7 avatar Nov 30 '21 17:11 hugoc7

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;

svperbeast avatar Feb 10 '23 06:02 svperbeast