1 /* This program parses an input string in a format a bit like JSON:
2 * {'foobar': 1234, 'xyz': 'abc', 'tree': [[[1, 2], 3], [4, 5]]}
3 * and encodes it as protobuf
5 * Note: The string parsing here is not in any way intended to be robust
6 * nor safe against buffer overflows. It is just for this test.
13 #include "cyclic_callback.pb.h"
15 static char *find_end_of_item(char *p)
19 if (*p == '[' || *p == '{') depth++;
20 if (*p == ']' || *p == '}') depth--;
22 } while (depth > 0 || (*p != ',' && *p != '}'));
25 return p; /* End of parent dict */
28 while (*p == ' ') p++;
32 /* Parse a tree in format [[1 2] 3] and encode it directly to protobuf */
33 static bool encode_tree(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
35 TreeNode tree = TreeNode_init_zero;
36 char *p = (char*)*arg;
40 /* This is a tree branch */
42 tree.left.funcs.encode = encode_tree;
45 p = find_end_of_item(p);
46 tree.right.funcs.encode = encode_tree;
51 /* This is a leaf node */
56 return pb_encode_tag_for_field(stream, field) &&
57 pb_encode_submessage(stream, TreeNode_fields, &tree);
60 /* Parse a dictionary in format {'name': value} and encode it directly to protobuf */
61 static bool encode_dictionary(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
64 char *p = (char*)*arg;
68 KeyValuePair pair = KeyValuePair_init_zero;
71 PB_RETURN_ERROR(stream, "invalid key, missing quote");
73 p++; /* Starting quote of key */
74 textlen = strchr(p, '\'') - p;
75 strncpy(pair.key, p, textlen);
76 pair.key[textlen] = 0;
79 while (*p == ' ') p++;
84 pair.treeValue.funcs.encode = encode_tree;
85 pair.treeValue.arg = p;
89 /* Value is a string */
90 pair.has_stringValue = true;
92 textlen = strchr(p, '\'') - p;
93 strncpy(pair.stringValue, p, textlen);
94 pair.stringValue[textlen] = 0;
98 /* Value is a dictionary */
99 pair.has_dictValue = true;
100 pair.dictValue.dictItem.funcs.encode = encode_dictionary;
101 pair.dictValue.dictItem.arg = p;
105 /* Value is integer */
106 pair.has_intValue = true;
107 pair.intValue = atoi(p);
110 p = find_end_of_item(p);
112 if (!pb_encode_tag_for_field(stream, field))
115 if (!pb_encode_submessage(stream, KeyValuePair_fields, &pair))
123 int main(int argc, char *argv[])
126 pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
127 Dictionary dict = Dictionary_init_zero;
131 fprintf(stderr, "Usage: %s \"{'foobar': 1234, ...}\"\n", argv[0]);
135 dict.dictItem.funcs.encode = encode_dictionary;
136 dict.dictItem.arg = argv[1];
138 if (!pb_encode(&stream, Dictionary_fields, &dict))
140 fprintf(stderr, "Encoding error: %s\n", PB_GET_ERROR(&stream));
144 fwrite(buffer, 1, stream.bytes_written, stdout);