@@ -2232,6 +2232,79 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22322232 }
22332233}
22342234
2235+ static void WriteFileUtf8 (const FunctionCallbackInfo<Value>& args) {
2236+ // Fast C++ path for fs.writeFileSync(path, data) with utf8 encoding
2237+ // (file, data, options.flag, options.mode)
2238+
2239+ Environment* env = Environment::GetCurrent (args);
2240+ auto isolate = env->isolate ();
2241+
2242+ CHECK_EQ (args.Length (), 4 );
2243+
2244+ BufferValue value (isolate, args[1 ]);
2245+ CHECK_NOT_NULL (*value);
2246+
2247+ CHECK (args[2 ]->IsInt32 ());
2248+ const int flags = args[2 ].As <Int32>()->Value ();
2249+
2250+ CHECK (args[3 ]->IsInt32 ());
2251+ const int mode = args[3 ].As <Int32>()->Value ();
2252+
2253+ uv_file file;
2254+
2255+ bool is_fd = args[0 ]->IsInt32 ();
2256+
2257+ // Check for file descriptor
2258+ if (is_fd) {
2259+ file = args[0 ].As <Int32>()->Value ();
2260+ } else {
2261+ BufferValue path (isolate, args[0 ]);
2262+ CHECK_NOT_NULL (*path);
2263+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
2264+
2265+ FSReqWrapSync req_open (" open" , *path);
2266+
2267+ FS_SYNC_TRACE_BEGIN (open);
2268+ file =
2269+ SyncCallAndThrowOnError (env, &req_open, uv_fs_open, *path, flags, mode);
2270+ FS_SYNC_TRACE_END (open);
2271+
2272+ if (is_uv_error (file)) {
2273+ return ;
2274+ }
2275+ }
2276+
2277+ int bytesWritten = 0 ;
2278+ uint32_t offset = 0 ;
2279+
2280+ const size_t length = value.length ();
2281+ uv_buf_t uvbuf = uv_buf_init (value.out (), length);
2282+
2283+ FS_SYNC_TRACE_BEGIN (write);
2284+ while (offset < length) {
2285+ FSReqWrapSync req_write (" write" );
2286+ bytesWritten = SyncCallAndThrowOnError (
2287+ env, &req_write, uv_fs_write, file, &uvbuf, 1 , -1 );
2288+
2289+ offset += bytesWritten;
2290+ DCHECK_LE (offset, length);
2291+ uvbuf.base += bytesWritten;
2292+ uvbuf.len -= bytesWritten;
2293+ }
2294+ FS_SYNC_TRACE_END (write);
2295+
2296+ if (!is_fd) {
2297+ FSReqWrapSync req_close (" close" );
2298+
2299+ FS_SYNC_TRACE_BEGIN (close);
2300+ int result = SyncCallAndThrowOnError (env, &req_close, uv_fs_close, file);
2301+ FS_SYNC_TRACE_END (close);
2302+
2303+ if (is_uv_error (result)) {
2304+ return ;
2305+ }
2306+ }
2307+ }
22352308
22362309/*
22372310 * Wrapper for read(2).
@@ -3073,6 +3146,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
30733146 SetMethod (isolate, target, " writeBuffer" , WriteBuffer);
30743147 SetMethod (isolate, target, " writeBuffers" , WriteBuffers);
30753148 SetMethod (isolate, target, " writeString" , WriteString);
3149+ SetMethod (isolate, target, " writeFileUtf8" , WriteFileUtf8);
30763150 SetMethod (isolate, target, " realpath" , RealPath);
30773151 SetMethod (isolate, target, " copyFile" , CopyFile);
30783152
@@ -3192,6 +3266,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
31923266 registry->Register (WriteBuffer);
31933267 registry->Register (WriteBuffers);
31943268 registry->Register (WriteString);
3269+ registry->Register (WriteFileUtf8);
31953270 registry->Register (RealPath);
31963271 registry->Register (CopyFile);
31973272
0 commit comments