Changeset View
Changeset View
Standalone View
Standalone View
desktop/addons/windows-pushnotifications/CollectionsWrap.h
- This file was added.
// Copyright (c) The NodeRT Contributors | |||||
// All rights reserved. | |||||
// | |||||
// Licensed under the Apache License, Version 2.0 (the ""License""); you may | |||||
// not use this file except in compliance with the License. You may obtain a | |||||
// copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | |||||
// | |||||
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS | |||||
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY | |||||
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | |||||
// MERCHANTABLITY OR NON-INFRINGEMENT. | |||||
// | |||||
// See the Apache Version 2.0 License for specific language governing | |||||
// permissions and limitations under the License. | |||||
#pragma once | |||||
#include <v8.h> | |||||
#include "NodeRtUtils.h" | |||||
#include "OpaqueWrapper.h" | |||||
#include "WrapperBase.h" | |||||
#include "nan.h" | |||||
#include <functional> | |||||
namespace NodeRT | |||||
{ | |||||
namespace Collections | |||||
{ | |||||
using Nan::False; | |||||
using Nan::HandleScope; | |||||
using Nan::MaybeLocal; | |||||
using Nan::Null; | |||||
using Nan::Persistent; | |||||
using Nan::True; | |||||
using Nan::Undefined; | |||||
using v8::Boolean; | |||||
using v8::FunctionTemplate; | |||||
using v8::Integer; | |||||
using v8::Local; | |||||
using v8::String; | |||||
using v8::Value; | |||||
template <class T> | |||||
class ArrayWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
EscapableHandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Array").ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetIndexedPropertyHandler(localRef->InstanceTemplate(), Get, Set); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("length").ToLocalChecked(), LengthGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateArrayWrapper( | |||||
::Platform::Array<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc = nullptr, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
ArrayWrapper<T> *wrapperInstance = new ArrayWrapper<T>( | |||||
winRtInstance, getterFunc, checkTypeFunc, convertToTypeFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
ArrayWrapper( | |||||
::Platform::Array<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
: _instance(winRtInstance), | |||||
_getterFunc(getterFunc), | |||||
_checkTypeFunc(checkTypeFunc), | |||||
_convertToTypeFunc(convertToTypeFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void LengthGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
ArrayWrapper<T> *wrapper = | |||||
ArrayWrapper<T>::Unwrap<ArrayWrapper<T>>(info.This()); | |||||
try | |||||
{ | |||||
unsigned int result = wrapper->_instance->Length; | |||||
info.GetReturnValue().Set(Nan::New<Integer>(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
static void Get(uint32_t index, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
ArrayWrapper<T> *wrapper = | |||||
ArrayWrapper<T>::Unwrap<ArrayWrapper<T>>(info.This()); | |||||
if (wrapper->_instance->Length <= index) | |||||
{ | |||||
return; | |||||
} | |||||
if (wrapper->_getterFunc == nullptr) | |||||
{ | |||||
info.GetReturnValue().Set(CreateOpaqueWrapper(wrapper->_instance[index])); | |||||
} | |||||
else | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
wrapper->_getterFunc(wrapper->_instance[index])); | |||||
} | |||||
} | |||||
static void Set(uint32_t index, | |||||
Local<Value> value, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
ArrayWrapper<T> *wrapper = | |||||
ArrayWrapper<T>::Unwrap<ArrayWrapper<T>>(info.This()); | |||||
if (wrapper->_checkTypeFunc && !wrapper->_checkTypeFunc(value)) | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"The argument to set isn't of the expected type or internal WinRt " | |||||
L"object was disposed"))); | |||||
return; | |||||
} | |||||
if (wrapper->_instance->Length <= index) | |||||
{ | |||||
Nan::ThrowError(Nan::Error( | |||||
NodeRT::Utils::NewString(L"Given index exceeded array length"))); | |||||
return; | |||||
} | |||||
if (wrapper->_convertToTypeFunc) | |||||
{ | |||||
try | |||||
{ | |||||
wrapper->_instance[index] = wrapper->_convertToTypeFunc(value); | |||||
} | |||||
catch (::Platform::Exception ^ e) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(e); | |||||
} | |||||
} | |||||
return; | |||||
} | |||||
private: | |||||
::Platform::Array<T> ^ _instance; | |||||
std::function<Local<Value>(T)> _getterFunc; | |||||
std::function<bool(Local<Value>)> _checkTypeFunc; | |||||
std::function<T(Local<Value>)> _convertToTypeFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class T> | |||||
Persistent<FunctionTemplate> ArrayWrapper<T>::s_constructorTemplate; | |||||
template <class T> | |||||
class IteratorWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IIterator") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetPrototypeMethod(localRef, "getMany", GetMany); | |||||
Nan::SetPrototypeMethod(localRef, "moveNext", MoveNext); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("current").ToLocalChecked(), | |||||
CurrentGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("hasCurrent").ToLocalChecked(), | |||||
HasCurrentGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateIteratorWrapper( | |||||
::Windows::Foundation::Collections::IIterator<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc = nullptr) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
IteratorWrapper<T> *wrapperInstance = | |||||
new IteratorWrapper<T>(winRtInstance, getterFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
IteratorWrapper(::Windows::Foundation::Collections::IIterator<T> ^ | |||||
winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc) | |||||
: _instance(winRtInstance), _getterFunc(getterFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void MoveNext(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IIterator<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
IteratorWrapper<T> *wrapper = | |||||
IteratorWrapper<T>::Unwrap<IteratorWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
bool result; | |||||
result = wrapper->_instance->MoveNext(); | |||||
info.GetReturnValue().Set(Nan::New<Boolean>(result)); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
// Not supporting this for now since we need to initialize the array ourselves | |||||
// and don't know which size to use | |||||
static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented"))); | |||||
return; | |||||
} | |||||
static void CurrentGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IIterator<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
IteratorWrapper<T> *wrapper = | |||||
IteratorWrapper<T>::Unwrap<IteratorWrapper<T>>(info.This()); | |||||
try | |||||
{ | |||||
T current = wrapper->_instance->Current; | |||||
if (wrapper->_getterFunc != nullptr) | |||||
{ | |||||
info.GetReturnValue().Set(wrapper->_getterFunc(current)); | |||||
} | |||||
else | |||||
{ | |||||
info.GetReturnValue().Set(CreateOpaqueWrapper(current)); | |||||
} | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
static void HasCurrentGetter( | |||||
Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IIterator<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
IteratorWrapper<T> *wrapper = | |||||
IteratorWrapper<T>::Unwrap<IteratorWrapper<T>>(info.This()); | |||||
try | |||||
{ | |||||
bool result = wrapper->_instance->HasCurrent; | |||||
info.GetReturnValue().Set(Nan::New<Boolean>(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IIterator<T> ^ _instance; | |||||
std::function<Local<Value>(T)> _getterFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class T> | |||||
class IterableWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IIterable") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetPrototypeMethod(localRef, "first", First); | |||||
return; | |||||
} | |||||
static Local<Value> CreateIterableWrapper( | |||||
::Windows::Foundation::Collections::IIterable<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc = nullptr) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
IterableWrapper<T> *wrapperInstance = | |||||
new IterableWrapper<T>(winRtInstance, getterFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
IterableWrapper(::Windows::Foundation::Collections::IIterable<T> ^ | |||||
winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc) | |||||
: _instance(winRtInstance), _getterFunc(getterFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This().Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void First(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IIterable<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
IterableWrapper<T> *wrapper = | |||||
IterableWrapper<T>::Unwrap<IterableWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
::Windows::Foundation::Collections::IIterator<T> ^ result = | |||||
wrapper->_instance->First(); | |||||
info.GetReturnValue().Set(IteratorWrapper<T>::CreateIteratorWrapper( | |||||
result, wrapper->_getterFunc)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IIterable<T> ^ _instance; | |||||
std::function<Local<Value>(T)> _getterFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class T> | |||||
Persistent<FunctionTemplate> IterableWrapper<T>::s_constructorTemplate; | |||||
template <class T> | |||||
Persistent<FunctionTemplate> IteratorWrapper<T>::s_constructorTemplate; | |||||
template <class T> | |||||
class VectorViewWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IVectorView") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetIndexedPropertyHandler(localRef->InstanceTemplate(), Get); | |||||
Nan::SetPrototypeMethod(localRef, "getMany", GetMany); | |||||
Nan::SetPrototypeMethod(localRef, "getAt", GetAt); | |||||
Nan::SetPrototypeMethod(localRef, "indexOf", IndexOf); | |||||
Nan::SetPrototypeMethod(localRef, "first", First); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("size").ToLocalChecked(), SizeGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("length").ToLocalChecked(), SizeGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateVectorViewWrapper( | |||||
::Windows::Foundation::Collections::IVectorView<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
VectorViewWrapper<T> *wrapperInstance = | |||||
new VectorViewWrapper<T>(winRtInstance, getterFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
VectorViewWrapper( | |||||
::Windows::Foundation::Collections::IVectorView<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
: _instance(winRtInstance), | |||||
_getterFunc(getterFunc), | |||||
_checkTypeFunc(checkTypeFunc), | |||||
_convertToTypeFunc(convertToTypeFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void Get(uint32_t index, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVectorView<T> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorViewWrapper<T> *wrapper = | |||||
VectorViewWrapper<T>::Unwrap<VectorViewWrapper<T>>(info.This()); | |||||
if (wrapper->_instance->Size <= index) | |||||
{ | |||||
return; | |||||
} | |||||
if (wrapper->_getterFunc == nullptr) | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
CreateOpaqueWrapper(wrapper->_instance->GetAt(index))); | |||||
} | |||||
else | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
wrapper->_getterFunc(wrapper->_instance->GetAt(index))); | |||||
} | |||||
} | |||||
static void GetAt(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVectorView<T> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorViewWrapper<T> *wrapper = | |||||
VectorViewWrapper<T>::Unwrap<VectorViewWrapper<T>>(info.This()); | |||||
if (info.Length() == 1 && info[0]->IsUint32()) | |||||
{ | |||||
try | |||||
{ | |||||
unsigned int index = info[0]->Uint32Value(Nan::GetCurrentContext()).FromMaybe(0); | |||||
if (index >= wrapper->_instance->Size) | |||||
{ | |||||
return; | |||||
} | |||||
T result; | |||||
result = wrapper->_instance->GetAt(index); | |||||
if (wrapper->_getterFunc) | |||||
{ | |||||
info.GetReturnValue().Set(wrapper->_getterFunc(result)); | |||||
} | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented"))); | |||||
return; | |||||
} | |||||
static void First(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVectorView<T> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorViewWrapper<T> *wrapper = | |||||
VectorViewWrapper<T>::Unwrap<VectorViewWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(IteratorWrapper<T>::CreateIteratorWrapper( | |||||
wrapper->_instance->First(), wrapper->_getterFunc)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void IndexOf(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVectorView<T> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorViewWrapper<T> *wrapper = | |||||
VectorViewWrapper<T>::Unwrap<VectorViewWrapper<T>>(info.This()); | |||||
if (wrapper->_convertToTypeFunc == nullptr || | |||||
wrapper->_checkTypeFunc == nullptr) | |||||
{ | |||||
Nan::ThrowError( | |||||
Nan::Error(NodeRT::Utils::NewString(L"Method isn't supported"))); | |||||
return; | |||||
} | |||||
if (info.Length() == 1 && wrapper->_checkTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
T item = wrapper->_convertToTypeFunc(info[0]); | |||||
unsigned int index; | |||||
bool result = wrapper->_instance->IndexOf(item, &index); | |||||
Local<Object> resObj = Nan::New<Object>(); | |||||
Nan::Set(resObj, Nan::New<String>("boolean").ToLocalChecked(), | |||||
Nan::New<v8::Boolean>(result)); | |||||
Nan::Set(resObj, Nan::New<String>("index").ToLocalChecked(), | |||||
Nan::New<v8::Integer>(index)); | |||||
info.GetReturnValue().Set(resObj); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void SizeGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVectorView<T> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorViewWrapper<T> *wrapper = | |||||
VectorViewWrapper<T>::Unwrap<VectorViewWrapper<T>>(info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(Nan::New<Integer>(wrapper->_instance->Size)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IVectorView<T> ^ _instance; | |||||
std::function<Local<Value>(T)> _getterFunc; | |||||
std::function<bool(Local<Value>)> _checkTypeFunc; | |||||
std::function<T(Local<Value>)> _convertToTypeFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class T> | |||||
Persistent<FunctionTemplate> VectorViewWrapper<T>::s_constructorTemplate; | |||||
template <class T> | |||||
class VectorWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IVector") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetIndexedPropertyHandler(localRef->InstanceTemplate(), Get, Set); | |||||
Nan::SetPrototypeMethod(localRef, "getMany", GetMany); | |||||
Nan::SetPrototypeMethod(localRef, "getAt", GetAt); | |||||
Nan::SetPrototypeMethod(localRef, "indexOf", IndexOf); | |||||
Nan::SetPrototypeMethod(localRef, "first", First); | |||||
Nan::SetPrototypeMethod(localRef, "append", Append); | |||||
Nan::SetPrototypeMethod(localRef, "clear", Clear); | |||||
Nan::SetPrototypeMethod(localRef, "getView", GetView); | |||||
Nan::SetPrototypeMethod(localRef, "insertAt", InsertAt); | |||||
Nan::SetPrototypeMethod(localRef, "removeAt", RemoveAt); | |||||
Nan::SetPrototypeMethod(localRef, "removeAtEnd", RemoveAtEnd); | |||||
Nan::SetPrototypeMethod(localRef, "replaceAll", ReplaceAll); | |||||
Nan::SetPrototypeMethod(localRef, "setAt", SetAt); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("size").ToLocalChecked(), SizeGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("length").ToLocalChecked(), SizeGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateVectorWrapper( | |||||
::Windows::Foundation::Collections::IVector<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
VectorWrapper<T> *wrapperInstance = new VectorWrapper<T>( | |||||
winRtInstance, getterFunc, checkTypeFunc, convertToTypeFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
VectorWrapper( | |||||
::Windows::Foundation::Collections::IVector<T> ^ winRtInstance, | |||||
const std::function<Local<Value>(T)> &getterFunc, | |||||
const std::function<bool(Local<Value>)> &checkTypeFunc = nullptr, | |||||
const std::function<T(Local<Value>)> &convertToTypeFunc = nullptr) | |||||
: _instance(winRtInstance), | |||||
_getterFunc(getterFunc), | |||||
_checkTypeFunc(checkTypeFunc), | |||||
_convertToTypeFunc(convertToTypeFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void Get(uint32_t index, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (wrapper->_instance->Size <= index) | |||||
{ | |||||
return; | |||||
} | |||||
if (wrapper->_getterFunc == nullptr) | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
CreateOpaqueWrapper(wrapper->_instance->GetAt(index))); | |||||
} | |||||
else | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
wrapper->_getterFunc(wrapper->_instance->GetAt(index))); | |||||
} | |||||
} | |||||
static void Set(uint32 index, | |||||
Local<Value> value, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (!wrapper->_checkTypeFunc(value)) | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"The value to set isn't of the expected type"))); | |||||
return; | |||||
} | |||||
try | |||||
{ | |||||
T item = wrapper->_convertToTypeFunc(value); | |||||
wrapper->_instance->SetAt(index, item); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Append(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
T value = wrapper->_convertToTypeFunc(info[0]); | |||||
wrapper->_instance->Append(value); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Clear(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
wrapper->_instance->Clear(); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented"))); | |||||
return; | |||||
} | |||||
static void GetView(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
::Windows::Foundation::Collections::IVectorView<T> ^ result = | |||||
wrapper->_instance->GetView(); | |||||
info.GetReturnValue().Set(VectorViewWrapper<T>::CreateVectorViewWrapper( | |||||
result, wrapper->_getterFunc, wrapper->_checkTypeFunc, | |||||
wrapper->_convertToTypeFunc)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void InsertAt(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 2 && info[0]->IsUint32() && | |||||
wrapper->_checkTypeFunc(info[1])) | |||||
{ | |||||
try | |||||
{ | |||||
unsigned int index = info[0]->Uint32Value(Nan::GetCurrentContext()).FromMaybe(0); | |||||
T value = wrapper->_convertToTypeFunc(info[1]); | |||||
wrapper->_instance->InsertAt(index, value); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void RemoveAt(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 1 && info[0]->IsUint32()) | |||||
{ | |||||
try | |||||
{ | |||||
unsigned int index = info[0]->Uint32Value(Nan::GetCurrentContext()).FromMaybe(0); | |||||
wrapper->_instance->RemoveAt(index); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void RemoveAtEnd(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
wrapper->_instance->RemoveAtEnd(); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void ReplaceAll(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 1 && | |||||
NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<T> ^>(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
WrapperBase *itemsWrapper = | |||||
WrapperBase::Unwrap<WrapperBase>(info[0].As<Object>()); | |||||
::Platform::Array<T> ^ items = | |||||
(::Platform::Array<T> ^) itemsWrapper->GetObjectInstance(); | |||||
wrapper->_instance->ReplaceAll(items); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void GetAt(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 1 && info[0]->IsUint32()) | |||||
{ | |||||
try | |||||
{ | |||||
unsigned int index = info[0]->Uint32Value(Nan::GetCurrentContext()).FromMaybe(0); | |||||
if (index >= wrapper->_instance->Size) | |||||
{ | |||||
return; | |||||
} | |||||
T result; | |||||
result = wrapper->_instance->GetAt(index); | |||||
if (wrapper->_getterFunc) | |||||
{ | |||||
info.GetReturnValue().Set(wrapper->_getterFunc(result)); | |||||
} | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void SetAt(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 2 && info[0]->IsUint32() && | |||||
wrapper->_checkTypeFunc(info[1])) | |||||
{ | |||||
try | |||||
{ | |||||
unsigned int index = info[0]->Uint32Value(Nan::GetCurrentContext()).FromMaybe(0); | |||||
if (index >= wrapper->_instance->Size) | |||||
{ | |||||
return; | |||||
} | |||||
T item = wrapper->_convertToTypeFunc(info[1]); | |||||
wrapper->_instance->SetAt(index, item); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void First(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(IteratorWrapper<T>::CreateIteratorWrapper( | |||||
wrapper->_instance->First(), wrapper->_getterFunc)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void IndexOf(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
if (wrapper->_convertToTypeFunc == nullptr || | |||||
wrapper->_checkTypeFunc == nullptr) | |||||
{ | |||||
Nan::ThrowError( | |||||
Nan::Error(NodeRT::Utils::NewString(L"Method isn't supported"))); | |||||
return; | |||||
} | |||||
if (info.Length() == 1 && wrapper->_checkTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
T item = wrapper->_convertToTypeFunc(info[0]); | |||||
unsigned int index; | |||||
bool result = wrapper->_instance->IndexOf(item, &index); | |||||
Local<Object> resObj = Nan::New<Object>(); | |||||
Nan::Set(resObj, Nan::New<String>("boolean").ToLocalChecked(), | |||||
Nan::New<Boolean>(result)); | |||||
Nan::Set(resObj, Nan::New<String>("index").ToLocalChecked(), | |||||
Nan::New<Integer>(index)); | |||||
info.GetReturnValue().Set(resObj); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void SizeGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IVector<T> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
VectorWrapper<T> *wrapper = | |||||
VectorWrapper<T>::Unwrap<VectorWrapper<T>>(info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(Nan::New<Integer>(wrapper->_instance->Size)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IVector<T> ^ _instance; | |||||
std::function<Local<Value>(T)> _getterFunc; | |||||
std::function<bool(Local<Value>)> _checkTypeFunc; | |||||
std::function<T(Local<Value>)> _convertToTypeFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class T> | |||||
Persistent<FunctionTemplate> VectorWrapper<T>::s_constructorTemplate; | |||||
template <class K, class V> | |||||
class KeyValuePairWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IKeyValuePair") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("key").ToLocalChecked(), KeyGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("value").ToLocalChecked(), ValueGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateKeyValuePairWrapper( | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^ winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
KeyValuePairWrapper<K, V> *wrapperInstance = new KeyValuePairWrapper<K, V>( | |||||
winRtInstance, keyGetterFunc, valueGetterFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
KeyValuePairWrapper(::Windows::Foundation::Collections::IKeyValuePair<K, V> ^ | |||||
winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc) | |||||
: _instance(winRtInstance), | |||||
_keyGetterFunc(keyGetterFunc), | |||||
_valueGetterFunc(valueGetterFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void KeyGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
KeyValuePairWrapper<K, V> *wrapper = | |||||
KeyValuePairWrapper<K, V>::Unwrap<KeyValuePairWrapper<K, V>>( | |||||
info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
wrapper->_keyGetterFunc(wrapper->_instance->Key)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
static void ValueGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
KeyValuePairWrapper<K, V> *wrapper = | |||||
KeyValuePairWrapper<K, V>::Unwrap<KeyValuePairWrapper<K, V>>( | |||||
info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set( | |||||
wrapper->_valueGetterFunc(wrapper->_instance->Value)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^ _instance; | |||||
std::function<Local<Value>(K)> _keyGetterFunc; | |||||
std::function<Local<Value>(V)> _valueGetterFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class K, class V> | |||||
Persistent<FunctionTemplate> KeyValuePairWrapper<K, V>::s_constructorTemplate; | |||||
template <class K, class V> | |||||
class MapViewWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IMapView") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetPrototypeMethod(localRef, "hasKey", HasKey); | |||||
Nan::SetPrototypeMethod(localRef, "lookup", Lookup); | |||||
Nan::SetPrototypeMethod(localRef, "split", Split); | |||||
Nan::SetPrototypeMethod(localRef, "first", First); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("size").ToLocalChecked(), SizeGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("length").ToLocalChecked(), SizeGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateMapViewWrapper( | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^ winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkKeyTypeFunc, | |||||
const std::function<K(Local<Value>)> &convertToKeyTypeFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
MapViewWrapper<K, V> *wrapperInstance = | |||||
new MapViewWrapper<K, V>(winRtInstance, keyGetterFunc, checkKeyTypeFunc, | |||||
convertToKeyTypeFunc, valueGetterFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
MapViewWrapper(::Windows::Foundation::Collections::IMapView<K, V> ^ | |||||
winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkKeyTypeFunc, | |||||
const std::function<K(Local<Value>)> &convertToKeyTypeFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc) | |||||
: _instance(winRtInstance), | |||||
_keyGetterFunc(keyGetterFunc), | |||||
_checkKeyTypeFunc(checkKeyTypeFunc), | |||||
_convertToKeyTypeFunc(convertToKeyTypeFunc), | |||||
_valueGetterFunc(valueGetterFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void HasKey(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapViewWrapper<K, V> *wrapper = | |||||
MapViewWrapper<K, V>::Unwrap<MapViewWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkKeyTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
bool result = wrapper->_instance->HasKey(key); | |||||
info.GetReturnValue().Set(Nan::New<Boolean>(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void First(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapViewWrapper<K, V> *wrapper = | |||||
MapViewWrapper<K, V>::Unwrap<MapViewWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
const std::function<Local<Value>(K)> &keyGetter = | |||||
wrapper->_keyGetterFunc; | |||||
const std::function<Local<Value>(V)> &valueGetter = | |||||
wrapper->_valueGetterFunc; | |||||
info.GetReturnValue().Set( | |||||
IteratorWrapper< | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^>:: | |||||
CreateIteratorWrapper( | |||||
wrapper->_instance->First(), | |||||
[keyGetter, valueGetter]( | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, | |||||
V> ^ | |||||
value) | |||||
{ | |||||
return KeyValuePairWrapper< | |||||
K, V>::CreateKeyValuePairWrapper(value, keyGetter, | |||||
valueGetter); | |||||
})); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Lookup(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapViewWrapper<K, V> *wrapper = | |||||
MapViewWrapper<K, V>::Unwrap<MapViewWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkKeyTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
V result = wrapper->_instance->Lookup(key); | |||||
info.GetReturnValue().Set(wrapper->_valueGetterFunc(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Split(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapViewWrapper<K, V> *wrapper = | |||||
MapViewWrapper<K, V>::Unwrap<MapViewWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^ first; | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^ second; | |||||
wrapper->_instance->Split(&first, &second); | |||||
Local<Object> resObj = Nan::New<Object>(); | |||||
Nan::Set( | |||||
resObj, Nan::New<String>("first").ToLocalChecked(), | |||||
MapViewWrapper<K, V>::CreateMapViewWrapper( | |||||
first, wrapper->_keyGetterFunc, wrapper->_checkTypeFunc, | |||||
wrapper->_convertToKeyTypeFunc, wrapper->_valueGetterFunc)); | |||||
Nan::Set( | |||||
resObj, Nan::New<String>("second").ToLocalChecked(), | |||||
MapViewWrapper<K, V>::CreateMapViewWrapper( | |||||
second, wrapper->_keyGetterFunc, wrapper->_checkTypeFunc, | |||||
wrapper->_convertToKeyTypeFunc, wrapper->_valueGetterFunc)); | |||||
info.GetReturnValue().Set(resObj); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void SizeGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^>( | |||||
info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapViewWrapper<K, V> *wrapper = | |||||
MapViewWrapper<K, V>::Unwrap<MapViewWrapper<K, V>>(info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(Nan::New<Integer>(wrapper->_instance->Size)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^ _instance; | |||||
std::function<bool(Local<Value>)> _checkTypeFunc; | |||||
std::function<Local<Value>(K)> _keyGetterFunc; | |||||
std::function<K(Local<Value>)> _convertToKeyTypeFunc; | |||||
std::function<Local<Value>(V)> _valueGetterFunc; | |||||
std::function<bool(Local<Value>)> _checkKeyTypeFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class K, class V> | |||||
Persistent<FunctionTemplate> MapViewWrapper<K, V>::s_constructorTemplate; | |||||
template <class K, class V> | |||||
class MapWrapper : NodeRT::WrapperBase | |||||
{ | |||||
public: | |||||
static void Init() | |||||
{ | |||||
HandleScope scope; | |||||
Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New); | |||||
s_constructorTemplate.Reset(localRef); | |||||
localRef->SetClassName( | |||||
Nan::New<String>("Windows::Foundation::Collections:IMap") | |||||
.ToLocalChecked()); | |||||
localRef->InstanceTemplate()->SetInternalFieldCount(1); | |||||
Nan::SetPrototypeMethod(localRef, "hasKey", HasKey); | |||||
Nan::SetPrototypeMethod(localRef, "lookup", Lookup); | |||||
Nan::SetPrototypeMethod(localRef, "getView", GetView); | |||||
Nan::SetPrototypeMethod(localRef, "clear", Clear); | |||||
Nan::SetPrototypeMethod(localRef, "insert", Insert); | |||||
Nan::SetPrototypeMethod(localRef, "remove", Remove); | |||||
Nan::SetPrototypeMethod(localRef, "first", First); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("size").ToLocalChecked(), SizeGetter); | |||||
Nan::SetAccessor(localRef->PrototypeTemplate(), | |||||
Nan::New<String>("length").ToLocalChecked(), SizeGetter); | |||||
return; | |||||
} | |||||
static Local<Value> CreateMapWrapper( | |||||
::Windows::Foundation::Collections::IMap<K, V> ^ winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkKeyTypeFunc, | |||||
const std::function<K(Local<Value>)> &convertToKeyTypeFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkValueTypeFunc, | |||||
const std::function<V(Local<Value>)> &convertToValueTypeFunc) | |||||
{ | |||||
EscapableHandleScope scope; | |||||
if (winRtInstance == nullptr) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
if (s_constructorTemplate.IsEmpty()) | |||||
{ | |||||
Init(); | |||||
} | |||||
v8::Local<Value> args[] = {Undefined()}; | |||||
Local<FunctionTemplate> localRef = | |||||
Nan::New<FunctionTemplate>(s_constructorTemplate); | |||||
Local<Object> objectInstance = | |||||
Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), 0, args) | |||||
.ToLocalChecked(); | |||||
if (objectInstance.IsEmpty()) | |||||
{ | |||||
return scope.Escape(Undefined()); | |||||
} | |||||
MapWrapper<K, V> *wrapperInstance = new MapWrapper<K, V>( | |||||
winRtInstance, keyGetterFunc, checkKeyTypeFunc, convertToKeyTypeFunc, | |||||
valueGetterFunc, checkValueTypeFunc, convertToValueTypeFunc); | |||||
wrapperInstance->Wrap(objectInstance); | |||||
return scope.Escape(objectInstance); | |||||
} | |||||
virtual ::Platform::Object ^ GetObjectInstance() const override | |||||
{ | |||||
return _instance; | |||||
} | |||||
private: | |||||
MapWrapper(::Windows::Foundation::Collections::IMap<K, V> ^ winRtInstance, | |||||
const std::function<Local<Value>(K)> &keyGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkKeyTypeFunc, | |||||
const std::function<K(Local<Value>)> &convertToKeyTypeFunc, | |||||
const std::function<Local<Value>(V)> &valueGetterFunc, | |||||
const std::function<bool(Local<Value>)> &checkValueTypeFunc, | |||||
const std::function<V(Local<Value>)> &convertToValueTypeFunc) | |||||
: _instance(winRtInstance), | |||||
_keyGetterFunc(keyGetterFunc), | |||||
_checkKeyTypeFunc(checkKeyTypeFunc), | |||||
_convertToKeyTypeFunc(convertToKeyTypeFunc), | |||||
_valueGetterFunc(valueGetterFunc), | |||||
_checkValueTypeFunc(checkValueTypeFunc), | |||||
_convertToValueTypeFunc(convertToValueTypeFunc) {} | |||||
static void New(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
NodeRT::Utils::SetHiddenValue( | |||||
info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), | |||||
True()); | |||||
info.GetReturnValue().Set(info.This()); | |||||
} | |||||
static void HasKey(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkKeyTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
bool result = wrapper->_instance->HasKey(key); | |||||
info.GetReturnValue().Set(Nan::New<Boolean>(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Remove(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkKeyTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
wrapper->_instance->Remove(key); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void Insert(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 2 && wrapper->_checkKeyTypeFunc(info[0]) && | |||||
wrapper->_checkValueTypeFunc(info[1])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
V value = wrapper->_convertToValueTypeFunc(info[1]); | |||||
bool result = wrapper->_instance->Insert(key, value); | |||||
info.GetReturnValue().Set(Nan::New<Boolean>(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void First(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
const std::function<Local<Value>(K)> &keyGetter = | |||||
wrapper->_keyGetterFunc; | |||||
const std::function<Local<Value>(V)> &valueGetter = | |||||
wrapper->_valueGetterFunc; | |||||
info.GetReturnValue().Set( | |||||
IteratorWrapper< | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, V> ^>:: | |||||
CreateIteratorWrapper( | |||||
wrapper->_instance->First(), | |||||
[keyGetter, valueGetter]( | |||||
::Windows::Foundation::Collections::IKeyValuePair<K, | |||||
V> ^ | |||||
value) | |||||
{ | |||||
return KeyValuePairWrapper< | |||||
K, V>::CreateKeyValuePairWrapper(value, keyGetter, | |||||
valueGetter); | |||||
})); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void Lookup(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 1 && wrapper->_checkKeyTypeFunc(info[0])) | |||||
{ | |||||
try | |||||
{ | |||||
K key = wrapper->_convertToKeyTypeFunc(info[0]); | |||||
V result = wrapper->_instance->Lookup(key); | |||||
info.GetReturnValue().Set(wrapper->_valueGetterFunc(result)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
return; | |||||
} | |||||
static void GetView(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
::Windows::Foundation::Collections::IMapView<K, V> ^ result = | |||||
wrapper->_instance->GetView(); | |||||
info.GetReturnValue().Set(MapViewWrapper<K, V>::CreateMapViewWrapper( | |||||
result, wrapper->_keyGetterFunc, wrapper->_checkKeyTypeFunc, | |||||
wrapper->_convertToKeyTypeFunc, wrapper->_valueGetterFunc)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void Clear(Nan::NAN_METHOD_ARGS_TYPE info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
if (info.Length() == 0) | |||||
{ | |||||
try | |||||
{ | |||||
wrapper->_instance->Clear(); | |||||
return; | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString( | |||||
L"Bad arguments: no suitable overload found"))); | |||||
return; | |||||
} | |||||
} | |||||
static void SizeGetter(Local<String> property, | |||||
const Nan::PropertyCallbackInfo<v8::Value> &info) | |||||
{ | |||||
HandleScope scope; | |||||
if (!NodeRT::Utils::IsWinRtWrapperOf< | |||||
::Windows::Foundation::Collections::IMap<K, V> ^>(info.This())) | |||||
{ | |||||
return; | |||||
} | |||||
MapWrapper<K, V> *wrapper = | |||||
MapWrapper<K, V>::Unwrap<MapWrapper<K, V>>(info.This()); | |||||
try | |||||
{ | |||||
info.GetReturnValue().Set(Nan::New<Integer>(wrapper->_instance->Size)); | |||||
} | |||||
catch (Platform::Exception ^ exception) | |||||
{ | |||||
NodeRT::Utils::ThrowWinRtExceptionInJs(exception); | |||||
return; | |||||
} | |||||
} | |||||
private: | |||||
::Windows::Foundation::Collections::IMap<K, V> ^ _instance; | |||||
std::function<Local<Value>(K)> _keyGetterFunc; | |||||
std::function<K(Local<Value>)> _convertToKeyTypeFunc; | |||||
std::function<bool(Local<Value>)> _checkKeyTypeFunc; | |||||
std::function<Local<Value>(V)> _valueGetterFunc; | |||||
std::function<V(Local<Value>)> _convertToValueTypeFunc; | |||||
std::function<bool(Local<Value>)> _checkValueTypeFunc; | |||||
static Persistent<FunctionTemplate> s_constructorTemplate; | |||||
}; | |||||
template <class K, class V> | |||||
Persistent<FunctionTemplate> MapWrapper<K, V>::s_constructorTemplate; | |||||
} // namespace Collections | |||||
}; // namespace NodeRT |