Skip to content

Commit a24d8ee

Browse files
authored
Merge pull request #60 from Axosoft/upgrade-to-n-api
Upgrade project to N-API for better ABI stability in Node
2 parents 32c2758 + 319c7df commit a24d8ee

File tree

7 files changed

+137
-122
lines changed

7 files changed

+137
-122
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ env:
44
- CXX=g++-4.8
55

66
node_js:
7+
- 8
8+
- 10
79
- 12
810

911
addons:

appveyor.yml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
1-
os: Visual Studio 2014 CTP4
1+
os: Visual Studio 2015
22
version: "{build}"
33
build: off
44
platform: x64
55
environment:
66
matrix:
7-
- nodejs_version: "0.10"
8-
nodejs_arch: "x86"
9-
- nodejs_version: "0.10"
10-
nodejs_arch: "x64"
11-
- nodejs_version: "0.12"
12-
nodejs_arch: "x86"
13-
- nodejs_version: "0.12"
14-
nodejs_arch: "x64"
15-
- nodejs_version: "2"
16-
nodejs_arch: "x86"
17-
- nodejs_version: "2"
18-
nodejs_arch: "x64"
19-
- nodejs_version: "4"
20-
nodejs_arch: "x64"
21-
- nodejs_version: "6"
22-
nodejs_arch: "x64"
237
- nodejs_version: "8"
248
nodejs_arch: "x64"
259
- nodejs_version: "10"
@@ -28,6 +12,6 @@ environment:
2812
nodejs_arch: "x64"
2913
install:
3014
- ps: Install-Product node $env:nodejs_version $env:nodejs_arch
31-
- npm install --msvs_version=2013
15+
- npm install --msvs_version=2015
3216
test_script:
3317
- npm test

binding.gyp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,28 @@
77
],
88
"include_dirs": [
99
"deps/cld/public",
10-
"<!(node -e \"require('nan')\")"
10+
"<!@(node -p \"require('node-addon-api').include\")"
1111
],
1212
"sources": ["src/constants.cc", "src/cld.cc"],
13-
"defines": [],
14-
"cflags_cc": ["-Wall"],
13+
"cflags!": ["-fno-exceptions"],
14+
"cflags_cc!": ["-Wall", "-fno-exceptions"],
1515
"xcode_settings": {
16+
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
17+
"CLANG_CXX_LIBRARY": "libc++",
18+
"MACOSX_DEPLOYMENT_TARGET": "10.7",
1619
"OTHER_CFLAGS": ["-Wall"]
17-
}
20+
},
21+
"msvs_settings": {
22+
"VCCLCompilerTool": { "ExceptionHandling": 1 }
23+
},
24+
"conditions": [
25+
['OS=="mac"', {
26+
"cflags+": ["-fvisibility=hidden"],
27+
"xcode_settings": {
28+
"GCC_SYMBOLS_PRIVATE_EXTERN": "YES"
29+
}
30+
}]
31+
]
1832
}
1933
]
2034
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"main": "./index",
1313
"dependencies": {
1414
"glob": "^5.0.10",
15-
"nan": "^2.9.2",
15+
"node-addon-api": "*",
1616
"rimraf": "^2.4.0",
1717
"underscore": "^1.6.0"
1818
},

src/cld.cc

Lines changed: 84 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,51 @@
55
using std::terminate_handler;
66
using std::unexpected_handler;
77

8-
#include "nan.h"
8+
#define NAPI_VERSION 4
9+
#include <napi.h>
910

1011
namespace NodeCld {
12+
Napi::Object Detect(const Napi::CallbackInfo& info) {
13+
auto env = info.Env();
1114

12-
NAN_METHOD(Detect) {
13-
v8::Local<v8::Object> results = Nan::New<v8::Object>();
14-
v8::String::Utf8Value text(v8::Isolate::GetCurrent(), Nan::To<v8::String>(info[0]).ToLocalChecked());
15-
16-
char *bytes = *text;
17-
int numBytes = text.length();
18-
bool isPlainText = Nan::To<bool>(info[1]).FromJust();
15+
std::string text = info[0].ToString().Utf8Value();
16+
const char *bytes = text.c_str();
17+
int numBytes = text.length();
18+
bool isPlainText = info[1].ToBoolean();
1919

2020
CLD2::CLDHints hints;
2121
hints.tld_hint = 0;
2222
hints.content_language_hint = 0;
2323
hints.language_hint = CLD2::UNKNOWN_LANGUAGE;
2424
hints.encoding_hint = CLD2::UNKNOWN_ENCODING;
2525

26-
v8::String::Utf8Value languageHint(v8::Isolate::GetCurrent(), Nan::To<v8::String>(info[2]).ToLocalChecked());
27-
v8::String::Utf8Value encodingHint(v8::Isolate::GetCurrent(), Nan::To<v8::String>(info[3]).ToLocalChecked());
28-
v8::String::Utf8Value tldHint(v8::Isolate::GetCurrent(), Nan::To<v8::String>(info[4]).ToLocalChecked());
29-
v8::String::Utf8Value httpHint(v8::Isolate::GetCurrent(), Nan::To<v8::String>(info[5]).ToLocalChecked());
3026

31-
if (tldHint.length() > 0) {
32-
hints.tld_hint = *tldHint;
27+
if (info[2].IsString()) {
28+
std::string languageHint = info[2].ToString().Utf8Value();
29+
if (languageHint.length() > 0) {
30+
hints.language_hint = Constants::getInstance().getLanguageFromName(languageHint.c_str());
31+
}
3332
}
34-
if (httpHint.length() > 0) {
35-
hints.content_language_hint = *httpHint;
33+
34+
if (info[3].IsString()) {
35+
std::string encodingHint = info[3].ToString().Utf8Value();
36+
if (encodingHint.length() > 0) {
37+
hints.encoding_hint = Constants::getInstance().getEncodingFromName(encodingHint.c_str());
38+
}
3639
}
37-
if (languageHint.length() > 0) {
38-
hints.language_hint = Constants::getInstance().getLanguageFromName(*languageHint);
40+
41+
if (info[4].IsString()) {
42+
std::string tldHint = info[4].ToString().Utf8Value();
43+
if (tldHint.length() > 0) {
44+
hints.tld_hint = tldHint.c_str();
45+
}
3946
}
40-
if (encodingHint.length() > 0) {
41-
hints.encoding_hint = Constants::getInstance().getEncodingFromName(*encodingHint);
47+
48+
if (info[5].IsString()) {
49+
std::string httpHint = info[5].ToString().Utf8Value();
50+
if (httpHint.length() > 0) {
51+
hints.content_language_hint = httpHint.c_str();
52+
}
4253
}
4354

4455
CLD2::Language language3[3];
@@ -48,7 +59,6 @@ namespace NodeCld {
4859
int textBytesFound;
4960
bool isReliable;
5061

51-
5262
CLD2::ExtDetectLanguageSummary(
5363
bytes, numBytes,
5464
isPlainText,
@@ -62,98 +72,83 @@ namespace NodeCld {
6272
&isReliable
6373
);
6474

65-
unsigned int languageIdx = 0;
66-
v8::Local<v8::Array> languages = v8::Local<v8::Array>(Nan::New<v8::Array>());
67-
for(int resultIdx = 0; resultIdx < 3; resultIdx++) {
75+
size_t languageIdx = 0;
76+
auto languages = Napi::Array::New(env);
77+
for (size_t resultIdx = 0; resultIdx < 3; resultIdx++) {
6878
CLD2::Language lang = language3[resultIdx];
6979

7080
if (lang == CLD2::UNKNOWN_LANGUAGE) {
7181
continue;
7282
}
7383

74-
v8::Local<v8::Object> item = Nan::New<v8::Object>();
75-
Nan::Set(item, Nan::New<v8::String>("name").ToLocalChecked(),
76-
Nan::New<v8::String>(Constants::getInstance().getLanguageName(lang)).ToLocalChecked());
77-
Nan::Set(item, Nan::New<v8::String>("code").ToLocalChecked(),
78-
Nan::New<v8::String>(Constants::getInstance().getLanguageCode(lang)).ToLocalChecked());
79-
Nan::Set(item, Nan::New<v8::String>("percent").ToLocalChecked(),
80-
Nan::New<v8::Number>(percent3[resultIdx]));
81-
Nan::Set(item, Nan::New<v8::String>("score").ToLocalChecked(),
82-
Nan::New<v8::Number>(normalized_score3[resultIdx]));
83-
84-
Nan::Set(languages, Nan::New<v8::Integer>(languageIdx), item);
85-
languageIdx++;
84+
auto item = Napi::Object::New(env);
85+
item["name"] = Napi::String::New(env, Constants::getInstance().getLanguageName(lang));
86+
item["code"] = Napi::String::New(env, Constants::getInstance().getLanguageCode(lang));
87+
item["percent"] = Napi::Number::New(env, percent3[resultIdx]);
88+
item["score"] = Napi::Number::New(env, normalized_score3[resultIdx]);
89+
90+
languages[languageIdx++] = item;
8691
}
8792

88-
unsigned int chunkIdx = 0;
89-
v8::Local<v8::Array> chunks = v8::Local<v8::Array>(Nan::New<v8::Array>());
90-
for(unsigned int resultIdx = 0; resultIdx < resultChunkVector.size(); resultIdx++) {
93+
size_t chunkIdx = 0;
94+
auto chunks = Napi::Array::New(env);
95+
for (size_t resultIdx = 0; resultIdx < resultChunkVector.size(); resultIdx++) {
9196
CLD2::ResultChunk chunk = resultChunkVector.at(resultIdx);
9297
CLD2::Language lang = static_cast<CLD2::Language>(chunk.lang1);
9398

9499
if (lang == CLD2::UNKNOWN_LANGUAGE) {
95100
continue;
96101
}
97102

98-
v8::Local<v8::Object> item = Nan::New<v8::Object>();
99-
Nan::Set(item, Nan::New<v8::String>("name").ToLocalChecked(),
100-
Nan::New<v8::String>(Constants::getInstance().getLanguageName(lang)).ToLocalChecked());
101-
Nan::Set(item, Nan::New<v8::String>("code").ToLocalChecked(),
102-
Nan::New<v8::String>(Constants::getInstance().getLanguageCode(lang)).ToLocalChecked());
103-
Nan::Set(item, Nan::New<v8::String>("offset").ToLocalChecked(),
104-
Nan::New<v8::Number>(chunk.offset));
105-
Nan::Set(item, Nan::New<v8::String>("bytes").ToLocalChecked(),
106-
Nan::New<v8::Number>(chunk.bytes));
107-
108-
Nan::Set(chunks, Nan::New<v8::Integer>(chunkIdx), item);
109-
chunkIdx++;
103+
auto item = Napi::Object::New(env);
104+
item["name"] = Napi::String::New(env, Constants::getInstance().getLanguageName(lang));
105+
item["code"] = Napi::String::New(env, Constants::getInstance().getLanguageCode(lang));
106+
item["offset"] = Napi::Number::New(env, chunk.offset);
107+
item["bytes"] = Napi::Number::New(env, chunk.bytes);
108+
109+
chunks[chunkIdx++] = item;
110110
}
111111

112-
Nan::Set(results, Nan::New<v8::String>("reliable").ToLocalChecked(),
113-
Nan::New<v8::Boolean>(isReliable));
114-
Nan::Set(results, Nan::New<v8::String>("textBytes").ToLocalChecked(),
115-
Nan::New<v8::Number>(textBytesFound));
116-
Nan::Set(results, Nan::New<v8::String>("languages").ToLocalChecked(),
117-
languages);
118-
Nan::Set(results, Nan::New<v8::String>("chunks").ToLocalChecked(),
119-
chunks);
112+
auto results = Napi::Object::New(env);
113+
results["reliable"] = Napi::Boolean::New(env, isReliable);
114+
results["textBytes"] = Napi::Number::New(env, textBytesFound);
115+
results["languages"] = languages;
116+
results["chunks"] = chunks;
120117

121-
info.GetReturnValue().Set(results);
118+
return results;
122119
}
123120

124-
extern "C" void init (v8::Local<v8::Object> target) {
125-
// set detected languages
126-
v8::Local<v8::Array> detected = Nan::New<v8::Array>();
127-
vector<NodeCldDetected>* rawDetected = Constants::getInstance().getDetected();
128-
for(vector<NodeCldDetected>::size_type i = 0; i < rawDetected->size(); i++) {
129-
NodeCldDetected rawLanguage = rawDetected->at(i);
130-
Nan::Set(detected, static_cast<uint32_t>(i),
131-
Nan::New<v8::String>(rawLanguage.name).ToLocalChecked());
121+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
122+
auto rawDetected = Constants::getInstance().getDetected();
123+
auto numDetected = rawDetected->size();
124+
auto detected = Napi::Array::New(env, numDetected);
125+
for (size_t i = 0; i < rawDetected->size(); i++) {
126+
auto rawLanguage = rawDetected->at(i);
127+
detected[i] = Napi::String::New(env, rawLanguage.name);
132128
}
133-
Nan::Set(target, Nan::New<v8::String>("DETECTED_LANGUAGES").ToLocalChecked(), detected);
134-
135-
// set all languages
136-
v8::Local<v8::Object> languages = Nan::New<v8::Object>();
137-
vector<NodeCldLanguage>* rawLanguages = Constants::getInstance().getLanguages();
138-
for(vector<NodeCldLanguage>::size_type i = 0; i < rawLanguages->size(); i++) {
139-
NodeCldLanguage rawLanguage = rawLanguages->at(i);
140-
Nan::Set(languages, Nan::New<v8::String>(rawLanguage.name).ToLocalChecked(),
141-
Nan::New<v8::String>(rawLanguage.code).ToLocalChecked());
129+
exports["DETECTED_LANGUAGES"] = detected;
130+
131+
auto languages = Napi::Object::New(env);
132+
auto rawLanguages = Constants::getInstance().getLanguages();
133+
for (size_t i = 0; i < rawLanguages->size(); i++) {
134+
auto rawLanguage = rawLanguages->at(i);
135+
languages[rawLanguage.name] = Napi::String::New(env, rawLanguage.code);
142136
}
143-
Nan::Set(target, Nan::New<v8::String>("LANGUAGES").ToLocalChecked(), languages);
144-
145-
// set encodings
146-
v8::Local<v8::Array> encodings = Nan::New<v8::Array>();
147-
vector<NodeCldEncoding>* rawEncodings = Constants::getInstance().getEncodings();
148-
for(vector<NodeCldEncoding>::size_type i = 0; i < rawEncodings->size(); i++) {
149-
NodeCldEncoding rawEncoding = rawEncodings->at(i);
150-
Nan::Set(encodings, static_cast<uint32_t>(i),
151-
Nan::New<v8::String>(rawEncoding.name).ToLocalChecked());
137+
exports["LANGUAGES"] = languages;
138+
139+
auto rawEncodings = Constants::getInstance().getEncodings();
140+
auto numEncodings = rawEncodings->size();
141+
auto encodings = Napi::Array::New(env, numEncodings);
142+
for (size_t i = 0; i < numEncodings; i++) {
143+
auto rawEncoding = rawEncodings->at(i);
144+
encodings[i] = Napi::String::New(env, rawEncoding.name);
152145
}
153-
Nan::Set(target, Nan::New<v8::String>("ENCODINGS").ToLocalChecked(), encodings);
146+
exports["ENCODINGS"] = encodings;
147+
148+
exports["detect"] = Napi::Function::New(env, Detect);
154149

155-
Nan::SetMethod(target, "detect", Detect);
150+
return exports;
156151
}
157152

158-
NODE_MODULE(cld, init);
153+
NODE_API_MODULE(cld, Init);
159154
}

test/data.js

Lines changed: 6 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)