Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over an unknown object in Duktape

Tags:

c++

duktape

So I have this duktape function which accepts an object as one of the parameters. Under normal circumstances, to retrieve the values of each of the objects attributes, I would use duk_get_prop() and duk_push_string(), however this assumes I know beforehand the structure of the object I am getting.

Now, consider a function which accepts an object with an unknown structure. I need to iterate over its keys, and retrieve all of its values.

I am trying to convert such an object to a C++ std::map<string, string> For example, calling from Javascript myFunction({x: 1, y: 3, z: 35}) should work as well as myFunction({foo: 12, bar: 43}).

It seems that duk_enum() would be an appropriate function for this, but I am not quite understanding how it works.

like image 262
Adrien Avatar asked Mar 15 '17 08:03

Adrien


1 Answers

The basic idiom for duk_enum() is:

/* Assume target object to enumerate is at obj_idx.
 * For a function's 1st argument that would be 0.
 */

duk_enum(ctx, 0 /*enum_flags*/);  /* Pushes enumerator object. */
while (duk_next(ctx, -1, 1 /*get_value*/)) {  /* -1 points to enumerator, here top of stack */
    /* Each time duk_enum() finds a new key/value pair, it
     * gets pushed to the value stack.  So here the stack
     * top is [ ... enum key value ].  Enum is at index -3,
     * key at -2, value at -1, all relative to stack top.
     */

    printf("enumerated key '%s', value '%s'\n", duk_safe_to_string(ctx, -2), duk_safe_to_string(ctx, -1));

    /* When you're done with the key/value, pop them off. */
    duk_pop_2(ctx);
}
duk_pop(ctx);  /* Pop enumerator object. */

If you don't want the value to be automatically pushed, pass 0 for "get_value" argument of duk_next(), and pop only the key at the end of the loop.

There are a set of flag to duk_enum() to control what you want to enumerate. 0 corresponds to a "for (var k in obj) { ... }" enumeration.

like image 102
Sami Vaarala Avatar answered Oct 04 '22 18:10

Sami Vaarala