src: refactor to use nan
- Now it supports latest 0.8.x, 0.10.x and 0.11.x
This commit is contained in:
@@ -4,7 +4,8 @@
|
|||||||
'target_name': 'pcsclite',
|
'target_name': 'pcsclite',
|
||||||
'sources': [ 'src/addon.cpp', 'src/pcsclite.cpp', 'src/cardreader.cpp' ],
|
'sources': [ 'src/addon.cpp', 'src/pcsclite.cpp', 'src/cardreader.cpp' ],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'/usr/include/PCSC'
|
'/usr/include/PCSC',
|
||||||
|
'<!(node -e "require(\'nan\')")'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [
|
'libraries': [
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffertools": "^2.1.2",
|
"buffertools": "^2.1.2",
|
||||||
"bindings": "~1.1.0"
|
"bindings": "^1.1.0",
|
||||||
|
"nan": "^1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha": "~1.11.0",
|
"mocha": "~1.11.0",
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
#include "cardreader.h"
|
#include "cardreader.h"
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <v8.h>
|
|
||||||
#include <node_buffer.h>
|
|
||||||
#include <pcsclite.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
using namespace node;
|
using namespace node;
|
||||||
@@ -14,64 +8,48 @@ Persistent<Function> CardReader::constructor;
|
|||||||
void CardReader::init(Handle<Object> target) {
|
void CardReader::init(Handle<Object> target) {
|
||||||
|
|
||||||
// Prepare constructor template
|
// Prepare constructor template
|
||||||
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
|
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
|
||||||
tpl->SetClassName(String::NewSymbol("CardReader"));
|
tpl->SetClassName(NanNew("CardReader"));
|
||||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
|
|
||||||
// Symbol
|
// Symbol
|
||||||
name_symbol = NODE_PSYMBOL("name");
|
NanAssignPersistent(name_symbol, NanNew("name"));
|
||||||
connected_symbol = NODE_PSYMBOL("connected");
|
NanAssignPersistent(connected_symbol, NanNew("connected"));
|
||||||
|
|
||||||
// Prototype
|
// Prototype
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "get_status", GetStatus);
|
NanSetPrototypeTemplate(tpl, "get_status", NanNew<FunctionTemplate>(GetStatus));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "_connect", Connect);
|
NanSetPrototypeTemplate(tpl, "_connect", NanNew<FunctionTemplate>(Connect));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "_disconnect", Disconnect);
|
NanSetPrototypeTemplate(tpl, "_disconnect", NanNew<FunctionTemplate>(Disconnect));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "_transmit", Transmit);
|
NanSetPrototypeTemplate(tpl, "_transmit", NanNew<FunctionTemplate>(Transmit));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "_control", Control);
|
NanSetPrototypeTemplate(tpl, "_control", NanNew<FunctionTemplate>(Control));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close);
|
NanSetPrototypeTemplate(tpl, "close", NanNew<FunctionTemplate>(Close));
|
||||||
|
|
||||||
// PCSCLite constants
|
// PCSCLite constants
|
||||||
// Share Mode
|
// Share Mode
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_SHARE_SHARED"),
|
NanSetPrototypeTemplate(tpl, "SCARD_SHARE_SHARED", NanNew(SCARD_SHARE_SHARED));
|
||||||
Integer::New(SCARD_SHARE_SHARED));
|
NanSetPrototypeTemplate(tpl, "SCARD_SHARE_EXCLUSIVE", NanNew(SCARD_SHARE_EXCLUSIVE));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_SHARE_EXCLUSIVE"),
|
NanSetPrototypeTemplate(tpl, "SCARD_SHARE_DIRECT", NanNew(SCARD_SHARE_DIRECT));
|
||||||
Integer::New(SCARD_SHARE_EXCLUSIVE));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_SHARE_DIRECT"),
|
|
||||||
Integer::New(SCARD_SHARE_DIRECT));
|
|
||||||
// Protocol
|
// Protocol
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_PROTOCOL_T0"),
|
NanSetPrototypeTemplate(tpl, "SCARD_PROTOCOL_T0", NanNew(SCARD_PROTOCOL_T0));
|
||||||
Integer::New(SCARD_PROTOCOL_T0));
|
NanSetPrototypeTemplate(tpl, "SCARD_PROTOCOL_T1", NanNew(SCARD_PROTOCOL_T1));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_PROTOCOL_T1"),
|
NanSetPrototypeTemplate(tpl, "SCARD_PROTOCOL_RAW", NanNew(SCARD_PROTOCOL_RAW));
|
||||||
Integer::New(SCARD_PROTOCOL_T1));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_PROTOCOL_RAW"),
|
|
||||||
Integer::New(SCARD_PROTOCOL_RAW));
|
|
||||||
// State
|
// State
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_UNAWARE"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_UNAWARE", NanNew(SCARD_STATE_UNAWARE));
|
||||||
Integer::New(SCARD_STATE_UNAWARE));
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_IGNORE", NanNew(SCARD_STATE_IGNORE));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_IGNORE"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_CHANGED", NanNew(SCARD_STATE_CHANGED));
|
||||||
Integer::New(SCARD_STATE_IGNORE));
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_UNKNOWN", NanNew(SCARD_STATE_UNKNOWN));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_CHANGED"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_UNAVAILABLE", NanNew(SCARD_STATE_UNAVAILABLE));
|
||||||
Integer::New(SCARD_STATE_CHANGED));
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_EMPTY", NanNew(SCARD_STATE_EMPTY));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_UNKNOWN"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_PRESENT", NanNew(SCARD_STATE_PRESENT));
|
||||||
Integer::New(SCARD_STATE_UNKNOWN));
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_ATRMATCH", NanNew(SCARD_STATE_ATRMATCH));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_UNAVAILABLE"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_EXCLUSIVE", NanNew(SCARD_STATE_EXCLUSIVE));
|
||||||
Integer::New(SCARD_STATE_UNAVAILABLE));
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_INUSE", NanNew(SCARD_STATE_INUSE));
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_EMPTY"),
|
NanSetPrototypeTemplate(tpl, "SCARD_STATE_MUTE", NanNew(SCARD_STATE_MUTE));
|
||||||
Integer::New(SCARD_STATE_EMPTY));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_PRESENT"),
|
|
||||||
Integer::New(SCARD_STATE_PRESENT));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_ATRMATCH"),
|
|
||||||
Integer::New(SCARD_STATE_ATRMATCH));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_EXCLUSIVE"),
|
|
||||||
Integer::New(SCARD_STATE_EXCLUSIVE));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_INUSE"),
|
|
||||||
Integer::New(SCARD_STATE_INUSE));
|
|
||||||
tpl->PrototypeTemplate()->Set(String::NewSymbol("SCARD_STATE_MUTE"),
|
|
||||||
Integer::New(SCARD_STATE_MUTE));
|
|
||||||
|
|
||||||
|
NanAssignPersistent<Function>(constructor, tpl->GetFunction());
|
||||||
constructor = Persistent<Function>::New(tpl->GetFunction());
|
target->Set(NanNew("CardReader"), tpl->GetFunction());
|
||||||
target->Set(String::NewSymbol("CardReader"), constructor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CardReader::CardReader(const std::string &reader_name): m_card_context(0),
|
CardReader::CardReader(const std::string &reader_name): m_card_context(0),
|
||||||
@@ -93,56 +71,53 @@ CardReader::~CardReader() {
|
|||||||
pthread_mutex_destroy(&m_mutex);
|
pthread_mutex_destroy(&m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::New(const Arguments& args) {
|
NAN_METHOD(CardReader::New) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
v8::String::Utf8Value reader_name(args[0]->ToString());
|
v8::String::Utf8Value reader_name(args[0]->ToString());
|
||||||
CardReader* obj = new CardReader(*reader_name);
|
CardReader* obj = new CardReader(*reader_name);
|
||||||
obj->Wrap(args.Holder());
|
obj->Wrap(args.Holder());
|
||||||
obj->handle_->Set(name_symbol, args[0]->ToString());
|
NanObjectWrapHandle(obj)->Set(NanNew(name_symbol), args[0]->ToString());
|
||||||
obj->handle_->Set(connected_symbol, Boolean::New(false));
|
NanObjectWrapHandle(obj)->Set(NanNew(connected_symbol), NanFalse());
|
||||||
|
|
||||||
return scope.Close(args.Holder());
|
NanReturnValue(args.Holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::GetStatus(const Arguments& args) {
|
NAN_METHOD(CardReader::GetStatus) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
Local<Function> cb = Local<Function>::Cast(args[0]);
|
Local<Function> cb = Local<Function>::Cast(args[0]);
|
||||||
|
|
||||||
AsyncBaton *async_baton = new AsyncBaton();
|
AsyncBaton *async_baton = new AsyncBaton();
|
||||||
async_baton->async.data = async_baton;
|
async_baton->async.data = async_baton;
|
||||||
async_baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(async_baton->callback, cb);
|
||||||
async_baton->reader = obj;
|
async_baton->reader = obj;
|
||||||
|
|
||||||
uv_async_init(uv_default_loop(), &async_baton->async, HandleReaderStatusChange);
|
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
||||||
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
||||||
pthread_detach(obj->m_status_thread);
|
pthread_detach(obj->m_status_thread);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::Connect(const Arguments& args) {
|
NAN_METHOD(CardReader::Connect) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
// The second argument is the length of the data to be received
|
// The second argument is the length of the data to be received
|
||||||
if (!args[0]->IsUint32()) {
|
if (!args[0]->IsUint32()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("First argument must be an integer");
|
||||||
String::New("First argument must be an integer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args[1]->IsUint32()) {
|
if (!args[1]->IsUint32()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Second argument must be an integer");
|
||||||
String::New("Second argument must be an integer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args[2]->IsFunction()) {
|
if (!args[2]->IsFunction()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Third argument must be a callback function");
|
||||||
String::New("Third argument must be a callback function")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectInput* ci = new ConnectInput();
|
ConnectInput* ci = new ConnectInput();
|
||||||
@@ -153,26 +128,28 @@ Handle<Value> CardReader::Connect(const Arguments& args) {
|
|||||||
// This creates our work request, including the libuv struct.
|
// This creates our work request, including the libuv struct.
|
||||||
Baton* baton = new Baton();
|
Baton* baton = new Baton();
|
||||||
baton->request.data = baton;
|
baton->request.data = baton;
|
||||||
baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(baton->callback, cb);
|
||||||
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
baton->input = ci;
|
baton->input = ci;
|
||||||
|
|
||||||
// Schedule our work request with libuv. Here you can specify the functions
|
// Schedule our work request with libuv. Here you can specify the functions
|
||||||
// that should be executed in the threadpool and back in the main thread
|
// that should be executed in the threadpool and back in the main thread
|
||||||
// after the threadpool function completed.
|
// after the threadpool function completed.
|
||||||
int status = uv_queue_work(uv_default_loop(), &baton->request, DoConnect, AfterConnect);
|
int status = uv_queue_work(uv_default_loop(),
|
||||||
|
&baton->request,
|
||||||
|
DoConnect,
|
||||||
|
reinterpret_cast<uv_after_work_cb>(AfterConnect));
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::Disconnect(const Arguments& args) {
|
NAN_METHOD(CardReader::Disconnect) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
if (!args[0]->IsFunction()) {
|
if (!args[0]->IsFunction()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("First argument must be a callback function");
|
||||||
String::New("First argument must be a callback function")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Function> cb = Local<Function>::Cast(args[0]);
|
Local<Function> cb = Local<Function>::Cast(args[0]);
|
||||||
@@ -180,44 +157,43 @@ Handle<Value> CardReader::Disconnect(const Arguments& args) {
|
|||||||
// This creates our work request, including the libuv struct.
|
// This creates our work request, including the libuv struct.
|
||||||
Baton* baton = new Baton();
|
Baton* baton = new Baton();
|
||||||
baton->request.data = baton;
|
baton->request.data = baton;
|
||||||
baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(baton->callback, cb);
|
||||||
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
|
|
||||||
// Schedule our work request with libuv. Here you can specify the functions
|
// Schedule our work request with libuv. Here you can specify the functions
|
||||||
// that should be executed in the threadpool and back in the main thread
|
// that should be executed in the threadpool and back in the main thread
|
||||||
// after the threadpool function completed.
|
// after the threadpool function completed.
|
||||||
int status = uv_queue_work(uv_default_loop(), &baton->request, DoDisconnect, AfterDisconnect);
|
int status = uv_queue_work(uv_default_loop(),
|
||||||
|
&baton->request,
|
||||||
|
DoDisconnect,
|
||||||
|
reinterpret_cast<uv_after_work_cb>(AfterDisconnect));
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::Transmit(const Arguments& args) {
|
NAN_METHOD(CardReader::Transmit) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
// The first argument is the buffer to be transmitted.
|
// The first argument is the buffer to be transmitted.
|
||||||
if (!Buffer::HasInstance(args[0])) {
|
if (!Buffer::HasInstance(args[0])) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("First argument must be a Buffer");
|
||||||
String::New("First argument must be a Buffer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second argument is the length of the data to be received
|
// The second argument is the length of the data to be received
|
||||||
if (!args[1]->IsUint32()) {
|
if (!args[1]->IsUint32()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Second argument must be an integer");
|
||||||
String::New("Second argument must be an integer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The third argument is the protocol to be used
|
// The third argument is the protocol to be used
|
||||||
if (!args[2]->IsUint32()) {
|
if (!args[2]->IsUint32()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Third argument must be an integer");
|
||||||
String::New("Third argument must be an integer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fourth argument is the callback function
|
// The fourth argument is the callback function
|
||||||
if (!args[3]->IsFunction()) {
|
if (!args[3]->IsFunction()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Fourth argument must be a callback function");
|
||||||
String::New("Fourth argument must be a callback function")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Object> buffer_data = args[0]->ToObject();
|
Local<Object> buffer_data = args[0]->ToObject();
|
||||||
@@ -228,7 +204,7 @@ Handle<Value> CardReader::Transmit(const Arguments& args) {
|
|||||||
// This creates our work request, including the libuv struct.
|
// This creates our work request, including the libuv struct.
|
||||||
Baton* baton = new Baton();
|
Baton* baton = new Baton();
|
||||||
baton->request.data = baton;
|
baton->request.data = baton;
|
||||||
baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(baton->callback, cb);
|
||||||
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
TransmitInput *ti = new TransmitInput();
|
TransmitInput *ti = new TransmitInput();
|
||||||
ti->card_protocol = protocol;
|
ti->card_protocol = protocol;
|
||||||
@@ -242,38 +218,37 @@ Handle<Value> CardReader::Transmit(const Arguments& args) {
|
|||||||
// Schedule our work request with libuv. Here you can specify the functions
|
// Schedule our work request with libuv. Here you can specify the functions
|
||||||
// that should be executed in the threadpool and back in the main thread
|
// that should be executed in the threadpool and back in the main thread
|
||||||
// after the threadpool function completed.
|
// after the threadpool function completed.
|
||||||
int status = uv_queue_work(uv_default_loop(), &baton->request, DoTransmit, AfterTransmit);
|
int status = uv_queue_work(uv_default_loop(),
|
||||||
|
&baton->request,
|
||||||
|
DoTransmit,
|
||||||
|
reinterpret_cast<uv_after_work_cb>(AfterTransmit));
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::Control(const Arguments& args) {
|
NAN_METHOD(CardReader::Control) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
// The first argument is the buffer to be transmitted.
|
// The first argument is the buffer to be transmitted.
|
||||||
if (!Buffer::HasInstance(args[0])) {
|
if (!Buffer::HasInstance(args[0])) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("First argument must be a Buffer");
|
||||||
String::New("First argument must be a Buffer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second argument is the control code to be used
|
// The second argument is the control code to be used
|
||||||
if (!args[1]->IsUint32()) {
|
if (!args[1]->IsUint32()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Second argument must be an integer");
|
||||||
String::New("Second argument must be an integer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The third argument is output buffer
|
// The third argument is output buffer
|
||||||
if (!Buffer::HasInstance(args[2])) {
|
if (!Buffer::HasInstance(args[2])) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Third argument must be a Buffer");
|
||||||
String::New("First argument must be a Buffer")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fourth argument is the callback function
|
// The fourth argument is the callback function
|
||||||
if (!args[3]->IsFunction()) {
|
if (!args[3]->IsFunction()) {
|
||||||
return ThrowException(Exception::TypeError(
|
NanThrowError("Fourth argument must be a callback function");
|
||||||
String::New("Fourth argument must be a callback function")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Object> in_buf = args[0]->ToObject();
|
Local<Object> in_buf = args[0]->ToObject();
|
||||||
@@ -284,7 +259,7 @@ Handle<Value> CardReader::Control(const Arguments& args) {
|
|||||||
// This creates our work request, including the libuv struct.
|
// This creates our work request, including the libuv struct.
|
||||||
Baton* baton = new Baton();
|
Baton* baton = new Baton();
|
||||||
baton->request.data = baton;
|
baton->request.data = baton;
|
||||||
baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(baton->callback, cb);
|
||||||
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
baton->reader = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
ControlInput *ci = new ControlInput();
|
ControlInput *ci = new ControlInput();
|
||||||
ci->control_code = control_code;
|
ci->control_code = control_code;
|
||||||
@@ -297,26 +272,31 @@ Handle<Value> CardReader::Control(const Arguments& args) {
|
|||||||
// Schedule our work request with libuv. Here you can specify the functions
|
// Schedule our work request with libuv. Here you can specify the functions
|
||||||
// that should be executed in the threadpool and back in the main thread
|
// that should be executed in the threadpool and back in the main thread
|
||||||
// after the threadpool function completed.
|
// after the threadpool function completed.
|
||||||
int status = uv_queue_work(uv_default_loop(), &baton->request, DoControl, AfterControl);
|
int status = uv_queue_work(uv_default_loop(),
|
||||||
|
&baton->request,
|
||||||
|
DoControl,
|
||||||
|
reinterpret_cast<uv_after_work_cb>(AfterControl));
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::Close(const Arguments& args) {
|
NAN_METHOD(CardReader::Close) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
|
|
||||||
LONG result = SCardCancel(obj->m_status_card_context);
|
LONG result = SCardCancel(obj->m_status_card_context);
|
||||||
obj->m_status_card_context = 0;
|
obj->m_status_card_context = 0;
|
||||||
|
|
||||||
return scope.Close(Integer::New(result));
|
NanReturnValue(NanNew<Integer>(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
||||||
|
|
||||||
|
NanScope();
|
||||||
|
|
||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
||||||
AsyncResult* ar = async_baton->async_result;
|
AsyncResult* ar = async_baton->async_result;
|
||||||
|
|
||||||
@@ -325,28 +305,28 @@ void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
|
|
||||||
/* Emit end event */
|
/* Emit end event */
|
||||||
Handle<Value> argv[1] = {
|
Handle<Value> argv[1] = {
|
||||||
String::New("end"), // event name
|
NanNew("end"), // event name
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeCallback(async_baton->reader->handle_, "emit", 1, argv);
|
NanMakeCallback(NanObjectWrapHandle(async_baton->reader), "emit", 1, argv);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ar->result == SCARD_S_SUCCESS) {
|
if (ar->result == SCARD_S_SUCCESS) {
|
||||||
const unsigned argc = 3;
|
const unsigned argc = 3;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Undefined(), // argument
|
NanUndefined(), // argument
|
||||||
Integer::New(ar->status),
|
NanNew<Integer>(ar->status),
|
||||||
CreateBufferInstance(reinterpret_cast<char*>(ar->atr), ar->atrlen)
|
NanNewBufferHandle(reinterpret_cast<char*>(ar->atr), ar->atrlen)
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(async_baton->reader->handle_, async_baton->callback, argc, argv);
|
NanCallback(NanNew(async_baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(ar->result)));
|
Local<Value> err = NanError(pcsc_stringify_error(ar->result));
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(async_baton->reader->handle_, async_baton->callback, argc, argv);
|
NanCallback(NanNew(async_baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,36 +403,32 @@ void CardReader::DoConnect(uv_work_t* req) {
|
|||||||
baton->result = cr;
|
baton->result = cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NODE_VERSION_AT_LEAST(0, 9, 4)
|
|
||||||
void CardReader::AfterConnect(uv_work_t* req, int status) {
|
void CardReader::AfterConnect(uv_work_t* req, int status) {
|
||||||
#else
|
|
||||||
void CardReader::AfterConnect(uv_work_t* req) {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
Baton* baton = static_cast<Baton*>(req->data);
|
Baton* baton = static_cast<Baton*>(req->data);
|
||||||
ConnectInput *ci = static_cast<ConnectInput*>(baton->input);
|
ConnectInput *ci = static_cast<ConnectInput*>(baton->input);
|
||||||
ConnectResult *cr = static_cast<ConnectResult*>(baton->result);
|
ConnectResult *cr = static_cast<ConnectResult*>(baton->result);
|
||||||
|
|
||||||
if (cr->result) {
|
if (cr->result) {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(cr->result)));
|
Local<Value> err = NanError(pcsc_stringify_error(cr->result));
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
baton->reader->handle_->Set(connected_symbol, Boolean::New(true));
|
NanObjectWrapHandle(baton->reader)->Set(NanNew(connected_symbol), NanTrue());
|
||||||
const unsigned argc = 2;
|
const unsigned argc = 2;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Local<Value>::New(Null()),
|
NanNull(),
|
||||||
Integer::New(cr->card_protocol)
|
NanNew<Integer>(cr->card_protocol)
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The callback is a permanent handle, so we have to dispose of it manually.
|
// The callback is a permanent handle, so we have to dispose of it manually.
|
||||||
baton->callback.Dispose();
|
NanDisposePersistent(baton->callback);
|
||||||
delete ci;
|
delete ci;
|
||||||
delete cr;
|
delete cr;
|
||||||
delete baton;
|
delete baton;
|
||||||
@@ -481,35 +457,31 @@ void CardReader::DoDisconnect(uv_work_t* req) {
|
|||||||
baton->result = reinterpret_cast<void*>(result);
|
baton->result = reinterpret_cast<void*>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NODE_VERSION_AT_LEAST(0, 9, 4)
|
|
||||||
void CardReader::AfterDisconnect(uv_work_t* req, int status) {
|
void CardReader::AfterDisconnect(uv_work_t* req, int status) {
|
||||||
#else
|
|
||||||
void CardReader::AfterDisconnect(uv_work_t* req) {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
Baton* baton = static_cast<Baton*>(req->data);
|
Baton* baton = static_cast<Baton*>(req->data);
|
||||||
LONG result = reinterpret_cast<LONG>(baton->result);
|
LONG result = reinterpret_cast<LONG>(baton->result);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(result)));
|
Local<Value> err = NanError(pcsc_stringify_error(result));
|
||||||
|
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
baton->reader->handle_->Set(connected_symbol, Boolean::New(false));
|
NanObjectWrapHandle(baton->reader)->Set(NanNew(connected_symbol), NanFalse());
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Local<Value>::New(Null())
|
NanNull()
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The callback is a permanent handle, so we have to dispose of it manually.
|
// The callback is a permanent handle, so we have to dispose of it manually.
|
||||||
baton->callback.Dispose();
|
NanDisposePersistent(baton->callback);
|
||||||
|
|
||||||
delete baton;
|
delete baton;
|
||||||
}
|
}
|
||||||
@@ -543,37 +515,33 @@ void CardReader::DoTransmit(uv_work_t* req) {
|
|||||||
baton->result = tr;
|
baton->result = tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NODE_VERSION_AT_LEAST(0, 9, 4)
|
|
||||||
void CardReader::AfterTransmit(uv_work_t* req, int status) {
|
void CardReader::AfterTransmit(uv_work_t* req, int status) {
|
||||||
#else
|
|
||||||
void CardReader::AfterTransmit(uv_work_t* req) {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
Baton* baton = static_cast<Baton*>(req->data);
|
Baton* baton = static_cast<Baton*>(req->data);
|
||||||
TransmitInput *ti = static_cast<TransmitInput*>(baton->input);
|
TransmitInput *ti = static_cast<TransmitInput*>(baton->input);
|
||||||
TransmitResult *tr = static_cast<TransmitResult*>(baton->result);
|
TransmitResult *tr = static_cast<TransmitResult*>(baton->result);
|
||||||
|
|
||||||
if (tr->result) {
|
if (tr->result) {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(tr->result)));
|
Local<Value> err = NanError(pcsc_stringify_error(tr->result));
|
||||||
|
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
const unsigned argc = 2;
|
const unsigned argc = 2;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Local<Value>::New(Null()),
|
NanNull(),
|
||||||
CreateBufferInstance(reinterpret_cast<char*>(tr->data), tr->len)
|
NanNewBufferHandle(reinterpret_cast<char*>(tr->data), tr->len)
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The callback is a permanent handle, so we have to dispose of it manually.
|
// The callback is a permanent handle, so we have to dispose of it manually.
|
||||||
baton->callback.Dispose();
|
NanDisposePersistent(baton->callback);
|
||||||
delete [] ti->in_data;
|
delete [] ti->in_data;
|
||||||
delete ti;
|
delete ti;
|
||||||
delete [] tr->data;
|
delete [] tr->data;
|
||||||
@@ -611,37 +579,33 @@ void CardReader::DoControl(uv_work_t* req) {
|
|||||||
baton->result = cr;
|
baton->result = cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NODE_VERSION_AT_LEAST(0, 9, 4)
|
|
||||||
void CardReader::AfterControl(uv_work_t* req, int status) {
|
void CardReader::AfterControl(uv_work_t* req, int status) {
|
||||||
#else
|
|
||||||
void CardReader::AfterControl(uv_work_t* req) {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
Baton* baton = static_cast<Baton*>(req->data);
|
Baton* baton = static_cast<Baton*>(req->data);
|
||||||
ControlInput *ci = static_cast<ControlInput*>(baton->input);
|
ControlInput *ci = static_cast<ControlInput*>(baton->input);
|
||||||
ControlResult *cr = static_cast<ControlResult*>(baton->result);
|
ControlResult *cr = static_cast<ControlResult*>(baton->result);
|
||||||
|
|
||||||
if (cr->result) {
|
if (cr->result) {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(cr->result)));
|
Local<Value> err = NanError(pcsc_stringify_error(cr->result));
|
||||||
|
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
const unsigned argc = 2;
|
const unsigned argc = 2;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Local<Value>::New(Null()),
|
NanNull(),
|
||||||
Integer::New(cr->len)
|
NanNew<Integer>(cr->len)
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
|
NanCallback(NanNew(baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The callback is a permanent handle, so we have to dispose of it manually.
|
// The callback is a permanent handle, so we have to dispose of it manually.
|
||||||
baton->callback.Dispose();
|
NanDisposePersistent(baton->callback);
|
||||||
delete ci;
|
delete ci;
|
||||||
delete cr;
|
delete cr;
|
||||||
delete baton;
|
delete baton;
|
||||||
@@ -653,26 +617,7 @@ void CardReader::CloseCallback(uv_handle_t *handle) {
|
|||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
||||||
AsyncResult* ar = async_baton->async_result;
|
AsyncResult* ar = async_baton->async_result;
|
||||||
delete ar;
|
delete ar;
|
||||||
async_baton->callback.Dispose();
|
NanDisposePersistent(async_baton->callback);
|
||||||
SCardReleaseContext(async_baton->reader->m_status_card_context);
|
SCardReleaseContext(async_baton->reader->m_status_card_context);
|
||||||
delete async_baton;
|
delete async_baton;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> CardReader::CreateBufferInstance(char* data, unsigned long size) {
|
|
||||||
if (size == 0) {
|
|
||||||
return Undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get Buffer from global scope.
|
|
||||||
Local<Object> global = Context::GetCurrent()->Global();
|
|
||||||
Local<Value> bv = global->Get(String::NewSymbol("Buffer"));
|
|
||||||
assert(bv->IsFunction());
|
|
||||||
Local<Function> b = Local<Function>::Cast(bv);
|
|
||||||
Handle<Value> argv[3] = {
|
|
||||||
Buffer::New(data, size)->handle_,
|
|
||||||
Integer::New(size),
|
|
||||||
Integer::New(0)
|
|
||||||
};
|
|
||||||
|
|
||||||
return b->NewInstance(3, argv);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef CARDREADER_H
|
#ifndef CARDREADER_H
|
||||||
#define CARDREADER_H
|
#define CARDREADER_H
|
||||||
|
|
||||||
#include <node.h>
|
#include <nan.h>
|
||||||
#include <node_version.h>
|
#include <node_version.h>
|
||||||
#include <winscard.h>
|
#include <winscard.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -84,13 +84,14 @@ class CardReader: public node::ObjectWrap {
|
|||||||
~CardReader();
|
~CardReader();
|
||||||
|
|
||||||
static v8::Persistent<v8::Function> constructor;
|
static v8::Persistent<v8::Function> constructor;
|
||||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
|
||||||
static v8::Handle<v8::Value> GetStatus(const v8::Arguments& args);
|
static NAN_METHOD(New);
|
||||||
static v8::Handle<v8::Value> Connect(const v8::Arguments& args);
|
static NAN_METHOD(GetStatus);
|
||||||
static v8::Handle<v8::Value> Disconnect(const v8::Arguments& args);
|
static NAN_METHOD(Connect);
|
||||||
static v8::Handle<v8::Value> Transmit(const v8::Arguments& args);
|
static NAN_METHOD(Disconnect);
|
||||||
static v8::Handle<v8::Value> Control(const v8::Arguments& args);
|
static NAN_METHOD(Transmit);
|
||||||
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
|
static NAN_METHOD(Control);
|
||||||
|
static NAN_METHOD(Close);
|
||||||
|
|
||||||
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
||||||
static void* HandlerFunction(void* arg);
|
static void* HandlerFunction(void* arg);
|
||||||
@@ -100,18 +101,10 @@ class CardReader: public node::ObjectWrap {
|
|||||||
static void DoControl(uv_work_t* req);
|
static void DoControl(uv_work_t* req);
|
||||||
static void CloseCallback(uv_handle_t *handle);
|
static void CloseCallback(uv_handle_t *handle);
|
||||||
|
|
||||||
#if NODE_VERSION_AT_LEAST(0, 9, 4)
|
|
||||||
static void AfterConnect(uv_work_t* req, int status);
|
static void AfterConnect(uv_work_t* req, int status);
|
||||||
static void AfterDisconnect(uv_work_t* req, int status);
|
static void AfterDisconnect(uv_work_t* req, int status);
|
||||||
static void AfterTransmit(uv_work_t* req, int status);
|
static void AfterTransmit(uv_work_t* req, int status);
|
||||||
static void AfterControl(uv_work_t* req, int status);
|
static void AfterControl(uv_work_t* req, int status);
|
||||||
#else
|
|
||||||
static void AfterConnect(uv_work_t* req);
|
|
||||||
static void AfterDisconnect(uv_work_t* req);
|
|
||||||
static void AfterTransmit(uv_work_t* req);
|
|
||||||
static void AfterControl(uv_work_t* req);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static v8::Handle<v8::Value> CreateBufferInstance(char* data, unsigned long size);
|
static v8::Handle<v8::Value> CreateBufferInstance(char* data, unsigned long size);
|
||||||
|
|
||||||
|
|||||||
21
src/common.h
21
src/common.h
@@ -1,21 +0,0 @@
|
|||||||
#ifndef COMMON_H
|
|
||||||
#define COMMON_H
|
|
||||||
|
|
||||||
#include <node.h>
|
|
||||||
|
|
||||||
static void PerformCallback(v8::Handle<v8::Object> object,
|
|
||||||
v8::Persistent<v8::Function> &callback,
|
|
||||||
const unsigned argc, v8::Handle<v8::Value> *argv) {
|
|
||||||
|
|
||||||
// Wrap the callback function call in a TryCatch so that we can call
|
|
||||||
// node's FatalException afterwards. This makes it possible to catch
|
|
||||||
// the exception from JavaScript land using the
|
|
||||||
// process.on('uncaughtException') event.
|
|
||||||
v8::TryCatch try_catch;
|
|
||||||
callback->Call(object, argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* COMMON_H */
|
|
||||||
@@ -1,11 +1,4 @@
|
|||||||
#include "pcsclite.h"
|
#include "pcsclite.h"
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <v8.h>
|
|
||||||
#include <pcsclite.h>
|
|
||||||
#include <node_buffer.h>
|
|
||||||
#include <string>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
using namespace node;
|
using namespace node;
|
||||||
@@ -15,15 +8,15 @@ Persistent<Function> PCSCLite::constructor;
|
|||||||
void PCSCLite::init(Handle<Object> target) {
|
void PCSCLite::init(Handle<Object> target) {
|
||||||
|
|
||||||
// Prepare constructor template
|
// Prepare constructor template
|
||||||
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
|
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
|
||||||
tpl->SetClassName(String::NewSymbol("PCSCLite"));
|
tpl->SetClassName(NanNew("PCSCLite"));
|
||||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
// Prototype
|
// Prototype
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "start", Start);
|
NanSetPrototypeTemplate(tpl, "start", NanNew<FunctionTemplate>(Start));
|
||||||
NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close);
|
NanSetPrototypeTemplate(tpl, "close", NanNew<FunctionTemplate>(Close));
|
||||||
|
|
||||||
constructor = Persistent<Function>::New(tpl->GetFunction());
|
NanAssignPersistent<Function>(constructor, tpl->GetFunction());
|
||||||
target->Set(String::NewSymbol("PCSCLite"), constructor);
|
target->Set(NanNew("PCSCLite"), tpl->GetFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
PCSCLite::PCSCLite(): m_card_context(0) {
|
PCSCLite::PCSCLite(): m_card_context(0) {
|
||||||
@@ -39,46 +32,47 @@ PCSCLite::~PCSCLite() {
|
|||||||
pthread_cancel(m_status_thread);
|
pthread_cancel(m_status_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> PCSCLite::New(const Arguments& args) {
|
NAN_METHOD(PCSCLite::New) {
|
||||||
|
NanScope();
|
||||||
HandleScope scope;
|
|
||||||
PCSCLite* obj = new PCSCLite();
|
PCSCLite* obj = new PCSCLite();
|
||||||
obj->Wrap(args.Holder());
|
obj->Wrap(args.Holder());
|
||||||
return scope.Close(args.Holder());
|
NanReturnValue(args.Holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> PCSCLite::Start(const Arguments& args) {
|
NAN_METHOD(PCSCLite::Start) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
PCSCLite* obj = ObjectWrap::Unwrap<PCSCLite>(args.This());
|
PCSCLite* obj = ObjectWrap::Unwrap<PCSCLite>(args.This());
|
||||||
Local<Function> cb = Local<Function>::Cast(args[0]);
|
Local<Function> cb = Local<Function>::Cast(args[0]);
|
||||||
|
|
||||||
AsyncBaton *async_baton = new AsyncBaton();
|
AsyncBaton *async_baton = new AsyncBaton();
|
||||||
async_baton->async.data = async_baton;
|
async_baton->async.data = async_baton;
|
||||||
async_baton->callback = Persistent<Function>::New(cb);
|
NanAssignPersistent(async_baton->callback, cb);
|
||||||
async_baton->pcsclite = obj;
|
async_baton->pcsclite = obj;
|
||||||
|
|
||||||
uv_async_init(uv_default_loop(), &async_baton->async, HandleReaderStatusChange);
|
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
||||||
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
||||||
pthread_detach(obj->m_status_thread);
|
pthread_detach(obj->m_status_thread);
|
||||||
|
|
||||||
return scope.Close(Undefined());
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value> PCSCLite::Close(const Arguments& args) {
|
NAN_METHOD(PCSCLite::Close) {
|
||||||
|
|
||||||
HandleScope scope;
|
NanScope();
|
||||||
|
|
||||||
PCSCLite* obj = ObjectWrap::Unwrap<PCSCLite>(args.This());
|
PCSCLite* obj = ObjectWrap::Unwrap<PCSCLite>(args.This());
|
||||||
|
|
||||||
LONG result = SCardCancel(obj->m_card_context);
|
LONG result = SCardCancel(obj->m_card_context);
|
||||||
|
|
||||||
return scope.Close(Integer::New(result));
|
NanReturnValue(NanNew<Integer>(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCSCLite::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
void PCSCLite::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
||||||
|
|
||||||
|
NanScope();
|
||||||
|
|
||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
||||||
PCSCLite* pcsclite = async_baton->pcsclite;
|
PCSCLite* pcsclite = async_baton->pcsclite;
|
||||||
AsyncResult* ar = async_baton->async_result;
|
AsyncResult* ar = async_baton->async_result;
|
||||||
@@ -91,17 +85,17 @@ void PCSCLite::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
if ((ar->result == SCARD_S_SUCCESS) || (ar->result == (LONG)SCARD_E_NO_READERS_AVAILABLE)) {
|
if ((ar->result == SCARD_S_SUCCESS) || (ar->result == (LONG)SCARD_E_NO_READERS_AVAILABLE)) {
|
||||||
const unsigned argc = 2;
|
const unsigned argc = 2;
|
||||||
Handle<Value> argv[argc] = {
|
Handle<Value> argv[argc] = {
|
||||||
Undefined(), // argument
|
NanUndefined(), // argument
|
||||||
Buffer::New(ar->readers_name, ar->readers_name_length)->handle_
|
NanNewBufferHandle(ar->readers_name, ar->readers_name_length)
|
||||||
};
|
};
|
||||||
|
|
||||||
PerformCallback(async_baton->pcsclite->handle_, async_baton->callback, argc, argv);
|
NanCallback(NanNew(async_baton->callback)).Call(argc, argv);
|
||||||
} else {
|
} else {
|
||||||
Local<Value> err = Exception::Error(String::New(pcsc_stringify_error(ar->result)));
|
Local<Value> err = NanError(pcsc_stringify_error(ar->result));
|
||||||
// Prepare the parameters for the callback function.
|
// Prepare the parameters for the callback function.
|
||||||
const unsigned argc = 1;
|
const unsigned argc = 1;
|
||||||
Handle<Value> argv[argc] = { err };
|
Handle<Value> argv[argc] = { err };
|
||||||
PerformCallback(async_baton->pcsclite->handle_, async_baton->callback, argc, argv);
|
NanCallback(NanNew(async_baton->callback)).Call(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset AsyncResult */
|
/* reset AsyncResult */
|
||||||
@@ -150,7 +144,7 @@ void PCSCLite::CloseCallback(uv_handle_t *handle) {
|
|||||||
AsyncResult* ar = async_baton->async_result;
|
AsyncResult* ar = async_baton->async_result;
|
||||||
delete [] ar->readers_name;
|
delete [] ar->readers_name;
|
||||||
delete ar;
|
delete ar;
|
||||||
async_baton->callback.Dispose();
|
NanDisposePersistent(async_baton->callback);
|
||||||
delete async_baton;
|
delete async_baton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#ifndef PCSCLITE_H
|
#ifndef PCSCLITE_H
|
||||||
#define PCSCLITE_H
|
#define PCSCLITE_H
|
||||||
|
|
||||||
#include <node.h>
|
#include <nan.h>
|
||||||
|
|
||||||
#include <winscard.h>
|
#include <winscard.h>
|
||||||
|
|
||||||
class PCSCLite: public node::ObjectWrap {
|
class PCSCLite: public node::ObjectWrap {
|
||||||
@@ -31,9 +32,9 @@ class PCSCLite: public node::ObjectWrap {
|
|||||||
~PCSCLite();
|
~PCSCLite();
|
||||||
|
|
||||||
static v8::Persistent<v8::Function> constructor;
|
static v8::Persistent<v8::Function> constructor;
|
||||||
static v8::Handle<v8::Value> New(const v8::Arguments& args);
|
static NAN_METHOD(New);
|
||||||
static v8::Handle<v8::Value> Start(const v8::Arguments& args);
|
static NAN_METHOD(Start);
|
||||||
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
|
static NAN_METHOD(Close);
|
||||||
|
|
||||||
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
||||||
static void* HandlerFunction(void* arg);
|
static void* HandlerFunction(void* arg);
|
||||||
|
|||||||
Reference in New Issue
Block a user