Improved add-on, now links to libzet.so and can open the specified index file
[node_zettair.git] / zetjs.cpp
1 #include <node.h>
2 #include <node_object_wrap.h>
3
4 #include "def.h"
5 #include "fdset.h"
6 #include "vec.h"
7 #include "index.h"
8 #include "_index.h"
9 #include "iobtree.h"
10 #include "vocab.h"
11 #include "mlparse.h"
12 #include "str.h"
13 #include "docmap.h"
14
15 namespace zetjs {
16
17 class IndexObject : public node::ObjectWrap {
18 public:
19   static void Init(v8::Local<v8::Object> exports);
20
21 private:
22   struct index* idx;
23   double value_;
24
25   explicit IndexObject(struct index* idx);
26   ~IndexObject();
27
28   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
29   static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
30   static v8::Persistent<v8::Function> constructor;
31 };
32
33 v8::Persistent<v8::Function> IndexObject::constructor;
34
35 IndexObject::IndexObject(struct index* idx0) : idx(idx0), value_(0.) {
36 }
37
38 IndexObject::~IndexObject() {
39 }
40
41 void IndexObject::Init(v8::Local<v8::Object> exports) {
42   v8::Isolate* isolate = exports->GetIsolate();
43
44   // Prepare constructor template
45   v8::Local<v8::FunctionTemplate> tpl =
46     v8::FunctionTemplate::New(isolate, New);
47   tpl->SetClassName(v8::String::NewFromUtf8(isolate, "Index"));
48   tpl->InstanceTemplate()->SetInternalFieldCount(1);
49
50   // Prototype
51   NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
52
53   constructor.Reset(isolate, tpl->GetFunction());
54   exports->Set(
55     v8::String::NewFromUtf8(isolate, "Index"),
56     tpl->GetFunction()
57   );
58 }
59
60 void IndexObject::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
61   v8::Isolate* isolate = args.GetIsolate();
62
63   if (args.IsConstructCall()) {
64     // Invoked as constructor: `new Index(...)`
65     v8::String::Utf8Value* prefix =
66       args[0]->IsUndefined() ? NULL : new v8::String::Utf8Value(args[0]);
67     struct index* idx = NULL;;
68     int lopts = INDEX_LOAD_NOOPT;
69     struct index_load_opt lopt;
70
71     lopts |= INDEX_LOAD_IGNORE_VERSION;  /* quick hack */
72     if (
73       (
74         idx = index_load(
75           prefix ? **prefix : "index",
76           MEMORY_DEFAULT,
77           lopts,
78           &lopt
79         )
80       ) == NULL
81     ) {
82       isolate->ThrowException(
83         v8::String::NewFromUtf8(isolate, "Unable to load index")
84       );
85       delete prefix;
86       return;
87     }
88     IndexObject* obj = new IndexObject(idx);
89     obj->Wrap(args.This());
90     args.GetReturnValue().Set(args.This());
91     delete prefix;
92   } else {
93     // Invoked as plain function `Index(...)`, turn into construct call.
94     const int argc = 1;
95     v8::Local<v8::Value> argv[argc] = { args[0] };
96     v8::Local<v8::Context> context = isolate->GetCurrentContext();
97     v8::Local<v8::Function> cons =
98       v8::Local<v8::Function>::New(isolate, constructor);
99     v8::Local<v8::Object> result =
100       cons->NewInstance(context, argc, argv).ToLocalChecked();
101     args.GetReturnValue().Set(result);
102   }
103 }
104
105 void IndexObject::PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args) {
106   v8::Isolate* isolate = args.GetIsolate();
107
108   IndexObject* obj = node::ObjectWrap::Unwrap<IndexObject>(args.Holder());
109   obj->value_ += 1;
110
111   args.GetReturnValue().Set(v8::Number::New(isolate, obj->value_));
112 }
113
114 void InitAll(v8::Local<v8::Object> exports) {
115   IndexObject::Init(exports);
116 }
117
118 NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
119
120 }