This repository has been archived by the owner on Dec 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathonig-scanner.cc
119 lines (96 loc) · 4.57 KB
/
onig-scanner.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "onig-scanner.h"
#include "onig-scanner-worker.h"
using ::v8::FunctionTemplate;
using ::v8::Context;
void OnigScanner::Init(Local<Object> target) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(OnigScanner::New);
tpl->SetClassName(Nan::New<String>("OnigScanner").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Context> context = Nan::GetCurrentContext();
v8::Isolate* isolate = context->GetIsolate();
tpl->PrototypeTemplate()->Set(isolate, "_findNextMatch", Nan::New<FunctionTemplate>(OnigScanner::FindNextMatch));
tpl->PrototypeTemplate()->Set(isolate, "_findNextMatchSync", Nan::New<FunctionTemplate>(OnigScanner::FindNextMatchSync));
Nan::Set(target, Nan::New<String>("OnigScanner").ToLocalChecked(), tpl->GetFunction(context).ToLocalChecked());
}
void InitModule(Local<Object> target) {
OnigScanner::Init(target);
OnigString::Init(target);
}
NODE_MODULE(onig_scanner, InitModule)
NAN_METHOD(OnigScanner::New) {
Nan::HandleScope scope;
OnigScanner* scanner = new OnigScanner(Local<Array>::Cast(info[0]));
scanner->Wrap(info.This());
info.GetReturnValue().SetUndefined();
}
NAN_METHOD(OnigScanner::FindNextMatchSync) {
Nan::HandleScope scope;
OnigScanner* scanner = node::ObjectWrap::Unwrap<OnigScanner>(info.This());
Local<Object> param1 = Local<Object>::Cast(info[0]);
Local<Number> param2 = Local<Number>::Cast(info[1]);
Local<Value> result;
if (param1->IsString()) {
Local<String> v8String = Local<String>::Cast(info[0]);
result = scanner->FindNextMatchSync(v8String, param2);
} else {
OnigString* onigString = node::ObjectWrap::Unwrap<OnigString>(info[0].As<Object>());
result = scanner->FindNextMatchSync(onigString, param2);
}
info.GetReturnValue().Set(result);
}
NAN_METHOD(OnigScanner::FindNextMatch) {
Nan::HandleScope scope;
OnigScanner* scanner = node::ObjectWrap::Unwrap<OnigScanner>(info.This());
scanner->FindNextMatch(Local<String>::Cast(info[0]), Local<Number>::Cast(info[1]), Local<Function>::Cast(info[2]));
info.GetReturnValue().SetUndefined();
}
OnigScanner::OnigScanner(Local<Array> sources) {
int length = sources->Length();
regExps.resize(length);
Local<Context> context = Nan::GetCurrentContext();
for (int i = 0; i < length; i++) {
Nan::Utf8String utf8Value(sources->Get(context, i).ToLocalChecked());
regExps[i] = shared_ptr<OnigRegExp>(new OnigRegExp(string(*utf8Value)));
}
searcher = shared_ptr<OnigSearcher>(new OnigSearcher(regExps));
}
OnigScanner::~OnigScanner() {}
void OnigScanner::FindNextMatch(Local<String> v8String, Local<Number> v8StartLocation, Local<Function> v8Callback) {
int charOffset = v8StartLocation->Value();
Nan::Callback *callback = new Nan::Callback(v8Callback);
OnigScannerWorker *worker = new OnigScannerWorker(callback, regExps, v8String, charOffset);
Nan::AsyncQueueWorker(worker);
}
Local<Value> OnigScanner::FindNextMatchSync(Local<String> v8String, Local<Number> v8StartLocation) {
OnigString* source = new OnigString(v8String);
Local<Value> r = FindNextMatchSync(source, v8StartLocation);
delete source;
return r;
}
Local<Value> OnigScanner::FindNextMatchSync(OnigString* source, Local<Number> v8StartLocation) {
int charOffset = v8StartLocation->Value();
shared_ptr<OnigResult> bestResult = searcher->Search(source, charOffset);
if (bestResult != NULL) {
Local<Object> result = Nan::New<Object>();
Nan::Set(result, Nan::New<String>("index").ToLocalChecked(), Nan::New<Number>(bestResult->Index()));
Nan::Set(result, Nan::New<String>("captureIndices").ToLocalChecked(), CaptureIndicesForMatch(bestResult.get(), source));
return result;
} else {
return Nan::Null();
}
}
Local<Value> OnigScanner::CaptureIndicesForMatch(OnigResult* result, OnigString* source) {
int resultCount = result->Count();
Local<Array> captures = Nan::New<Array>(resultCount);
for (int index = 0; index < resultCount; index++) {
int captureStart = source->ConvertUtf8OffsetToUtf16(result->LocationAt(index));
int captureEnd = source->ConvertUtf8OffsetToUtf16(result->LocationAt(index) + result->LengthAt(index));
Local<Object> capture = Nan::New<Object>();
Nan::Set(capture, Nan::New<String>("index").ToLocalChecked(), Nan::New<Number>(index));
Nan::Set(capture, Nan::New<String>("start").ToLocalChecked(), Nan::New<Number>(captureStart));
Nan::Set(capture, Nan::New<String>("end").ToLocalChecked(), Nan::New<Number>(captureEnd));
Nan::Set(capture, Nan::New<String>("length").ToLocalChecked(), Nan::New<Number>(captureEnd - captureStart));
Nan::Set(captures, index, capture);
}
return captures;
}