filesaver
main.cpp
Go to the documentation of this file.
1 //
2 // Created by Pedro Tacla Yamada on 18/05/20.
3 //
4 
5 #include <node.h>
6 #include <node_api.h>
7 #include <node_object_wrap.h>
8 #include <vector>
9 
10 #include <lfilesaver/FileSaver.h>
11 
13 
19 {
20 
22 using v8::Context;
23 using v8::Exception;
24 using v8::Function;
25 using v8::FunctionCallbackInfo;
26 using v8::FunctionTemplate;
27 using v8::Isolate;
28 using v8::Local;
29 using v8::NewStringType;
30 using v8::Object;
31 using v8::ObjectTemplate;
32 using v8::String;
33 using v8::Value;
34 
35 static FileSaver filesaver;
36 
41 class NodeFileSaver : public node::ObjectWrap
42 {
43 public:
44  static void initialize (Local<Object> exports)
45  {
46  auto* isolate = exports->GetIsolate ();
47  auto context = isolate->GetCurrentContext ();
48 
49  auto addonDataTpl = ObjectTemplate::New (isolate);
50  addonDataTpl->SetInternalFieldCount (1);
51 
52  auto addonData = addonDataTpl->NewInstance (context).ToLocalChecked ();
53  auto name = String::NewFromUtf8 (isolate, "FileSaver", NewStringType::kNormal).ToLocalChecked ();
54  auto tpl = FunctionTemplate::New (isolate, New, addonData);
55  tpl->SetClassName (name);
56 
57  std::vector<std::pair<std::string, v8::FunctionCallback>> methods{
58  {"start", Start},
59  {"stop", Stop},
60  {"scan", Scan},
61 
62  {"getCurrentSizeAt", GetCurrentSizeAt},
63  {"getTargets", GetTargets},
64  {"getTotalFiles", GetTotalFiles},
65  {"getTotalKnownFiles", GetTotalKnownFiles},
66  {"getFilesPerSecond", GetFilesPerSecond},
67  {"getNumWorkers", GetNumWorkers},
68  {"getElapsed", GetElapsed},
69 
70  {"isPathFinished", IsPathFinished},
71  {"areAllTargetsFinished", AreAllTargetsFinished},
72 
73  {"setNumWorkers", SetNumWorkers},
74  };
75 
76  tpl->InstanceTemplate ()->SetInternalFieldCount (static_cast<int> (methods.size ()));
77  for (auto& pair : methods)
78  {
79  NODE_SET_PROTOTYPE_METHOD (tpl, pair.first.c_str (), pair.second);
80  }
81 
82  auto constructor = tpl->GetFunction (context).ToLocalChecked ();
83  addonData->SetInternalField (0, constructor);
84  exports->Set (context, name, constructor).FromJust ();
85  }
86 
87 private:
88  NodeFileSaver () = default;
89  ~NodeFileSaver () override = default;
90 
91  static void New (const v8::FunctionCallbackInfo<v8::Value>& args)
92  {
93  Isolate* isolate = args.GetIsolate ();
94  Local<Context> context = isolate->GetCurrentContext ();
95 
96  if (args.IsConstructCall ())
97  {
98  auto* obj = new NodeFileSaver ();
99  obj->Wrap (args.This ());
100  args.GetReturnValue ().Set (args.This ());
101  }
102  else
103  {
104  auto cons = args.Data ().As<Object> ()->GetInternalField (0).As<Function> ();
105  auto result = cons->NewInstance (context, 0, nullptr).ToLocalChecked ();
106  args.GetReturnValue ().Set (result);
107  }
108  }
109 
110  static void Start (const v8::FunctionCallbackInfo<v8::Value>& args)
111  {
112  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
113  nodeFileSaver->fileSaver.start ();
114  }
115 
116  static void Stop (const v8::FunctionCallbackInfo<v8::Value>& args)
117  {
118  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
119  nodeFileSaver->fileSaver.stop ();
120  }
121 
122  static void Scan (const v8::FunctionCallbackInfo<v8::Value>& args)
123  {
124  auto* isolate = args.GetIsolate ();
125  auto context = isolate->GetCurrentContext ();
126  auto target = args[0]->ToString (context);
127  if (target.IsEmpty ())
128  {
129  isolate->ThrowException (Exception::TypeError (
130  String::NewFromUtf8 (isolate, "Missing required target argument", NewStringType::kNormal)
131  .ToLocalChecked ()));
132  return;
133  }
134 
135  std::string output;
136  output.resize (static_cast<unsigned long> (target.ToLocalChecked ()->Length ()));
137  target.ToLocalChecked ()->WriteUtf8 (isolate, output.data ());
138  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
139  nodeFileSaver->fileSaver.scan (output);
140  }
141 
142  static void GetCurrentSizeAt (const v8::FunctionCallbackInfo<v8::Value>& args)
143  {
144  auto* isolate = args.GetIsolate ();
145  auto context = isolate->GetCurrentContext ();
146  auto target = args[0]->ToString (context);
147  if (target.IsEmpty ())
148  {
149  isolate->ThrowException (Exception::TypeError (
150  String::NewFromUtf8 (isolate, "Missing required target argument", NewStringType::kNormal)
151  .ToLocalChecked ()));
152  return;
153  }
154 
155  std::string output;
156  output.resize (static_cast<unsigned long> (target.ToLocalChecked ()->Length ()));
157  target.ToLocalChecked ()->WriteUtf8 (isolate, output.data ());
158  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
159  auto result = nodeFileSaver->fileSaver.getCurrentSizeAt (output);
160 
161  args.GetReturnValue ().Set (static_cast<double> (result));
162  }
163 
164  static void GetTargets (const v8::FunctionCallbackInfo<v8::Value>& args)
165  {
166  auto* isolate = args.GetIsolate ();
167  auto context = isolate->GetCurrentContext ();
168  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
169  auto result = nodeFileSaver->fileSaver.getTargets ();
170 
171  auto resultArray = v8::Array::New (isolate, static_cast<int> (result.size ()));
172  unsigned int i = 0;
173  for (const auto& pth : result)
174  {
175  auto value =
176  String::NewFromUtf8 (isolate, pth.string ().c_str (), NewStringType::kNormal).ToLocalChecked ();
177  auto r = resultArray->Set (context, i, value);
178 
179  if (!r.FromMaybe (false))
180  {
181  isolate->ThrowException (Exception::Error (
182  String::NewFromUtf8 (isolate, "Failed to create result array", NewStringType::kNormal)
183  .ToLocalChecked ()));
184  }
185 
186  i += 1;
187  }
188 
189  args.GetReturnValue ().Set (resultArray);
190  }
191 
192  static void GetTotalFiles (const v8::FunctionCallbackInfo<v8::Value>& args)
193  {
194  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
195  auto result = nodeFileSaver->fileSaver.getTotalFiles ();
196 
197  args.GetReturnValue ().Set (static_cast<double> (result));
198  }
199 
200  static void GetTotalKnownFiles (const v8::FunctionCallbackInfo<v8::Value>& args)
201  {
202  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
203  auto result = nodeFileSaver->fileSaver.getTotalKnownFiles ();
204 
205  args.GetReturnValue ().Set (static_cast<double> (result));
206  }
207 
208  static void GetFilesPerSecond (const v8::FunctionCallbackInfo<v8::Value>& args)
209  {
210  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
211  auto result = nodeFileSaver->fileSaver.getFilesPerSecond ();
212 
213  args.GetReturnValue ().Set (static_cast<double> (result));
214  }
215 
216  static void GetNumWorkers (const v8::FunctionCallbackInfo<v8::Value>& args)
217  {
218  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
219  auto result = nodeFileSaver->fileSaver.getNumWorkers ();
220 
221  args.GetReturnValue ().Set (static_cast<double> (result));
222  }
223 
224  static void GetElapsed (const v8::FunctionCallbackInfo<v8::Value>& args)
225  {
226  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
227  auto result = nodeFileSaver->fileSaver.getElapsed ();
228 
229  args.GetReturnValue ().Set (static_cast<double> (result));
230  }
231 
232  static void IsPathFinished (const v8::FunctionCallbackInfo<v8::Value>& args)
233  {
234  auto* isolate = args.GetIsolate ();
235  auto context = isolate->GetCurrentContext ();
236  auto target = args[0]->ToString (context);
237  if (target.IsEmpty ())
238  {
239  isolate->ThrowException (Exception::TypeError (
240  String::NewFromUtf8 (isolate, "Missing required target argument", NewStringType::kNormal)
241  .ToLocalChecked ()));
242  return;
243  }
244 
245  std::string output;
246  output.resize (static_cast<unsigned long> (target.ToLocalChecked ()->Length ()));
247  target.ToLocalChecked ()->WriteUtf8 (isolate, output.data ());
248  boost::filesystem::path outputPath{output};
249 
250  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
251  auto result = nodeFileSaver->fileSaver.isPathFinished (outputPath);
252 
253  args.GetReturnValue ().Set (static_cast<bool> (result));
254  }
255 
256  static void AreAllTargetsFinished (const v8::FunctionCallbackInfo<v8::Value>& args)
257  {
258  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
259  auto result = nodeFileSaver->fileSaver.areAllTargetsFinished ();
260 
261  args.GetReturnValue ().Set (static_cast<bool> (result));
262  }
263 
264  static void SetNumWorkers (const v8::FunctionCallbackInfo<v8::Value>& args)
265  {
266  auto* isolate = args.GetIsolate ();
267  auto context = isolate->GetCurrentContext ();
268  auto numWorkers = args[0]->ToUint32 (context);
269  if (numWorkers.IsEmpty ())
270  {
271  isolate->ThrowException (Exception::TypeError (
272  String::NewFromUtf8 (isolate, "Missing required numWorkers argument", NewStringType::kNormal)
273  .ToLocalChecked ()));
274  return;
275  }
276 
277  auto* nodeFileSaver = ObjectWrap::Unwrap<NodeFileSaver> (args.Holder ());
278  nodeFileSaver->fileSaver.setNumWorkers (numWorkers.ToLocalChecked ()->Value ());
279  }
280 
281  FileSaver fileSaver;
282 };
283 
284 void initialize (Local<Object> exports)
285 {
286  NodeFileSaver::initialize (exports);
287 }
288 
289 NODE_MODULE (NODE_GYP_MODULE_NAME, initialize)
290 
291 } // namespace filesaver::node_addon
static void initialize(Local< Object > exports)
Definition: main.cpp:44
Defines Node.js bindings to FileSaver.
Definition: main.cpp:19
void initialize(Local< Object > exports)
Definition: main.cpp:284