Shortest way (single line) to get default argument from v8 function?

It has been a long time since I used C ++, and even longer since I wrapped my head in cool types. I'm just looking for a working single liner to get an argument from v8 or the default when no argument was provided.

v8::String::Utf8Value arg0(args[0]);
v8::String::Utf8Value arg1(args[1]);
v8::String::Utf8Value arg2(args[2]);
const char *username = (args.Length() > 0) ? *arg0 : "";
const char *password = (args.Length() > 1) ? *arg1 : "";
const char *service = (args.Length() > 2) ? *arg2 : "login";

Outputs:

func (); // {username: "", password: "", service: "login"}
func ('1'); // {username: "1", password: "", service: "login"}
func ('1', '2'); // {username: "1", password: "2", service: "login"}
func ('a', 'b', 'c'); // {username: "a", password: "b", service: "c"}

Unfortunately, the following near-ideal solution does not work for me (any ideas, why?):

const char *username = (args.Length() > 0) ? *v8::String::Utf8Value(args[0]->ToString()) : "";
const char *password = (args.Length() > 1) ? *v8::String::Utf8Value(args[1]->ToString()) : "";
const char *service = (args.Length() > 2) ? *v8::String::Utf8Value(args[2]->ToString()) : "login";
+5
source share
4 answers

Vyacheslav Egorov nailed it with his comment, by the time I turned to the rope, he was destroyed. I ended up using:

char *get(v8::Local<v8::Value> value, const char *fallback = "") {
    if (value->IsString()) {
        v8::String::AsciiValue string(value);
        char *str = (char *) malloc(string.length() + 1);
        strcpy(str, *string);
        return str;
    }
    char *str = (char *) malloc(strlen(fallback) + 1);
    strcpy(str, fallback);
    return str;
}

Usage example:

v8::Handle<v8::Value> myMethod(const v8::Arguments &args) {
    char *username = get(args[0], "user");
    char *password = get(args[1], "pass");

    ...
}
+8
source

This bit of code worked well for me to extract a string value from a v8 value in one line:

std::string tempString(*v8::String::Utf8Value(args[someInteger]));

The std :: string constructor should handle your default scripts without requiring additional code, but if you need to manually check for null values, this is trivial.

, stdout , , , ?

std::string* printAllArgs(const Arguments& args){
    std::cout << "PRINTING ALL ARGS: ";
    std::string* stringArray = new std::string[args.Length()];
    for(int i = 0; i < args.Length(); i++){
        std::string tempString(*v8::String::Utf8Value(args[i]));
        stringArray[i] = tempString;
        std::cout << tempString << ";";
    }
    return stringArray;
}
+3

, AsciiValue , - :

const char *username = *v8::String::Utf8Value(args[0]->ToString());
//transient AsciiValue object has gone out of scope, and its destructor has been called in
//  previous line, rendering the pointer (content) invalid henceforth!
...

, AsciiValue .

2 , "" :

{
  v8::String::Utf8Value usernameObj(args[0]->ToString());
  const char *username = *usernameObj;
  ...
  //use username pointer as often as desired; it remains valid in this entire scope.
  doSomethingWithString(username); //OK

  //can also dereference Utf8Value object only when needed:
  doSomethingWithString(*usernameObj); //OK
}
//here, usernameObj is out of scope and is destroyed, and username will become invalid.

, :

doSomethingWithString(*v8::String::Utf8Value(args[0]->ToString())); //OK

doSomethingWithString . , Utf8Value, .

String:: AsciiValue.

+2
string bi = info[0]->IsUndefined() ? "backwardIndex.dat" : string(*Nan::Utf8String(info[0]));
0

All Articles