Skip to content

Commit d024d3e

Browse files
authored
napi: revamp buffer API (#117)
1 parent 802fd26 commit d024d3e

27 files changed

Lines changed: 299 additions & 67 deletions

File tree

src/node_jsrtapi.cc

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ namespace jsrtimpl {
151151
}
152152
}
153153

154+
// node::Buffer::FreeCallback
155+
static void Finalize(char* data, void* callbackState) {
156+
Finalize(callbackState);
157+
}
158+
154159
private:
155160
void* _data;
156161
napi_finalize _cb;
@@ -1291,20 +1296,52 @@ void CALLBACK ExternalArrayBufferFinalizeCallback(void *data)
12911296
static_cast<ArrayBufferFinalizeInfo*>(data)->Free();
12921297
}
12931298

1294-
napi_status napi_buffer_new(napi_env e, char* data, size_t size, napi_value* result) {
1299+
napi_status napi_create_buffer(napi_env e, size_t size, char** data, napi_value* result) {
1300+
CHECK_ARG(result);
1301+
// TODO(tawoll): Replace v8impl with jsrt-based version.
1302+
1303+
v8::MaybeLocal<v8::Object> maybe = node::Buffer::New(v8impl::V8IsolateFromJsEnv(e), size);
1304+
if (maybe.IsEmpty()) {
1305+
return napi_generic_failure;
1306+
}
1307+
1308+
v8::Local<v8::Object> buffer = maybe.ToLocalChecked();
1309+
if (data != nullptr) {
1310+
*data = node::Buffer::Data(buffer);
1311+
}
1312+
1313+
*result = v8impl::JsValueFromV8LocalValue(buffer);
1314+
return napi_ok;
1315+
}
1316+
1317+
napi_status napi_create_external_buffer(napi_env e,
1318+
size_t size,
1319+
char* data,
1320+
napi_finalize finalize_cb,
1321+
napi_value* result) {
12951322
CHECK_ARG(result);
12961323
// TODO(tawoll): Replace v8impl with jsrt-based version.
12971324

1325+
jsrtimpl::ExternalData* externalData = new jsrtimpl::ExternalData(data, finalize_cb);
12981326
v8::MaybeLocal<v8::Object> maybe = node::Buffer::New(
1299-
v8impl::V8IsolateFromJsEnv(e), data, size);
1327+
v8impl::V8IsolateFromJsEnv(e),
1328+
data,
1329+
size,
1330+
jsrtimpl::ExternalData::Finalize,
1331+
externalData);
1332+
13001333
if (maybe.IsEmpty()) {
13011334
return napi_generic_failure;
13021335
}
1336+
13031337
*result = v8impl::JsValueFromV8LocalValue(maybe.ToLocalChecked());
13041338
return napi_ok;
13051339
}
13061340

1307-
napi_status napi_buffer_copy(napi_env e, const char* data, size_t size, napi_value* result) {
1341+
napi_status napi_create_buffer_copy(napi_env e,
1342+
const char* data,
1343+
size_t size,
1344+
napi_value* result) {
13081345
CHECK_ARG(result);
13091346
// TODO(tawoll): Implement node::Buffer in terms of napi to avoid using chakra shim here.
13101347

@@ -1317,7 +1354,7 @@ napi_status napi_buffer_copy(napi_env e, const char* data, size_t size, napi_val
13171354
return napi_ok;
13181355
}
13191356

1320-
napi_status napi_buffer_has_instance(napi_env e, napi_value v, bool* result) {
1357+
napi_status napi_is_buffer(napi_env e, napi_value v, bool* result) {
13211358
CHECK_ARG(result);
13221359
JsValueRef typedArray = reinterpret_cast<JsValueRef>(v);
13231360
JsTypedArrayType arrayType;
@@ -1326,25 +1363,23 @@ napi_status napi_buffer_has_instance(napi_env e, napi_value v, bool* result) {
13261363
return napi_ok;
13271364
}
13281365

1329-
napi_status napi_buffer_data(napi_env e, napi_value v, char** result) {
1330-
CHECK_ARG(result);
1366+
napi_status napi_get_buffer_info(napi_env e, napi_value v, char** data, size_t* length) {
13311367
JsValueRef typedArray = reinterpret_cast<JsValueRef>(v);
13321368
JsValueRef arrayBuffer;
13331369
unsigned int byteOffset;
13341370
ChakraBytePtr buffer;
13351371
unsigned int bufferLength;
13361372
CHECK_JSRT(JsGetTypedArrayInfo(typedArray, nullptr, &arrayBuffer, &byteOffset, nullptr));
13371373
CHECK_JSRT(JsGetArrayBufferStorage(arrayBuffer, &buffer, &bufferLength));
1338-
*result = reinterpret_cast<char*>(buffer + byteOffset);
1339-
return napi_ok;
1340-
}
13411374

1342-
napi_status napi_buffer_length(napi_env e, napi_value v, size_t* result) {
1343-
CHECK_ARG(result);
1344-
JsValueRef typedArray = reinterpret_cast<JsValueRef>(v);
1345-
unsigned int len;
1346-
CHECK_JSRT(JsGetTypedArrayInfo(typedArray, nullptr, nullptr, nullptr, &len));
1347-
*result = static_cast<size_t>(len);
1375+
if (data != nullptr) {
1376+
*data = reinterpret_cast<char*>(buffer + byteOffset);
1377+
}
1378+
1379+
if (length != nullptr) {
1380+
*length = static_cast<size_t>(bufferLength);
1381+
}
1382+
13481383
return napi_ok;
13491384
}
13501385

src/node_jsvmapi.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,21 @@ NODE_EXTERN napi_status napi_is_exception_pending(napi_env e, bool* result);
315315
NODE_EXTERN napi_status napi_get_and_clear_last_exception(napi_env e, napi_value* result);
316316

317317
// Methods to provide node::Buffer functionality with napi types
318-
NODE_EXTERN napi_status napi_buffer_new(napi_env e,
319-
char* data,
320-
size_t size,
321-
napi_value* result);
322-
NODE_EXTERN napi_status napi_buffer_copy(napi_env e,
323-
const char* data,
324-
size_t size,
325-
napi_value* result);
326-
NODE_EXTERN napi_status napi_buffer_has_instance(napi_env e, napi_value v, bool* result);
327-
NODE_EXTERN napi_status napi_buffer_data(napi_env e, napi_value v, char** result);
328-
NODE_EXTERN napi_status napi_buffer_length(napi_env e, napi_value v, size_t* result);
318+
NODE_EXTERN napi_status napi_create_buffer(napi_env e,
319+
size_t size,
320+
char** data,
321+
napi_value* result);
322+
NODE_EXTERN napi_status napi_create_external_buffer(napi_env e,
323+
size_t size,
324+
char* data,
325+
napi_finalize finalize_cb,
326+
napi_value* result);
327+
NODE_EXTERN napi_status napi_create_buffer_copy(napi_env e,
328+
const char* data,
329+
size_t size,
330+
napi_value* result);
331+
NODE_EXTERN napi_status napi_is_buffer(napi_env e, napi_value v, bool* result);
332+
NODE_EXTERN napi_status napi_get_buffer_info(napi_env e, napi_value v, char** data, size_t* length);
329333

330334
// Methods to work with array buffers and typed arrays
331335
NODE_EXTERN napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
assert.equal(addon.hello(), 'world');
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
assert.equal(addon.add(3, 5), 8);

test/addons-abi/3_callbacks/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
addon.RunCallback(function(msg) {
77
assert.equal(msg, 'hello world');

test/addons-abi/4_object_factory/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
var obj1 = addon('hello');
77
var obj2 = addon('world');
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
var fn = addon();
77
assert.equal(fn(), 'hello world'); // 'hello world'

test/addons-abi/6_object_wrap/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
var obj = new addon.MyObject(9);
77
assert.ok(obj instanceof addon.MyObject);

test/addons-abi/7_factory_wrap/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var createObject = require('./build/Release/binding');
4+
var createObject = require(`./build/${common.buildType}/binding`);
55

66
var obj = createObject(10);
77
assert.equal(obj.plusOne(), 11);

test/addons-abi/8_passing_wrapped/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
2-
require('../../common');
2+
var common = require('../../common');
33
var assert = require('assert');
4-
var addon = require('./build/Release/binding');
4+
var addon = require(`./build/${common.buildType}/binding`);
55

66
var obj1 = addon.createObject(10);
77
var obj2 = addon.createObject(20);

0 commit comments

Comments
 (0)