[quickjs-devel] Re: How to iterate an object in c++ code?

  • From: Guido Grassel <guido.grassel@xxxxxxxxxx>
  • To: "quickjs-devel@xxxxxxxxxxxxx" <quickjs-devel@xxxxxxxxxxxxx>
  • Date: Fri, 3 Jan 2020 14:37:35 +0000



Hi!

Lets say you have your own JS function called foo(x).
You implement this function in C. 

JSValue js_foo(JSContext *ctx, JSValueConst this_val,
                                 int argc, JSValueConst *argv) 

parameter 'x' from JS will be argv[0] and of type JSValue
Checkout the struct JSValue in the QJS sources ....

JSValue can be of type Bool, Number, Object, Array, etc.
To work with the value of x you want to convert argv[0] from JSValue 
to 'normal' C data types.  I give some hints how to do this below:

Converting Strings use JS_ToCString(), for Numbers use JS_ToInt32()

Converting an object / map can be done like this
I make the blunt assumption that values (jsVal) are all of type string

                JSValue jsLen = JS_GetArrayLength(ctx, jsArray);  // from 
quickjs.c
        int arrayLen;
        JS_ToInt32(ctx, &arrayLen, jsLen);
        JS_FreeValue(ctx, jsLen);

        // read out the array of string key - value pairs
        int i = 0;
        while (i + 1 < arrayLen) {
            JSValue jsKey = JS_GetPropertyUint32(ctx, jsArray, i++);
            JSValue jsVal = JS_GetPropertyUint32(ctx, jsArray, i++);
            if (JS_IsString(jsKey) && JS_IsString(jsVal)) {
                const char *keyS = JS_ToCString(ctx, jsKey);
                const char *valS = JS_ToCString(ctx, jsVal);

                                // do something with the data

                JS_FreeCString(ctx, keyS);
                JS_FreeCString(ctx, valS);
            }
            JS_FreeValue(ctx, jsKey);
            JS_FreeValue(ctx, jsVal);
        }


Converting an Array works similar:

                JSValue jsArrayLen = JS_GetArrayLength(ctx, jsDataArray)
                int arrayLen;
        JS_ToInt32(ctx, &arrayLen, jsArrayLen);
        JS_FreeValue(ctx, jsArrayLen);

                for (int i = 0; i < arrayLen; i++) {
            // the i-th element in the data array
            JSValue jsArrayElement = JS_GetPropertyUint32(ctx, jsDataArray, i);

                        // convert jsArrayElement to C data structure and use it

            JS_FreeValue(ctx, jsArrayElement);
                }
        JS_FreeValue(ctx, jsDataArray);


Hope this helps (a little bit). 
When I started, I had very similar questions as you asked. Unfortunately, QJS 
documentation could not help me.
I found reading quickjs-libc.c sources educational

- Guido

-----Original Message-----
From: quickjs-devel-bounce@xxxxxxxxxxxxx 
[mailto:quickjs-devel-bounce@xxxxxxxxxxxxx] On Behalf Of Vladimir Timofeev
Sent: 03 January 2020 13:20
To: quickjs-devel@xxxxxxxxxxxxx
Subject: [quickjs-devel] Re: How to iterate an object in c++ code?

Hi!

Did you try to use JS_GetOwnPropertyNames?

On Fri, Jan 3, 2020 at 12:16 PM sineysan <sineysan@xxxxxxx> wrote:



Thanks reply.

I pass a JS object from js to c, how I iterate all keys from the object in c 
side?
I have tried to call JS_GetIterator(ctx, val), "val" is the object passed 
from script, but got an error "value is not iterable".


At 2020-01-03 16:46:20, "Guido Grassel" <guido.grassel@xxxxxxxxxx> wrote:

Hi!



If this is a string that is JSON encoded, you first need to decode the string 
to get JS objects (JSValue)  that you can then read / write from C.

Use JS_ParseJson(..)



If you already have JS objects, you need to check their type first (functions 
JS_IsNumber/String,/Object/Array), then read out (convert to C types) number, 
string, bool, Array, and Object separately.



To my knowledge there is no function that would do all of this in one go.



-         Guido





From: quickjs-devel-bounce@xxxxxxxxxxxxx 
[mailto:quickjs-devel-bounce@xxxxxxxxxxxxx] On Behalf Of sineysan
Sent: 03 January 2020 08:34
To: quickjs-devel@xxxxxxxxxxxxx
Subject: [quickjs-devel] How to iterate an object in c++ code?



Hello:



I want to iterate a Json object in c++ code, how to do this? I can't find any 
API for this purpose.











-- 
Vladimir Timofeev <vovkasm@xxxxxxxxx>

Other related posts: