|
22 | 22 | # include <io.h>
|
23 | 23 | #endif
|
24 | 24 |
|
| 25 | +#include <vector> |
| 26 | + |
25 | 27 | namespace node {
|
26 | 28 |
|
27 | 29 | using v8::Array;
|
@@ -433,6 +435,50 @@ Local<Value> BuildStatsObject(Environment* env, const uv_stat_t* s) {
|
433 | 435 | return handle_scope.Escape(stats);
|
434 | 436 | }
|
435 | 437 |
|
| 438 | +// Used to speed up module loading. Returns the contents of the file as |
| 439 | +// a string or undefined when the file cannot be opened. The speedup |
| 440 | +// comes from not creating Error objects on failure. |
| 441 | +static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) { |
| 442 | + Environment* env = Environment::GetCurrent(args); |
| 443 | + |
| 444 | + CHECK(args[0]->IsString()); |
| 445 | + node::Utf8Value path(env->isolate(), args[0]); |
| 446 | + |
| 447 | + FILE* const stream = fopen(*path, "rb"); |
| 448 | + if (stream == nullptr) { |
| 449 | + return; |
| 450 | + } |
| 451 | + |
| 452 | + std::vector<char> chars; |
| 453 | + while (!ferror(stream)) { |
| 454 | + const size_t kBlockSize = 32 << 10; |
| 455 | + const size_t start = chars.size(); |
| 456 | + chars.resize(start + kBlockSize); |
| 457 | + const size_t numchars = fread(&chars[start], 1, kBlockSize, stream); |
| 458 | + if (numchars < kBlockSize) { |
| 459 | + chars.resize(start + numchars); |
| 460 | + } |
| 461 | + if (numchars == 0) { |
| 462 | + break; |
| 463 | + } |
| 464 | + } |
| 465 | + |
| 466 | + CHECK_EQ(false, ferror(stream)); |
| 467 | + CHECK_EQ(0, fclose(stream)); |
| 468 | + |
| 469 | + size_t start = 0; |
| 470 | + if (chars.size() >= 3 && 0 == memcmp(&chars[0], "\xEF\xBB\xBF", 3)) { |
| 471 | + start = 3; // Skip UTF-8 BOM. |
| 472 | + } |
| 473 | + |
| 474 | + Local<String> chars_string = |
| 475 | + String::NewFromUtf8(env->isolate(), |
| 476 | + &chars[start], |
| 477 | + String::kNormalString, |
| 478 | + chars.size() - start); |
| 479 | + args.GetReturnValue().Set(chars_string); |
| 480 | +} |
| 481 | + |
436 | 482 | // Used to speed up module loading. Returns 0 if the path refers to
|
437 | 483 | // a file, 1 when it's a directory or < 0 on error (usually -ENOENT.)
|
438 | 484 | // The speedup comes from not creating thousands of Stat and Error objects.
|
@@ -1161,6 +1207,7 @@ void InitFs(Handle<Object> target,
|
1161 | 1207 | env->SetMethod(target, "rmdir", RMDir);
|
1162 | 1208 | env->SetMethod(target, "mkdir", MKDir);
|
1163 | 1209 | env->SetMethod(target, "readdir", ReadDir);
|
| 1210 | + env->SetMethod(target, "internalModuleReadFile", InternalModuleReadFile); |
1164 | 1211 | env->SetMethod(target, "internalModuleStat", InternalModuleStat);
|
1165 | 1212 | env->SetMethod(target, "stat", Stat);
|
1166 | 1213 | env->SetMethod(target, "lstat", LStat);
|
|
0 commit comments