Using stringify from v8 shell

I am creating a console based on the v8 shell, I took an example of the code that replaced v8, and it works very well, but I am trying to convert the v8 :: object to its lowercase version (json), but have not found a way to do this.

Here is my sample code inside shell.cc:

v8::Handle test(const v8::Arguments& args) { v8::HandleScope handle_scope; const char* json; v8::String::Utf8Value strJson(args[0]); printf(ToCString(json)); if (args[0]->IsObject()) { printf("it an object\n"); } return v8::String::New(""); } 

In the shell, I created a test.js file with this:

 var a = { name: 'John' }; test(a); 

and I get this after running js in the shell console:

 [object Object] It an object 

I want:

 { "name": "John" } 

if i changed js code to:

 var a = { name: 'John'} test(JSON.stringify(a)); 

it works very well, but I don’t want the user to know how to parse the javascript variable in json, and I don’t want to check every single input of the object and parse it manually.

Is there a way to execute the same statement inside shell.cc code in C? something like:

 v8::Handle<v8::String> temp = JSON.parse(arg[0]); 

update: This is how I handle this, but I need a cleaner way to do the same:

 const char* toJson(const v8::Local<v8::Object>& obj) { std::stringstream ss; ss << "{"; v8::Local<v8::Array> propertyNames = obj->GetPropertyNames(); for (int x = 0; x < propertyNames->Length(); x++) { if (x != 0) { ss << ", "; } v8::String::Utf8Value name(propertyNames->Get(x)); ss << "\"" << ToCString(name) << "\":"; v8::Local<v8::Value> val = obj->GetInternalField(x); if (val->IsObject()) { ss << toJson(val->ToObject()); } else { ss << "\"" << ToCString(v8::String::Utf8Value(val)) << "\""; } } ss << "}"; const char* result = ss.str().c_str(); return result; } v8::Handle test(const v8::Arguments& args) { v8::HandleScope handle_scope; const char* json; v8::String::Utf8Value strJson(args[0]); if (args[0]->IsObject()) { char* json = toJson(args[0]); // ... // Some operations with the json // ... } return v8::String::New(""); } 
+7
source share
2 answers

I found this way to do the opposite (JSON to v8 object) using v8s built into the JSON.parse function. http://www.mail-archive.com/ v8-users@googlegroups.com /msg04430.html

Adjusting this to use JSON.stringify instead would look like this (untested):

 Handle<String> toJson(Handle<Value> object) { HandleScope scope; Handle<Context> context = Context::GetCurrent(); Handle<Object> global = context->Global(); Handle<Object> JSON = global->Get(String::New("JSON"))->ToObject(); Handle<Function> JSON_stringify = Handle<Function>::Cast(JSON->Get(String::New("stringify"))); return scope.Close(JSON_stringify->Call(JSON, 1, object)); } 
+10
source

I wanted to avoid using deprecated V8 methods for my implementation of the v8::Value -to- string , so I put together this function inspired by Michael. The disadvantage is that it is very verbose:

 bool MakeStringValue(const string& str, v8::Isolate* isolate, v8::Handle<v8::Value>* out_value) { const v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromUtf8( isolate, str.c_str(), v8::NewStringType::kNormal, str.size()); v8::Handle<v8::String> value; if (!maybe_string.ToLocal(&value)) { return false; } *out_value = static_cast<v8::Handle<v8::Value>>(value); return true; } bool ConvertValueToString(v8::Handle<v8::Value> value, v8::Isolate* isolate, v8::Local<v8::Context> context, string* value_string) { v8::Local<v8::Object> global = context->Global(); v8::Handle<v8::Value> json_string_value; v8::Handle<v8::Value> stringify_string_value; if (!MakeStringValue("JSON", isolate, &json_string_value) || !MakeStringValue("stringify", isolate, &stringify_string_value)) { return false; } const v8::MaybeLocal<v8::Value> maybe_json_value = global->Get(context, json_string_value); v8::Handle<v8::Value> json_value; if (!maybe_json_value.ToLocal(&json_value)) { return false; } v8::MaybeLocal<v8::Object> maybe_json_object = json_value->ToObject(context); v8::Handle<v8::Object> json_object; if (!maybe_json_object.ToLocal(&json_object)) { return false; } const v8::MaybeLocal<v8::Value> maybe_stringify_value = json_object->Get(context, stringify_string_value); v8::Handle<v8::Value> stringify_value; if (!maybe_stringify_value.ToLocal(&stringify_value)) { return false; } v8::Function* stringify_function = v8::Function::Cast(*stringify_value); v8::TryCatch try_catch(isolate); const v8::MaybeLocal<v8::Value> maybe_result = stringify_function->Call(context, json_object, 1, &value); v8::Local<v8::Value> result; if (try_catch.HasCaught() || !maybe_result.ToLocal(&result) || result.IsEmpty() || result->IsNullOrUndefined() || !result->IsString()) { return false; } v8::Local<v8::String> result_string; if (!result->ToString(context).ToLocal(&result_string)) { return false; } v8::String::Utf8Value utf8_value(result_string); // operator* returns a const char*. if (*utf8_value == nullptr) { return false; } value_string->assign(*utf8_value, utf8_value.length()); return true; } 
0
source

All Articles