Basically, what this function should do is encode an arbitrary set of data in memory to a series of bytes that starts with 0x02
, ends with 0x03
, and encodes each instance of 0x02
, 0x03
, or 0x25
by preceding it with 0x25
. It does this to make it safe for stream transmission, for example, a TCP socket. It returns a non-null-terminated array of char
allocated with malloc
(and therefore must be free
d by the caller) and the length of the new array.
size_t encodedata(char** outdata, const void* data, size_t size)
{
const char* dchr = data;
size_t n = 2;
for (size_t i = 0; i < size; i++)
n += dchr[i] == 0x02 ? 2 : dchr[i] == 0x03 ? 2 : dchr[i] == 0x25 ? 2 : 1;
char* encdata = malloc(n);
encdata[0] = 0x02;
encdata[n-1] = 0x03;
for (size_t i = 0, j = 1; i < size && j < (n - 1); i++) {
if (dchr[i] == 0x02 || dchr[i] == 0x03 || dchr[i] == 0x25)
encdata[j++] = 0x25;
encdata[j++] = dchr[i];
}
*outdata = encdata;
return n;
}
The main
function, which tests encodedata
, runs without problems:
int main(int argc, char* argv[])
{
char* out;
char* in = "1" "\x02" "%" "\x03" "3";
size_t n = encodedata(&out, in, 6);
printf("size: %d\n", n);
for (size_t i = 0; i < n; ++i)
printf("%x ", out[i]);
printf("\n");
assert(n == 11);
assert(out[0] == 0x02);
assert(out[1] == '1');
assert(out[2] == 0x25);
assert(out[3] == 0x02);
assert(out[4] == 0x25);
assert(out[5] == 0x25);
assert(out[6] == 0x25);
assert(out[7] == 0x03);
assert(out[8] == '3');
assert(out[9] == 0x00);
assert(out[10] == 0x03);
free(out);
}