Search code examples
c++node.jsv8node.js-addon

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";

Solution

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