atom_api_asar.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <vector>
  6. #include "atom_natives.h" // NOLINT: This file is generated with coffee2c.
  7. #include "atom/common/asar/archive.h"
  8. #include "atom/common/native_mate_converters/callback.h"
  9. #include "atom/common/native_mate_converters/file_path_converter.h"
  10. #include "atom/common/node_includes.h"
  11. #include "native_mate/arguments.h"
  12. #include "native_mate/dictionary.h"
  13. #include "native_mate/object_template_builder.h"
  14. #include "native_mate/wrappable.h"
  15. namespace {
  16. class Archive : public mate::Wrappable<Archive> {
  17. public:
  18. static v8::Local<v8::Value> Create(v8::Isolate* isolate,
  19. const base::FilePath& path) {
  20. std::unique_ptr<asar::Archive> archive(new asar::Archive(path));
  21. if (!archive->Init())
  22. return v8::False(isolate);
  23. return (new Archive(isolate, std::move(archive)))->GetWrapper();
  24. }
  25. static void BuildPrototype(
  26. v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
  27. prototype->SetClassName(mate::StringToV8(isolate, "Archive"));
  28. mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
  29. .SetProperty("path", &Archive::GetPath)
  30. .SetMethod("getFileInfo", &Archive::GetFileInfo)
  31. .SetMethod("stat", &Archive::Stat)
  32. .SetMethod("readdir", &Archive::Readdir)
  33. .SetMethod("realpath", &Archive::Realpath)
  34. .SetMethod("copyFileOut", &Archive::CopyFileOut)
  35. .SetMethod("getFd", &Archive::GetFD)
  36. .SetMethod("destroy", &Archive::Destroy);
  37. }
  38. protected:
  39. Archive(v8::Isolate* isolate, std::unique_ptr<asar::Archive> archive)
  40. : archive_(std::move(archive)) {
  41. Init(isolate);
  42. }
  43. // Returns the path of the file.
  44. base::FilePath GetPath() {
  45. return archive_->path();
  46. }
  47. // Reads the offset and size of file.
  48. v8::Local<v8::Value> GetFileInfo(v8::Isolate* isolate,
  49. const base::FilePath& path) {
  50. asar::Archive::FileInfo info;
  51. if (!archive_ || !archive_->GetFileInfo(path, &info))
  52. return v8::False(isolate);
  53. mate::Dictionary dict(isolate, v8::Object::New(isolate));
  54. dict.Set("size", info.size);
  55. dict.Set("unpacked", info.unpacked);
  56. dict.Set("offset", info.offset);
  57. return dict.GetHandle();
  58. }
  59. // Returns a fake result of fs.stat(path).
  60. v8::Local<v8::Value> Stat(v8::Isolate* isolate,
  61. const base::FilePath& path) {
  62. asar::Archive::Stats stats;
  63. if (!archive_ || !archive_->Stat(path, &stats))
  64. return v8::False(isolate);
  65. mate::Dictionary dict(isolate, v8::Object::New(isolate));
  66. dict.Set("size", stats.size);
  67. dict.Set("offset", stats.offset);
  68. dict.Set("isFile", stats.is_file);
  69. dict.Set("isDirectory", stats.is_directory);
  70. dict.Set("isLink", stats.is_link);
  71. return dict.GetHandle();
  72. }
  73. // Returns all files under a directory.
  74. v8::Local<v8::Value> Readdir(v8::Isolate* isolate,
  75. const base::FilePath& path) {
  76. std::vector<base::FilePath> files;
  77. if (!archive_ || !archive_->Readdir(path, &files))
  78. return v8::False(isolate);
  79. return mate::ConvertToV8(isolate, files);
  80. }
  81. // Returns the path of file with symbol link resolved.
  82. v8::Local<v8::Value> Realpath(v8::Isolate* isolate,
  83. const base::FilePath& path) {
  84. base::FilePath realpath;
  85. if (!archive_ || !archive_->Realpath(path, &realpath))
  86. return v8::False(isolate);
  87. return mate::ConvertToV8(isolate, realpath);
  88. }
  89. // Copy the file out into a temporary file and returns the new path.
  90. v8::Local<v8::Value> CopyFileOut(v8::Isolate* isolate,
  91. const base::FilePath& path) {
  92. base::FilePath new_path;
  93. if (!archive_ || !archive_->CopyFileOut(path, &new_path))
  94. return v8::False(isolate);
  95. return mate::ConvertToV8(isolate, new_path);
  96. }
  97. // Return the file descriptor.
  98. int GetFD() const {
  99. if (!archive_)
  100. return -1;
  101. return archive_->GetFD();
  102. }
  103. // Free the resources used by archive.
  104. void Destroy() {
  105. archive_.reset();
  106. }
  107. private:
  108. std::unique_ptr<asar::Archive> archive_;
  109. DISALLOW_COPY_AND_ASSIGN(Archive);
  110. };
  111. void InitAsarSupport(v8::Isolate* isolate,
  112. v8::Local<v8::Value> process,
  113. v8::Local<v8::Value> require) {
  114. // Evaluate asar_init.coffee.
  115. const char* asar_init_native = reinterpret_cast<const char*>(
  116. static_cast<const unsigned char*>(node::asar_init_data));
  117. v8::Local<v8::Script> asar_init = v8::Script::Compile(v8::String::NewFromUtf8(
  118. isolate,
  119. asar_init_native,
  120. v8::String::kNormalString,
  121. sizeof(node::asar_init_data) -1));
  122. v8::Local<v8::Value> result = asar_init->Run();
  123. // Initialize asar support.
  124. base::Callback<void(v8::Local<v8::Value>,
  125. v8::Local<v8::Value>,
  126. std::string)> init;
  127. if (mate::ConvertFromV8(isolate, result, &init)) {
  128. const char* asar_native = reinterpret_cast<const char*>(
  129. static_cast<const unsigned char*>(node::asar_data));
  130. init.Run(process,
  131. require,
  132. std::string(asar_native, sizeof(node::asar_data) - 1));
  133. }
  134. }
  135. void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
  136. v8::Local<v8::Context> context, void* priv) {
  137. mate::Dictionary dict(context->GetIsolate(), exports);
  138. dict.SetMethod("createArchive", &Archive::Create);
  139. dict.SetMethod("initAsarSupport", &InitAsarSupport);
  140. }
  141. } // namespace
  142. NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_asar, Initialize)