Originally Posted by
apsync
Thank you for the responses, I can work further now I guess, if not, I will post my questions here.
The 'd' stands for dictionaries, you can find more info
here
I'd still go with sscanf, but that's me. For example a byte string and an integer could be done this way:
Code:
int bt_bytestring(const char **text)
{
int size, n;
if ( sscanf(*text, "%d:%n", &size, &n) == 1 )
{
*text += n;
printf("\"%.*s\"", size, *text);
*text += size;
return 1;
}
return 0;
}
int bt_integer(const char **text)
{
int value, n;
if ( sscanf(*text, "i%de%n", &value, &n) == 1 )
{
*text += n;
printf("%d", value);
return 1;
}
return 0;
}
These could be called by some overall function that looks at the current location in a string.
Code:
int process(const char **text)
{
return bt_bytestring (text) ||
bt_integer (text) ||
bt_list (text) ||
bt_dictionary (text);
}
The list and the dictionary are a bit more troublesome, but they are based on the previous.
Code:
int bt_list(const char **text)
{
if ( **text == 'l' )
{
fputs("[ ", stdout);
++*text;
while ( process(text) )
{
if ( **text == 'e' )
{
fputs(" ]", stdout);
++*text;
return 1;
}
fputs(", ", stdout);
}
}
return 0;
}
int bt_dict(const char **text)
{
if ( !process(text) )
{
return 0;
}
fputs(" => ", stdout);
if ( !process(text) )
{
return 0;
}
return 1;
}
int bt_dictionary(const char **text)
{
if ( **text != 'd' )
{
return 0;
}
fputs("{ ", stdout);
++*text;
while ( bt_dict(text) && **text != 'e' )
{
fputs(", ", stdout);
}
fputs(" }", stdout);
++*text;
return 1;
}
But a little test might look like this.
Code:
int main(void)
{
static const char *text[] =
{
"4:spam",
"i3e",
"l4:spam4:eggse",
"d3:cow3:moo4:spam4:eggse",
"d4:spaml1:a1:bee",
};
size_t i;
for ( i = 0; i < sizeof text / sizeof *text; ++i )
{
printf("\"%s\" : ", text[i]);
if ( !process(&text[i]) )
{
fputs("bad format", stdout);
}
putchar('\n');
}
return 0;
}
/* my output
"4:spam" : "spam"
"i3e" : 3
"l4:spam4:eggse" : [ "spam", "eggs" ]
"d3:cow3:moo4:spam4:eggse" : { "cow" => "moo", "spam" => "eggs" }
"d4:spaml1:a1:bee" : { "spam" => [ "a", "b" ] }
*/