Как проанализировать рекурсивные данные JSON в Duktape?

Я пытаюсь проанализировать рекурсивную структуру данных с помощью duktape и, похоже, где-то произошла ошибка.
Так как я новичок в библиотеке duktape и примеры не ясны в этой ситуации, я подумал, что могу спросить толпу.

Данные:

{
"type": "window",
"children": [
{
"type": "button"},
{
"type": "button"}
]
}

С функциями, используемыми для его анализа:

void parse_config() {
duk_context* context = duk_create_heap_default();
std::cout << "duk_create_heap_default" << std::endl;
duk_push_string(context, input.c_str());
std::cout << "duk_push_string" << std::endl;
duk_json_decode(context, 0);
std::cout << "duk_json_decode" << std::endl;
parse_widget(context);
}

void parse_widget(duk_context* context) {
duk_get_prop_string(context, 0, "type");
std::cout << "duk_get_prop_string" << std::endl;
auto type = duk_get_string(context, 1);
std::cout << "duk_get_string" << std::endl;
duk_pop(context);
std::cout << "duk_pop" << std::endl;
std::cout << "type: " << type << std::endl;
if (duk_has_prop_string(context, 0, "children")) {
std::cout << "duk_has_prop_string" << std::endl;
parse_children(context);
} else {
std::cout << "duk_has_prop_string" << std::endl;
std::cout << "no children" << std::endl;
}
}

void parse_children(duk_context* context) {
duk_get_prop_string(context, 0, "children");
std::cout << "duk_get_prop_string" << std::endl;
if (duk_is_array(context, 1)) {
std::cout << "duk_is_array" << std::endl;
duk_enum(context, 1, 0);
std::cout << "duk_enum" << std::endl;
while (duk_next(context, 2, 0)) {
std::cout << "duk_next" << std::endl;
std::cout << "parse child" << std::endl;
parse_widget(context);
}
}
}

С этой версией я получаю вывод:

$ ./programm
duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: $

Правильный вывод, конечно, должен быть:

duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children

Таким образом, остается вопрос: где моя ошибка в разборе данных?

1

Решение

Я вижу две проблемы:

  • Вы используете индексы стека значений 0 и 1 в parse_widget / parse_children, которые будут неверны после повторного выполнения. Обратите внимание, что индекс стека 0 не изменяется, когда вы выполняете обычные вызовы функций C (но изменяется, когда вы вызываете функцию native / Ecmascript, используя, например, duk_call()). Вы должны использовать отрицательные индексы для ссылки на элементы относительно вершины стека; Вы также можете использовать неотрицательные индексы, но отслеживать базовый индекс для текущего обрабатываемого виджета.

  • Есть duk_pop() отсутствует для дочернего массива, а также для перечислимого ключа и значения в duk_next() петля.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]