data_object_builder.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2017 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. #ifndef GIN_DATA_OBJECT_BUILDER_H_
  5. #define GIN_DATA_OBJECT_BUILDER_H_
  6. #include <utility>
  7. #include "base/check.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/strings/string_piece.h"
  10. #include "gin/converter.h"
  11. #include "gin/gin_export.h"
  12. #include "v8/include/v8-forward.h"
  13. #include "v8/include/v8-object.h"
  14. namespace gin {
  15. // Constructs a JavaScript object with a series of data properties.
  16. // (As with default data properties in JavaScript, these properties are
  17. // configurable, writable and enumerable.)
  18. //
  19. // Values are automatically converted using gin::Converter, though if
  20. // using a type where the conversion may fail, callers must convert ahead of
  21. // time.
  22. //
  23. // This class avoids the pitfall of using v8::Object::Set, which may invoke
  24. // setters on the object prototype.
  25. //
  26. // Expected usage:
  27. // v8::Local<v8::Object> object = gin::DataObjectBuilder(isolate)
  28. // .Set("boolean", true)
  29. // .Set("integer", 42)
  30. // .Build();
  31. //
  32. // Because this builder class contains local handles, callers must ensure it
  33. // does not outlive the scope in which it is created.
  34. class GIN_EXPORT DataObjectBuilder {
  35. public:
  36. explicit DataObjectBuilder(v8::Isolate* isolate);
  37. DataObjectBuilder(const DataObjectBuilder&) = delete;
  38. DataObjectBuilder& operator=(const DataObjectBuilder&) = delete;
  39. ~DataObjectBuilder();
  40. template <typename T>
  41. DataObjectBuilder& Set(base::StringPiece key, T&& value) {
  42. DCHECK(!object_.IsEmpty());
  43. v8::Local<v8::String> v8_key = StringToSymbol(isolate_, key);
  44. v8::Local<v8::Value> v8_value =
  45. ConvertToV8(isolate_, std::forward<T>(value));
  46. CHECK(object_->CreateDataProperty(context_, v8_key, v8_value).ToChecked());
  47. return *this;
  48. }
  49. template <typename T>
  50. DataObjectBuilder& Set(uint32_t index, T&& value) {
  51. DCHECK(!object_.IsEmpty());
  52. v8::Local<v8::Value> v8_value =
  53. ConvertToV8(isolate_, std::forward<T>(value));
  54. CHECK(object_->CreateDataProperty(context_, index, v8_value).ToChecked());
  55. return *this;
  56. }
  57. v8::Local<v8::Object> Build() {
  58. DCHECK(!object_.IsEmpty());
  59. v8::Local<v8::Object> result = object_;
  60. object_.Clear();
  61. return result;
  62. }
  63. private:
  64. raw_ptr<v8::Isolate> isolate_;
  65. v8::Local<v8::Context> context_;
  66. v8::Local<v8::Object> object_;
  67. };
  68. } // namespace gin
  69. #endif // GIN_DATA_OBJECT_BUILDER_H_