Does V8 has methods to parse json in c++.

2,145 views
Skip to first unread message

Guilherme Silva

unread,
Jun 9, 2012, 3:57:59 PM6/9/12
to v8-u...@googlegroups.com
Hi.

Does v8 has an function that can parse a json file to an object like an Handle<Value>?

Thanks ;).

Chris Jimison

unread,
Jun 9, 2012, 6:56:28 PM6/9/12
to v8-u...@googlegroups.com
No, but it is pretty easy to add one.

In <src> json-parse.h there is a method that is called to parse a V8
string and return a V8 handle. You would have to do the following:

1) Load the file contents into a v8 string
2) Add a function (object method) in v8.h in the includes to take in
your string and return the handle
3) Modify <src> api.cc that looks something like this (note this
method assumes you have opened a scope external to this call):

handle<object> NAME_OF_YOUR_FUNCTION(Handle<String> source)
{
Handle<String> sourceFlatten = Handle<String>(source->TryFlattenGetString());
// Optimized fast case where we only have ASCII characters.
Handle<Object> result;
if (sourceFlatten->IsSeqAsciiString()) {
result = JsonParser<true>::Parse(sourceFlatten);
} else {
result = JsonParser<false>::Parse(sourceFlatten);
}
return result;
}

or something to that effect.

Hope that helps.

-Chris
> --
> v8-users mailing list
> v8-u...@googlegroups.com
> http://groups.google.com/group/v8-users

Stephan Beal

unread,
Jun 9, 2012, 7:52:39 PM6/9/12
to v8-u...@googlegroups.com
On Sun, Jun 10, 2012 at 12:56 AM, Chris Jimison <cjim...@gmail.com> wrote:
 Handle<Object> result;
 if (sourceFlatten->IsSeqAsciiString()) {
   result = JsonParser<true>::Parse(sourceFlatten);
 } else {
   result = JsonParser<false>::Parse(sourceFlatten);
 }
 return result;
}

i don't think that code accepts Array input.

Why not just get the "JSON" property from the global scope, Cast() it to an Object, get it's "parse" property, cast it to a Function, and Call() that? 

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

Chris Jimison

unread,
Jun 9, 2012, 11:28:57 PM6/9/12
to v8-u...@googlegroups.com
Responses bellow:

On Sat, Jun 9, 2012 at 4:52 PM, Stephan Beal <sgb...@googlemail.com> wrote:
> On Sun, Jun 10, 2012 at 12:56 AM, Chris Jimison <cjim...@gmail.com> wrote:
>>
>>  Handle<Object> result;
>>  if (sourceFlatten->IsSeqAsciiString()) {
>>    result = JsonParser<true>::Parse(sourceFlatten);
>>  } else {
>>    result = JsonParser<false>::Parse(sourceFlatten);
>>  }
>>  return result;
>> }
>
>
> i don't think that code accepts Array input.

It was just a quick bit of code I pulled out of runtime.cc and meant
more to inform :)

>
> Why not just get the "JSON" property from the global scope, Cast() it to an
> Object, get it's "parse" property, cast it to a Function, and Call() that?

Simplicity always beats complexity, so forget what I suggested. This
is an even better solution.

Michael Schwartz

unread,
Jun 9, 2012, 11:52:14 PM6/9/12
to v8-u...@googlegroups.com
How about the obvious?

Run a script that calls JSON.stringify() on the object/string and returns it. Everything I've seen is that doing the JSON decode in JavaScript context is fastest.

Guilherme Silva

unread,
Jun 10, 2012, 5:30:10 PM6/10/12
to v8-u...@googlegroups.com
Thanks everybody for your replies! I want to create a Script Manager that encapsulates V8 and abstracts both js from json files ;).

Mark Essel

unread,
Jun 20, 2012, 6:49:17 PM6/20/12
to v8-u...@googlegroups.com
Just wanted to say thanks for asking this question Guilherme. I know have access to a straight forward json parser for my native module.
when walking the jsonObject that results from the parsing do you loop over properties to find the keys of interest or is there a rapid/hashlike lookup available?

ie
Handle<Value> parseJson(Handle<Value> jsonString) {
    HandleScope scope;

    Handle<Context> context = Context::GetCurrent();
    Handle<Object> global = context->Global();

    Handle<Object> JSON = global->Get(String::New("JSON"))->ToObject();
    Handle<Function> JSON_parse = Handle<Function>::Cast(JSON->Get(String::New("parse")));

    // return JSON.parse.apply(JSON, jsonString);
    return scope.Close(JSON_parse->Call(JSON, 1, &jsonString));
}

then on the returned Handle<Value> obj

Local<Array> propertyNames = obj->GetPropertyNames();
for (int i=0;i < propertyNames->Length();++i) {
    // check if propertyName matches one I'm interested in
}

or recursively walk the json tree
Handle<Value> findMatchingValue(const string &key, Handle<Value> obj) {
    HandleScope scope;
    Handle<Value> rval;
    Local<Array> propertyNames = obj->GetPropertyNames();
    for (int i=0;i < propertyNames->Length();++i) {
        String::Utf8Value name = properNames->Get(i);
        if (name == *obj) { // check if propertyName matches one I'm interested in, not sure this will compile/function as desired
            rval = currentValue;
        }
        // if value type is an object or has children, gotta figure how to do this
            rval = findMatchingValue(key,value)
    }
}

Mark Essel

unread,
Jun 20, 2012, 6:57:44 PM6/20/12
to v8-u...@googlegroups.com
just reading over v8.h now, will have to save it until tomorrow.


On Sunday, June 10, 2012 5:30:10 PM UTC-4, Guilherme Silva wrote:

Matthias Ernst

unread,
Jun 21, 2012, 5:47:55 AM6/21/12
to v8-u...@googlegroups.com
On Thu, Jun 21, 2012 at 12:49 AM, Mark Essel <mes...@gmail.com> wrote:
> Just wanted to say thanks for asking this question Guilherme. I know have
> access to a straight forward json parser for my native module.
> when walking the jsonObject that results from the parsing do you loop over
> properties to find the keys of interest or is there a rapid/hashlike lookup
> available?

You're using it already: obj_handle->Get(propertyName)

Mark Essel

unread,
Jun 21, 2012, 6:03:48 AM6/21/12
to v8-u...@googlegroups.com, v8-u...@googlegroups.com
Thanks for calling it out Matthias. Assume it works for nested properties:

> obj_handle->Get(propertyName)->Get(propertyName)

I was hoping for a nested map of maps
obj[pname1][pname2][pname3]

Matthias Ernst

unread,
Jun 21, 2012, 6:11:00 AM6/21/12
to v8-u...@googlegroups.com
On Thu, Jun 21, 2012 at 12:03 PM, Mark Essel <mes...@gmail.com> wrote:
> Thanks for calling it out Matthias. Assume it works for nested properties:
>
>> obj_handle->Get(propertyName)->Get(propertyName)

Almost. Get is defined in Object, but returns a Handle<Value>.
So you need to test (value_handle->IsObject()) and cast
(value_handle.As<Object>).

Handle<Value> v = ... parse json ...
for (const string& property_name : path) {
if (!v->IsObject()) {
v = v8::Undefined();
break;
}
v = (v.As<Object>)->Get(property_name);
}

or somesuch.

Mark Essel

unread,
Jun 21, 2012, 7:55:28 AM6/21/12
to v8-u...@googlegroups.com, v8-u...@googlegroups.com
thanks again. Much appreciate the intro to json objects in v8

Mark Essel

unread,
Jun 21, 2012, 12:14:09 PM6/21/12
to v8-u...@googlegroups.com
Heyo Matthias, had some time to read this a.m. but couldn't find the
Get method you referred to.

I saw these in v8.h under class Object
V8EXPORT Local<Value> Get(Handle<Value> key);
V8EXPORT Local<Value> Get(uint32_t index);


is there a transform from string or char * to Handle<Value> key I'm missing?
String::New(buf)

and for keys is there a special string?
String::NewSymbol(buf)

https://groups.google.com/forum/#!msg/v8-users/AXnMijKMIxs/Kt0x9K81rlgJ

I'm calling Get from s where

Local<Object> s = sValue->ToObject();


no need to respond if you're busy. I'll keep poking around the docs
until I have a handle on the right types

Matthias Ernst

unread,
Jun 21, 2012, 12:33:23 PM6/21/12
to v8-u...@googlegroups.com
On Thu, Jun 21, 2012 at 6:14 PM, Mark Essel <mes...@gmail.com> wrote:
> Heyo Matthias, had some time to read this a.m. but couldn't find the
> Get method you referred to.
>
> I saw these in v8.h under class Object
> V8EXPORT Local<Value> Get(Handle<Value> key);
> V8EXPORT Local<Value> Get(uint32_t index);
>
>
> is there a transform from string or char * to Handle<Value> key I'm missing?
> String::New(buf)

Right, use v8::String::New(property_name.c_str()) .
Reply all
Reply to author
Forward
0 new messages