resource_bundle_source_map.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/renderer/resource_bundle_source_map.h"
  5. #include "base/containers/contains.h"
  6. #include "base/notreached.h"
  7. #include "base/strings/string_piece.h"
  8. #include "extensions/renderer/static_v8_external_one_byte_string_resource.h"
  9. #include "third_party/zlib/google/compression_utils.h"
  10. #include "ui/base/resource/resource_bundle.h"
  11. #include "v8/include/v8-primitive.h"
  12. namespace extensions {
  13. namespace {
  14. v8::Local<v8::String> ConvertString(v8::Isolate* isolate,
  15. const base::StringPiece& string) {
  16. // v8 takes ownership of the StaticV8ExternalOneByteStringResource (see
  17. // v8::String::NewExternalOneByte()).
  18. return v8::String::NewExternalOneByte(
  19. isolate, new StaticV8ExternalOneByteStringResource(string))
  20. .FromMaybe(v8::Local<v8::String>());
  21. }
  22. } // namespace
  23. ResourceBundleSourceMap::ResourceInfo::ResourceInfo() = default;
  24. ResourceBundleSourceMap::ResourceInfo::ResourceInfo(int in_id) : id(in_id) {}
  25. ResourceBundleSourceMap::ResourceInfo::ResourceInfo(ResourceInfo&& other) =
  26. default;
  27. ResourceBundleSourceMap::ResourceInfo::~ResourceInfo() = default;
  28. ResourceBundleSourceMap::ResourceInfo& ResourceBundleSourceMap::ResourceInfo::
  29. operator=(ResourceInfo&& other) = default;
  30. ResourceBundleSourceMap::ResourceBundleSourceMap(
  31. const ui::ResourceBundle* resource_bundle)
  32. : resource_bundle_(resource_bundle) {
  33. }
  34. ResourceBundleSourceMap::~ResourceBundleSourceMap() {
  35. }
  36. void ResourceBundleSourceMap::RegisterSource(const char* const name,
  37. int resource_id) {
  38. resource_map_.emplace(name, resource_id);
  39. }
  40. v8::Local<v8::String> ResourceBundleSourceMap::GetSource(
  41. v8::Isolate* isolate,
  42. const std::string& name) const {
  43. auto resource_iter = resource_map_.find(name);
  44. if (resource_iter == resource_map_.end()) {
  45. NOTREACHED() << "No module is registered with name \"" << name << "\"";
  46. return v8::Local<v8::String>();
  47. }
  48. const ResourceInfo& info = resource_iter->second;
  49. if (info.cached)
  50. return ConvertString(isolate, *info.cached);
  51. base::StringPiece resource = resource_bundle_->GetRawDataResource(info.id);
  52. if (resource.empty()) {
  53. NOTREACHED()
  54. << "Module resource registered as \"" << name << "\" not found";
  55. return v8::Local<v8::String>();
  56. }
  57. bool is_gzipped = resource_bundle_->IsGzipped(info.id);
  58. if (is_gzipped) {
  59. info.cached = std::make_unique<std::string>();
  60. uint32_t size = compression::GetUncompressedSize(resource);
  61. info.cached->resize(size);
  62. base::StringPiece uncompressed(*info.cached);
  63. if (!compression::GzipUncompress(resource, uncompressed)) {
  64. // Let |info.cached| point to an empty string, so that the next time when
  65. // the resource is requested, the method returns an empty string directly,
  66. // instead of trying to uncompress again.
  67. info.cached->clear();
  68. return v8::Local<v8::String>();
  69. }
  70. resource = uncompressed;
  71. }
  72. return ConvertString(isolate, resource);
  73. }
  74. bool ResourceBundleSourceMap::Contains(const std::string& name) const {
  75. return base::Contains(resource_map_, name);
  76. }
  77. } // namespace extensions