2012-01-24 17 views
7

से स्ट्रिंग का उपयोग करके मैं एक v8 खोल आधारित कंसोल बना रहा हूं, मैंने नमूना कोड लिया है जो v8 के साथ है और यह बहुत अच्छी तरह से काम कर रहा है, लेकिन मैं एक v8 :: ऑब्जेक्ट को स्ट्रिंग संस्करण में कनवर्ट करने का प्रयास कर रहा हूं इसके (जेसन) लेकिन इसे करने का कोई तरीका नहीं मिला। मैं इस के साथ एक फ़ाइल test.js बनाई खोल परv8 shell



    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's an object\n"); 
     } 
     return v8::String::New(""); 
    } 

:

यहाँ shell.cc अंदर मेरे नमूना कोड



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

और मैं भीतर js को क्रियान्वित करने के बाद इस मिल खोल कंसोल:



    [object Object] 
    It's an object 

क्या मैं चाहता हूँ है:



    { "name": "John" } 

अगर मैं करने के लिए जे एस कोड बदलने के लिए:



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

यह बहुत अच्छी तरह से काम करता है, लेकिन मैं उपयोगकर्ता को पता है json में JavaScript वैरिएबल पार्स करने के लिए कैसे होने चाहते हैं, और मैं के लिए जाँच करना चाहते हैं न ऑब्जेक्ट पर प्रत्येक इनपुट और इसे मैन्युअल रूप से पार्स करें।

क्या सी में shell.cc कोड के अंदर एक ही निर्देश निष्पादित करने का कोई तरीका है?



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

अद्यतन: की तरह कुछ JSON के



    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(""); 
    } 

उत्तर

10

मैं रिवर्स करने का यह रास्ता मिल गया (: यह मैं यह कैसे से निपटने कर रहा हूँ, लेकिन मैं एक क्लीनर तरीका भी ऐसा ही करना चाहते हैं v8 ऑब्जेक्ट), JSON.parse फ़ंक्शन में निर्मित v8s का उपयोग करना। http://www.mail-archive.com/[email protected]/msg04430.html

समायोजन इस बजाय JSON.stringify उपयोग करने के लिए एक तरह से इस प्रकार दिखाई देगा (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)); 
} 
0

मैं v8::Value -to- string रूपांतरण के अपने खुद के कार्यान्वयन के लिए अब-पदावनत वी 8 तरीकों का उपयोग कर से बचने के लिए चाहता था, तो मैंने माइकल के जवाब से प्रेरणा लेते हुए, इस समारोह को एक साथ रखा। नकारात्मकता यह है कि यह बहुत 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; 
} 
संबंधित मुद्दे