// Copyright (c) 2013 GitHub, Inc. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMMON_V8_CONVERSIONS_H_ #define COMMON_V8_CONVERSIONS_H_ #include #include #include "base/files/file_path.h" #include "base/string16.h" #include "browser/api/atom_api_window.h" #include "v8/include/v8.h" // Convert V8 value to arbitrary supported types. struct FromV8Value { explicit FromV8Value(v8::Handle value) : value_(value) {} operator int() { return value_->IntegerValue(); } operator bool() { return value_->BooleanValue(); } operator std::string() { return *v8::String::Utf8Value(value_); } operator string16() { v8::String::Value s(value_); return string16(reinterpret_cast(*s), s.length()); } operator base::FilePath() { return base::FilePath::FromUTF8Unsafe(FromV8Value(value_)); } operator std::vector() { std::vector array; v8::Handle v8_array = v8::Handle::Cast(value_); for (uint32_t i = 0; i < v8_array->Length(); ++i) array.push_back(FromV8Value(v8_array->Get(i))); return array; } operator atom::NativeWindow*() { using atom::api::Window; if (value_->IsObject()) { Window* window = Window::Unwrap(value_->ToObject()); if (window && window->window()) return window->window(); } return NULL; } operator v8::Persistent() { return value_->IsFunction() ? v8::Persistent::New( node::node_isolate, v8::Handle::Cast(value_)) : v8::Persistent(); } v8::Handle value_; }; // Convert arbitrary supported native type to V8 value. inline v8::Handle ToV8Value(int i) { return v8::Integer::New(i); } inline v8::Handle ToV8Value(bool b) { return v8::Boolean::New(b); } inline v8::Handle ToV8Value(const std::string& s) { return v8::String::New(s.data(), s.size()); } inline v8::Handle ToV8Value(const string16& s) { return v8::String::New(reinterpret_cast(s.data()), s.size()); } inline v8::Handle ToV8Value(const base::FilePath& path) { std::string path_string(path.AsUTF8Unsafe()); return v8::String::New(path_string.data(), path_string.size()); } inline v8::Handle ToV8Value(void* whatever) { return v8::Undefined(); } inline v8::Handle ToV8Value(const std::vector& paths) { v8::Handle result = v8::Array::New(paths.size()); for (size_t i = 0; i < paths.size(); ++i) result->Set(i, ToV8Value(paths[i])); return result; } // Check if a V8 Value is of specified type. template inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return false; } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return value->IsNumber(); } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return value->IsBoolean(); } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return value->IsString(); } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return V8ValueCanBeConvertedTo(value); } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { return V8ValueCanBeConvertedTo(value); } template<> inline bool V8ValueCanBeConvertedTo>( v8::Handle value) { return value->IsArray(); } template<> inline bool V8ValueCanBeConvertedTo(v8::Handle value) { using atom::api::Window; if (value->IsObject()) { Window* window = Window::Unwrap(value->ToObject()); if (window && window->window()) return true; } return false; } template<> inline bool V8ValueCanBeConvertedTo>( v8::Handle value) { return value->IsFunction(); } // Check and convert V8's Arguments to native types. template inline bool FromV8Arguments(const v8::Arguments& args, T1* value, int index = 0) { if (!V8ValueCanBeConvertedTo(args[index])) return false; *value = static_cast(FromV8Value(args[index])); return true; } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2) { return FromV8Arguments(args, a1) && FromV8Arguments(args, a2, 1); } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3) { return FromV8Arguments(args, a1, a2) && FromV8Arguments(args, a3, 2); } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3, T4* a4) { return FromV8Arguments(args, a1, a2, a3) && FromV8Arguments(args, a4, 3); } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3, T4* a4, T5* a5) { return FromV8Arguments(args, a1, a2, a3, a4) && FromV8Arguments(args, a5, 4); } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3, T4* a4, T5* a5, T6* a6) { return FromV8Arguments(args, a1, a2, a3, a4, a5) && FromV8Arguments(args, a6, 5); } template inline bool FromV8Arguments(const v8::Arguments& args, T1* a1, T2* a2, T3* a3, T4* a4, T5* a5, T6* a6, T7* a7) { return FromV8Arguments(args, a1, a2, a3, a4, a5, a6) && FromV8Arguments(args, a7, 6); } #endif // COMMON_V8_CONVERSIONS_H_