Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shortest way (one-liner) to get a default argument out of a v8 function?

It's been a long time since I've used C++, and even longer since I wrapped my head around hard types. I'm simply looking for a working one liner to do get an argument from v8, or a default value when an argument wasn't supplied.

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 close-to-ideal solution doesn't 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";
like image 812
Caleb Gray Avatar asked May 08 '12 22:05

Caleb Gray


2 Answers

Vyacheslav Egorov nailed it with his comment, by the time I was accessing the string, it had been destroyed. Ultimately 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");

    ...
}
like image 159
Caleb Gray Avatar answered Oct 03 '22 14:10

Caleb Gray


This bit of code worked well for me for extracting 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 scenarios without need for additional code, but if you do need to manually check for null values, this is trivial.

This code serves as an example, it gets string values of all the arguments and prints them to stdout, and of course puts them into a nice array, because what use is printing them out?

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;
}
like image 29
ChrisCM Avatar answered Oct 03 '22 14:10

ChrisCM