22
22
#include " node_buffer.h"
23
23
#include " node_internals.h"
24
24
#include " node_stat_watcher.h"
25
+ #include " node_file.h"
25
26
26
27
#include " req_wrap-inl.h"
27
28
#include " string_bytes.h"
41
42
#include < vector>
42
43
43
44
namespace node {
44
- namespace {
45
+
46
+ void FillStatsArray (double * fields, const uv_stat_t * s) {
47
+ fields[0 ] = s->st_dev ;
48
+ fields[1 ] = s->st_mode ;
49
+ fields[2 ] = s->st_nlink ;
50
+ fields[3 ] = s->st_uid ;
51
+ fields[4 ] = s->st_gid ;
52
+ fields[5 ] = s->st_rdev ;
53
+ #if defined(__POSIX__)
54
+ fields[6 ] = s->st_blksize ;
55
+ #else
56
+ fields[6 ] = -1 ;
57
+ #endif
58
+ fields[7 ] = s->st_ino ;
59
+ fields[8 ] = s->st_size ;
60
+ #if defined(__POSIX__)
61
+ fields[9 ] = s->st_blocks ;
62
+ #else
63
+ fields[9 ] = -1 ;
64
+ #endif
65
+ // Dates.
66
+ // NO-LINT because the fields are 'long' and we just want to cast to `unsigned`
67
+ #define X (idx, name ) \
68
+ /* NOLINTNEXTLINE(runtime/int) */ \
69
+ fields[idx] = ((unsigned long )(s->st_ ##name.tv_sec ) * 1e3 ) + \
70
+ /* NOLINTNEXTLINE(runtime/int) */ \
71
+ ((unsigned long )(s->st_ ##name.tv_nsec ) / 1e6 ); \
72
+
73
+ X (10 , atim)
74
+ X (11 , mtim)
75
+ X (12 , ctim)
76
+ X (13 , birthtim)
77
+ #undef X
78
+ }
79
+
80
+ namespace fs {
45
81
46
82
using v8::Array;
47
83
using v8::ArrayBuffer;
@@ -67,60 +103,6 @@ using v8::Value;
67
103
68
104
#define GET_OFFSET (a ) ((a)->IsNumber () ? (a)->IntegerValue() : -1)
69
105
70
- class FSReqWrap: public ReqWrap<uv_fs_t> {
71
- public:
72
- enum Ownership { COPY, MOVE };
73
-
74
- inline static FSReqWrap* New (Environment* env,
75
- Local<Object> req,
76
- const char * syscall,
77
- const char * data = nullptr ,
78
- enum encoding encoding = UTF8,
79
- Ownership ownership = COPY);
80
-
81
- inline void Dispose ();
82
-
83
- void ReleaseEarly () {
84
- if (data_ != inline_data ()) {
85
- delete[] data_;
86
- data_ = nullptr ;
87
- }
88
- }
89
-
90
- const char * syscall () const { return syscall_; }
91
- const char * data () const { return data_; }
92
- const enum encoding encoding_;
93
-
94
- size_t self_size () const override { return sizeof (*this ); }
95
-
96
- private:
97
- FSReqWrap (Environment* env,
98
- Local<Object> req,
99
- const char * syscall,
100
- const char * data,
101
- enum encoding encoding)
102
- : ReqWrap (env, req, AsyncWrap::PROVIDER_FSREQWRAP),
103
- encoding_ (encoding),
104
- syscall_ (syscall),
105
- data_ (data) {
106
- Wrap (object (), this );
107
- }
108
-
109
- ~FSReqWrap () {
110
- ReleaseEarly ();
111
- ClearWrap (object ());
112
- }
113
-
114
- void * operator new (size_t size) = delete ;
115
- void * operator new (size_t size, char * storage) { return storage; }
116
- char * inline_data () { return reinterpret_cast <char *>(this + 1 ); }
117
-
118
- const char * syscall_;
119
- const char * data_;
120
-
121
- DISALLOW_COPY_AND_ASSIGN (FSReqWrap);
122
- };
123
-
124
106
#define ASSERT_PATH (path ) \
125
107
if (*path == nullptr ) \
126
108
return TYPE_ERROR( #path " must be a string or Buffer" );
@@ -148,6 +130,19 @@ void FSReqWrap::Dispose() {
148
130
}
149
131
150
132
133
+ void FSReqWrap::Reject (Local<Value> reject) {
134
+ Local<Value> argv[1 ] { reject };
135
+ MakeCallback (env ()->oncomplete_string (), arraysize (argv), argv);
136
+ }
137
+
138
+ void FSReqWrap::Resolve (Local<Value> value) {
139
+ Local<Value> argv[2 ] {
140
+ Null (env ()->isolate ()),
141
+ value
142
+ };
143
+ MakeCallback (env ()->oncomplete_string (), arraysize (argv), argv);
144
+ }
145
+
151
146
void NewFSReqWrap (const FunctionCallbackInfo<Value>& args) {
152
147
CHECK (args.IsConstructCall ());
153
148
ClearWrap (args.This ());
@@ -163,29 +158,23 @@ void After(uv_fs_t *req) {
163
158
HandleScope handle_scope (env->isolate ());
164
159
Context::Scope context_scope (env->context ());
165
160
166
- // there is always at least one argument. "error"
167
- int argc = 1 ;
168
-
169
161
// Allocate space for two args. We may only use one depending on the case.
170
162
// (Feel free to increase this if you need more)
171
- Local<Value> argv[2 ];
172
163
MaybeLocal<Value> link;
173
164
Local<Value> error;
174
165
175
166
if (req->result < 0 ) {
176
167
// An error happened.
177
- argv[ 0 ] = UVException (env->isolate (),
178
- req->result ,
179
- req_wrap->syscall (),
180
- nullptr ,
181
- req->path ,
182
- req_wrap->data ());
168
+ req_wrap-> Reject ( UVException (env->isolate (),
169
+ req->result ,
170
+ req_wrap->syscall (),
171
+ nullptr ,
172
+ req->path ,
173
+ req_wrap->data () ));
183
174
} else {
184
175
// error value is empty or null for non-error.
185
- argv[0 ] = Null (env->isolate ());
186
-
187
- // All have at least two args now.
188
- argc = 2 ;
176
+ Local<Value> ret = Undefined (env->isolate ());
177
+ bool reject = false ;
189
178
190
179
switch (req->fs_type ) {
191
180
// These all have no data to pass.
@@ -205,74 +194,54 @@ void After(uv_fs_t *req) {
205
194
case UV_FS_CHOWN:
206
195
case UV_FS_FCHOWN:
207
196
case UV_FS_COPYFILE:
197
+ case UV_FS_UTIME:
198
+ case UV_FS_FUTIME:
208
199
// These, however, don't.
209
- argc = 1 ;
210
200
break ;
211
201
212
202
case UV_FS_STAT:
213
203
case UV_FS_LSTAT:
214
204
case UV_FS_FSTAT:
215
- argc = 1 ;
216
205
FillStatsArray (env->fs_stats_field_array (),
217
206
static_cast <const uv_stat_t *>(req->ptr ));
218
207
break ;
219
208
220
- case UV_FS_UTIME:
221
- case UV_FS_FUTIME:
222
- argc = 0 ;
223
- break ;
224
-
225
209
case UV_FS_OPEN:
226
- argv[1 ] = Integer::New (env->isolate (), req->result );
227
- break ;
228
-
229
210
case UV_FS_WRITE:
230
- argv[1 ] = Integer::New (env->isolate (), req->result );
211
+ case UV_FS_READ:
212
+ ret = Integer::New (env->isolate (), req->result );
231
213
break ;
232
214
215
+
233
216
case UV_FS_MKDTEMP:
234
217
{
235
218
link = StringBytes::Encode (env->isolate (),
236
219
static_cast <const char *>(req->path ),
237
220
req_wrap->encoding_ ,
238
221
&error);
239
222
if (link.IsEmpty ()) {
240
- argv[0 ] = error;
223
+ reject = true ;
224
+ ret = error;
241
225
} else {
242
- argv[ 1 ] = link.ToLocalChecked ();
226
+ ret = link.ToLocalChecked ();
243
227
}
244
228
break ;
245
229
}
246
230
247
231
case UV_FS_READLINK:
248
- link = StringBytes::Encode (env->isolate (),
249
- static_cast <const char *>(req->ptr ),
250
- req_wrap->encoding_ ,
251
- &error);
252
- if (link.IsEmpty ()) {
253
- argv[0 ] = error;
254
- } else {
255
- argv[1 ] = link.ToLocalChecked ();
256
- }
257
- break ;
258
-
259
232
case UV_FS_REALPATH:
260
233
link = StringBytes::Encode (env->isolate (),
261
234
static_cast <const char *>(req->ptr ),
262
235
req_wrap->encoding_ ,
263
236
&error);
264
237
if (link.IsEmpty ()) {
265
- argv[0 ] = error;
238
+ reject = true ;
239
+ ret = error;
266
240
} else {
267
- argv[ 1 ] = link.ToLocalChecked ();
241
+ ret = link.ToLocalChecked ();
268
242
}
269
243
break ;
270
244
271
- case UV_FS_READ:
272
- // Buffer interface
273
- argv[1 ] = Integer::New (env->isolate (), req->result );
274
- break ;
275
-
276
245
case UV_FS_SCANDIR:
277
246
{
278
247
int r;
@@ -288,10 +257,9 @@ void After(uv_fs_t *req) {
288
257
if (r == UV_EOF)
289
258
break ;
290
259
if (r != 0 ) {
291
- argv[0 ] = UVException (r,
292
- nullptr ,
293
- req_wrap->syscall (),
294
- static_cast <const char *>(req->path ));
260
+ reject = true ;
261
+ ret = UVException (r, nullptr , req_wrap->syscall (),
262
+ static_cast <const char *>(req->path ));
295
263
break ;
296
264
}
297
265
@@ -301,7 +269,8 @@ void After(uv_fs_t *req) {
301
269
req_wrap->encoding_ ,
302
270
&error);
303
271
if (filename.IsEmpty ()) {
304
- argv[0 ] = error;
272
+ reject = true ;
273
+ ret = error;
305
274
break ;
306
275
}
307
276
name_argv[name_idx++] = filename.ToLocalChecked ();
@@ -318,17 +287,19 @@ void After(uv_fs_t *req) {
318
287
.ToLocalChecked ();
319
288
}
320
289
321
- argv[ 1 ] = names;
290
+ ret = names;
322
291
}
323
292
break ;
324
293
325
294
default :
326
295
CHECK (0 && " Unhandled eio response" );
327
296
}
297
+ if (!reject)
298
+ req_wrap->Resolve (ret);
299
+ else
300
+ req_wrap->Reject (ret);
328
301
}
329
302
330
- req_wrap->MakeCallback (env->oncomplete_string (), argc, argv);
331
-
332
303
uv_fs_req_cleanup (req_wrap->req ());
333
304
req_wrap->Dispose ();
334
305
}
@@ -471,41 +442,6 @@ void Close(const FunctionCallbackInfo<Value>& args) {
471
442
}
472
443
}
473
444
474
- } // anonymous namespace
475
-
476
- void FillStatsArray (double * fields, const uv_stat_t * s) {
477
- fields[0 ] = s->st_dev ;
478
- fields[1 ] = s->st_mode ;
479
- fields[2 ] = s->st_nlink ;
480
- fields[3 ] = s->st_uid ;
481
- fields[4 ] = s->st_gid ;
482
- fields[5 ] = s->st_rdev ;
483
- #if defined(__POSIX__)
484
- fields[6 ] = s->st_blksize ;
485
- #else
486
- fields[6 ] = -1 ;
487
- #endif
488
- fields[7 ] = s->st_ino ;
489
- fields[8 ] = s->st_size ;
490
- #if defined(__POSIX__)
491
- fields[9 ] = s->st_blocks ;
492
- #else
493
- fields[9 ] = -1 ;
494
- #endif
495
- // Dates.
496
- // NO-LINT because the fields are 'long' and we just want to cast to `unsigned`
497
- #define X (idx, name ) \
498
- /* NOLINTNEXTLINE(runtime/int) */ \
499
- fields[idx] = ((unsigned long )(s->st_ ##name.tv_sec ) * 1e3 ) + \
500
- /* NOLINTNEXTLINE(runtime/int) */ \
501
- ((unsigned long )(s->st_ ##name.tv_nsec ) / 1e6 ); \
502
-
503
- X (10 , atim)
504
- X (11 , mtim)
505
- X (12 , ctim)
506
- X (13 , birthtim)
507
- #undef X
508
- }
509
445
510
446
// Used to speed up module loading. Returns the contents of the file as
511
447
// a string or undefined when the file cannot be opened. Returns an empty
@@ -1460,6 +1396,8 @@ void InitFs(Local<Object> target,
1460
1396
target->Set (wrapString, fst->GetFunction ());
1461
1397
}
1462
1398
1399
+ } // namespace fs
1400
+
1463
1401
} // end namespace node
1464
1402
1465
- NODE_BUILTIN_MODULE_CONTEXT_AWARE (fs, node::InitFs)
1403
+ NODE_BUILTIN_MODULE_CONTEXT_AWARE (fs, node::fs:: InitFs)
0 commit comments