@@ -2327,6 +2327,84 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
2327
2327
}
2328
2328
}
2329
2329
2330
+ static void WriteFileUtf8 (const FunctionCallbackInfo<Value>& args) {
2331
+ // Fast C++ path for fs.writeFileSync(path, data) with utf8 encoding
2332
+ // (file, data, options.flag, options.mode)
2333
+
2334
+ Environment* env = Environment::GetCurrent (args);
2335
+ auto isolate = env->isolate ();
2336
+
2337
+ CHECK_EQ (args.Length (), 4 );
2338
+
2339
+ BufferValue value (isolate, args[1 ]);
2340
+ CHECK_NOT_NULL (*value);
2341
+
2342
+ CHECK (args[2 ]->IsInt32 ());
2343
+ const int flags = args[2 ].As <Int32>()->Value ();
2344
+
2345
+ CHECK (args[3 ]->IsInt32 ());
2346
+ const int mode = args[3 ].As <Int32>()->Value ();
2347
+
2348
+ uv_file file;
2349
+
2350
+ bool is_fd = args[0 ]->IsInt32 ();
2351
+
2352
+ // Check for file descriptor
2353
+ if (is_fd) {
2354
+ file = args[0 ].As <Int32>()->Value ();
2355
+ } else {
2356
+ BufferValue path (isolate, args[0 ]);
2357
+ CHECK_NOT_NULL (*path);
2358
+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
2359
+
2360
+ FSReqWrapSync req_open (" open" , *path);
2361
+
2362
+ FS_SYNC_TRACE_BEGIN (open);
2363
+ file =
2364
+ SyncCallAndThrowOnError (env, &req_open, uv_fs_open, *path, flags, mode);
2365
+ FS_SYNC_TRACE_END (open);
2366
+
2367
+ if (is_uv_error (file)) {
2368
+ return ;
2369
+ }
2370
+ }
2371
+
2372
+ int bytesWritten = 0 ;
2373
+ uint32_t offset = 0 ;
2374
+
2375
+ const size_t length = value.length ();
2376
+ uv_buf_t uvbuf = uv_buf_init (value.out (), length);
2377
+
2378
+ FS_SYNC_TRACE_BEGIN (write);
2379
+ while (offset < length) {
2380
+ FSReqWrapSync req_write (" write" );
2381
+ bytesWritten = SyncCallAndThrowOnError (
2382
+ env, &req_write, uv_fs_write, file, &uvbuf, 1 , -1 );
2383
+
2384
+ // Write errored out
2385
+ if (bytesWritten < 0 ) {
2386
+ break ;
2387
+ }
2388
+
2389
+ offset += bytesWritten;
2390
+ DCHECK_LE (offset, length);
2391
+ uvbuf.base += bytesWritten;
2392
+ uvbuf.len -= bytesWritten;
2393
+ }
2394
+ FS_SYNC_TRACE_END (write);
2395
+
2396
+ if (!is_fd) {
2397
+ FSReqWrapSync req_close (" close" );
2398
+
2399
+ FS_SYNC_TRACE_BEGIN (close);
2400
+ int result = SyncCallAndThrowOnError (env, &req_close, uv_fs_close, file);
2401
+ FS_SYNC_TRACE_END (close);
2402
+
2403
+ if (is_uv_error (result)) {
2404
+ return ;
2405
+ }
2406
+ }
2407
+ }
2330
2408
2331
2409
/*
2332
2410
* Wrapper for read(2).
@@ -3169,6 +3247,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
3169
3247
SetMethod (isolate, target, " writeBuffer" , WriteBuffer);
3170
3248
SetMethod (isolate, target, " writeBuffers" , WriteBuffers);
3171
3249
SetMethod (isolate, target, " writeString" , WriteString);
3250
+ SetMethod (isolate, target, " writeFileUtf8" , WriteFileUtf8);
3172
3251
SetMethod (isolate, target, " realpath" , RealPath);
3173
3252
SetMethod (isolate, target, " copyFile" , CopyFile);
3174
3253
@@ -3289,6 +3368,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3289
3368
registry->Register (WriteBuffer);
3290
3369
registry->Register (WriteBuffers);
3291
3370
registry->Register (WriteString);
3371
+ registry->Register (WriteFileUtf8);
3292
3372
registry->Register (RealPath);
3293
3373
registry->Register (CopyFile);
3294
3374
0 commit comments