@@ -2292,6 +2292,84 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
2292
2292
}
2293
2293
}
2294
2294
2295
+ static void WriteFileUtf8 (const FunctionCallbackInfo<Value>& args) {
2296
+ // Fast C++ path for fs.writeFileSync(path, data) with utf8 encoding
2297
+ // (file, data, options.flag, options.mode)
2298
+
2299
+ Environment* env = Environment::GetCurrent (args);
2300
+ auto isolate = env->isolate ();
2301
+
2302
+ CHECK_EQ (args.Length (), 4 );
2303
+
2304
+ BufferValue value (isolate, args[1 ]);
2305
+ CHECK_NOT_NULL (*value);
2306
+
2307
+ CHECK (args[2 ]->IsInt32 ());
2308
+ const int flags = args[2 ].As <Int32>()->Value ();
2309
+
2310
+ CHECK (args[3 ]->IsInt32 ());
2311
+ const int mode = args[3 ].As <Int32>()->Value ();
2312
+
2313
+ uv_file file;
2314
+
2315
+ bool is_fd = args[0 ]->IsInt32 ();
2316
+
2317
+ // Check for file descriptor
2318
+ if (is_fd) {
2319
+ file = args[0 ].As <Int32>()->Value ();
2320
+ } else {
2321
+ BufferValue path (isolate, args[0 ]);
2322
+ CHECK_NOT_NULL (*path);
2323
+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
2324
+
2325
+ FSReqWrapSync req_open (" open" , *path);
2326
+
2327
+ FS_SYNC_TRACE_BEGIN (open);
2328
+ file =
2329
+ SyncCallAndThrowOnError (env, &req_open, uv_fs_open, *path, flags, mode);
2330
+ FS_SYNC_TRACE_END (open);
2331
+
2332
+ if (is_uv_error (file)) {
2333
+ return ;
2334
+ }
2335
+ }
2336
+
2337
+ int bytesWritten = 0 ;
2338
+ uint32_t offset = 0 ;
2339
+
2340
+ const size_t length = value.length ();
2341
+ uv_buf_t uvbuf = uv_buf_init (value.out (), length);
2342
+
2343
+ FS_SYNC_TRACE_BEGIN (write);
2344
+ while (offset < length) {
2345
+ FSReqWrapSync req_write (" write" );
2346
+ bytesWritten = SyncCallAndThrowOnError (
2347
+ env, &req_write, uv_fs_write, file, &uvbuf, 1 , -1 );
2348
+
2349
+ // Write errored out
2350
+ if (bytesWritten < 0 ) {
2351
+ break ;
2352
+ }
2353
+
2354
+ offset += bytesWritten;
2355
+ DCHECK_LE (offset, length);
2356
+ uvbuf.base += bytesWritten;
2357
+ uvbuf.len -= bytesWritten;
2358
+ }
2359
+ FS_SYNC_TRACE_END (write);
2360
+
2361
+ if (!is_fd) {
2362
+ FSReqWrapSync req_close (" close" );
2363
+
2364
+ FS_SYNC_TRACE_BEGIN (close);
2365
+ int result = SyncCallAndThrowOnError (env, &req_close, uv_fs_close, file);
2366
+ FS_SYNC_TRACE_END (close);
2367
+
2368
+ if (is_uv_error (result)) {
2369
+ return ;
2370
+ }
2371
+ }
2372
+ }
2295
2373
2296
2374
/*
2297
2375
* Wrapper for read(2).
@@ -3134,6 +3212,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
3134
3212
SetMethod (isolate, target, " writeBuffer" , WriteBuffer);
3135
3213
SetMethod (isolate, target, " writeBuffers" , WriteBuffers);
3136
3214
SetMethod (isolate, target, " writeString" , WriteString);
3215
+ SetMethod (isolate, target, " writeFileUtf8" , WriteFileUtf8);
3137
3216
SetMethod (isolate, target, " realpath" , RealPath);
3138
3217
SetMethod (isolate, target, " copyFile" , CopyFile);
3139
3218
@@ -3254,6 +3333,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3254
3333
registry->Register (WriteBuffer);
3255
3334
registry->Register (WriteBuffers);
3256
3335
registry->Register (WriteString);
3336
+ registry->Register (WriteFileUtf8);
3257
3337
registry->Register (RealPath);
3258
3338
registry->Register (CopyFile);
3259
3339
0 commit comments