in watchman/bser.cpp [523:603]
static json_ref bunser_template(
const char* buf,
const char* end,
json_int_t* used,
json_error_t* jerr) {
json_int_t needed = 0;
json_int_t total = 0;
json_int_t i, nelems;
json_int_t ip, np;
buf++;
total++;
if (*buf != BSER_ARRAY) {
snprintf(
jerr->text,
sizeof(jerr->text),
"Expected array encoding, but found 0x%02x",
*buf);
*used = total;
return nullptr;
}
// Load in the property names template
auto templ = bunser_array(buf, end, &needed, jerr);
if (!templ) {
*used = needed + total;
return nullptr;
}
total += needed;
buf += needed;
// And the number of objects
needed = 0;
if (!bunser_int(buf, end - buf, &needed, &nelems)) {
*used = needed + total;
snprintf(
jerr->text,
sizeof(jerr->text),
"invalid object number encoding (needed %d but have %d)",
(int)needed,
(int)(end - buf));
return nullptr;
}
total += needed;
buf += needed;
np = json_array_size(templ);
// Now load up the array with object values
auto arrval = json_array_of_size((size_t)nelems);
for (i = 0; i < nelems; i++) {
auto item = json_object_of_size((size_t)np);
for (ip = 0; ip < np; ip++) {
if (*buf == BSER_SKIP) {
buf++;
total++;
continue;
}
needed = 0;
auto val = bunser(buf, end, &needed, jerr);
if (!val) {
*used = needed + total;
return nullptr;
}
buf += needed;
total += needed;
json_object_set_new_nocheck(
item,
json_string_value(json_array_get(templ, (size_t)ip)),
std::move(val));
}
json_array_append_new(arrval, std::move(item));
}
*used = total;
return arrval;
}