diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-10 03:36:04 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-10 03:36:04 +0000 |
commit | 7f14c8de777b78b445cc500b8c17d8125b195056 (patch) | |
tree | 261ec41a3569299fece3b0dd2122472ad6e64981 | |
parent | 2863a6c2c11ffe6ca6ebd07cf412eaf87815a3e9 (diff) | |
download | chromium_src-7f14c8de777b78b445cc500b8c17d8125b195056.zip chromium_src-7f14c8de777b78b445cc500b8c17d8125b195056.tar.gz chromium_src-7f14c8de777b78b445cc500b8c17d8125b195056.tar.bz2 |
Mojo: Simplify object serialization
Eliminate ObjectTraits<T> classes in favor of putting these methods directly on
the generated *_Data classes. ObjectTraits<T> was added to hide these methods
from public classes, but now that *_Data classes are internal, there is no
longer any need for ObjectTraits<T>.
Review URL: https://codereview.chromium.org/131033002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244071 0039d316-1c4b-4281-b951-d872f2087c98
15 files changed, 238 insertions, 336 deletions
diff --git a/mojo/public/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/bindings/generators/cpp_templates/interface_definition.tmpl index 9885a36..713939a 100644 --- a/mojo/public/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/interface_definition.tmpl @@ -23,8 +23,8 @@ void {{proxy_name}}::{{method.name}}({{params_list(method)}}) { {#--- Computes #} {%- for param in method.parameters %} {%- if param.kind|is_object_kind %} - payload_size += mojo::internal::ComputeSizeOf( - mojo::internal::Unwrap({{param.name}})); + if (!{{param.name}}.is_null()) + payload_size += mojo::internal::Unwrap({{param.name}})->ComputeSize(); {%- endif %} {%- endfor %} @@ -36,9 +36,9 @@ void {{proxy_name}}::{{method.name}}({{params_list(method)}}) { {#--- Sets #} {% for param in method.parameters %} {%- if param.kind|is_object_kind %} - params->set_{{param.name}}( - mojo::internal::Clone(mojo::internal::Unwrap({{param.name}}), - builder.buffer())); + if (!{{param.name}}.is_null()) + params->set_{{param.name}}( + mojo::internal::Unwrap({{param.name}})->Clone(builder.buffer())); {%- elif param.kind|is_handle_kind %} params->set_{{param.name}}({{param.name}}.release()); {%- else %} @@ -47,7 +47,7 @@ void {{proxy_name}}::{{method.name}}({{params_list(method)}}) { {%- endfor %} mojo::Message message; - mojo::internal::EncodePointersAndHandles(params, &message.handles); + params->EncodePointersAndHandles(&message.handles); message.data = builder.Finish(); @@ -81,10 +81,10 @@ bool {{class_name}}Stub::Accept(mojo::Message* message) { reinterpret_cast<internal::{{class_name}}_{{method.name}}_Params_Data*>( message->data->payload); - if (!mojo::internal::DecodePointersAndHandles(params, message)) + if (!params->DecodePointersAndHandles(message)) return false; sink_->{{method.name}}({{params(method)}}); - mojo::internal::CloseHandles(params); + params->CloseHandles(); break; } {%- endfor %} diff --git a/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl index 1d6d700..c5a0fb3 100644 --- a/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl @@ -4,6 +4,7 @@ #include "./{{module_name|camel_to_underscores}}.h" +#include "mojo/public/bindings/lib/bindings_serialization.h" #include "mojo/public/bindings/lib/message_builder.h" namespace {{namespace}} { @@ -29,16 +30,16 @@ namespace { } // namespace -{#--- Struct definitions #} -{% for struct in structs %} -{%- include "struct_definition.tmpl" %} -{%- endfor %} - {#--- Struct destructors #} {%- for struct in structs %} {%- include "struct_destructor.tmpl" %} {%- endfor %} +{#--- Struct definitions #} +{% for struct in structs %} +{%- include "struct_definition.tmpl" %} +{%- endfor %} + } // namespace internal {#--- Struct builder definitions #} @@ -51,22 +52,3 @@ namespace { {%- include "interface_definition.tmpl" %} {%- endfor %} } // namespace {{namespace}} - -namespace mojo { -namespace internal { - -{#--- Struct serialization definitions #} -{%- for struct in structs %} -{%- include "struct_serialization_definition.tmpl" %} -{%- endfor %} - -{#--- Interface serialization definitions #} -{%- for interface in interfaces %} -{%- for method in interface.methods %} -{%- set struct = interface|struct_from_method(method) %} -{%- include "params_serialization.tmpl" %} -{%- endfor %} -{%- endfor %} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/generators/cpp_templates/module_internal.h.tmpl b/mojo/public/bindings/generators/cpp_templates/module_internal.h.tmpl index 624d4f5..44f340f 100644 --- a/mojo/public/bindings/generators/cpp_templates/module_internal.h.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/module_internal.h.tmpl @@ -8,7 +8,7 @@ #ifndef {{header_guard}} #define {{header_guard}} -#include "mojo/public/bindings/lib/bindings_serialization.h" +#include "mojo/public/bindings/lib/bindings_internal.h" namespace {{namespace}} { @@ -31,15 +31,4 @@ namespace internal { } // namespace internal } // namespace {{namespace}} -namespace mojo { -namespace internal { - -{#--- Serialization traits #} -{% for struct in structs %} -{% include "struct_serialization_traits.tmpl" %} -{%- endfor %} - -} // namespace internal -} // namespace mojo - #endif // {{header_guard}} diff --git a/mojo/public/bindings/generators/cpp_templates/params_definition.tmpl b/mojo/public/bindings/generators/cpp_templates/params_definition.tmpl index 32d9bab..b21f537 100644 --- a/mojo/public/bindings/generators/cpp_templates/params_definition.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/params_definition.tmpl @@ -15,9 +15,23 @@ class {{class_name}} { {#--- Getters -#} {{ struct_macros.getters(struct) }} - private: - friend class mojo::internal::ObjectTraits<{{class_name}}>; + void CloseHandles() { +{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} + if ({{pf.field.name}}_.ptr) + {{pf.field.name}}_.ptr->CloseHandles(); +{%- endfor %} + } + + void EncodePointersAndHandles(std::vector<mojo::Handle>* handles) { + {{ struct_macros.encodes(struct)|indent(4) }} + } + bool DecodePointersAndHandles(mojo::Message* message) { + {{ struct_macros.decodes(struct)|indent(4) }} + return true; + } + + private: {{class_name}}() { _header_.num_bytes = sizeof(*this); _header_.num_fields = 3; diff --git a/mojo/public/bindings/generators/cpp_templates/params_serialization.tmpl b/mojo/public/bindings/generators/cpp_templates/params_serialization.tmpl deleted file mode 100644 index 955b8e2..0000000 --- a/mojo/public/bindings/generators/cpp_templates/params_serialization.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{%- import "struct_macros.tmpl" as struct_macros %} -{%- set class_name = "%s::internal::%s_Data"|format(namespace, struct.name) %} -{%- set param_name = "params" %} -template <> -class ObjectTraits<{{class_name}}> { - public: - static void CloseHandles({{class_name}}* {{param_name}}) { -{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} - mojo::internal::CloseHandles({{param_name}}->{{pf.field.name}}_.ptr); -{%- endfor %} - } - - static void EncodePointersAndHandles( - {{class_name}}* {{param_name}}, - std::vector<Handle>* handles) { - {{ struct_macros.encodes(struct, param_name)|indent(4) }} - } - - static bool DecodePointersAndHandles( - {{class_name}}* {{param_name}}, - Message* message) { - {{ struct_macros.decodes(struct, param_name)|indent(4) }} - return true; - } -}; diff --git a/mojo/public/bindings/generators/cpp_templates/struct_declaration.tmpl b/mojo/public/bindings/generators/cpp_templates/struct_declaration.tmpl index 480e472..a4bfe21 100644 --- a/mojo/public/bindings/generators/cpp_templates/struct_declaration.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/struct_declaration.tmpl @@ -18,9 +18,13 @@ class {{class_name}} { {#--- Getters -#} {{ struct_macros.getters(struct) }} - private: - friend class mojo::internal::ObjectTraits<{{class_name}}>; + size_t ComputeSize() const; + {{class_name}}* Clone(mojo::Buffer* buf) const; + void CloseHandles(); + void EncodePointersAndHandles(std::vector<mojo::Handle>* handles); + bool DecodePointersAndHandles(mojo::Message* message); + private: {{class_name}}(); ~{{class_name}}(); // NOT IMPLEMENTED diff --git a/mojo/public/bindings/generators/cpp_templates/struct_definition.tmpl b/mojo/public/bindings/generators/cpp_templates/struct_definition.tmpl index bb90897..f23ebe9 100644 --- a/mojo/public/bindings/generators/cpp_templates/struct_definition.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/struct_definition.tmpl @@ -1,3 +1,4 @@ +{%- import "struct_macros.tmpl" as struct_macros %} {%- set class_name = struct.name ~ "_Data" %} // static {{class_name}}* {{class_name}}::New(mojo::Buffer* buf, mojo::Buffer::Destructor dtor) { @@ -8,3 +9,45 @@ _header_.num_bytes = sizeof(*this); _header_.num_fields = {{struct.packed.packed_fields|length}}; } + +size_t {{class_name}}::ComputeSize() const { + size_t result = sizeof(*this); +{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} + if ({{pf.field.name}}_.ptr) + result += {{pf.field.name}}_.ptr->ComputeSize(); +{%- endfor %} + return result; +} + +{{class_name}}* {{class_name}}::Clone(mojo::Buffer* buf) const { + {{class_name}}* clone = New(buf); + memcpy(clone, this, sizeof(*this)); +{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} + if ({{pf.field.name}}_.ptr) + clone->set_{{pf.field.name}}({{pf.field.name}}_.ptr->Clone(buf)); +{%- endfor %} +{%- for pf in struct.packed.packed_fields if pf.field.kind|is_handle_kind %} + mojo::internal::ResetIfNonNull({{pf.field.name}}()); +{%- endfor %} + return clone; +} + +void {{class_name}}::CloseHandles() { +{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} + if ({{pf.field.name}}_.ptr) + {{pf.field.name}}_.ptr->CloseHandles(); +{%- endfor %} +{%- if struct|is_struct_with_handles %} + {{struct.name}}_Data_Destructor(this); +{%- endif %} +} + +void {{class_name}}::EncodePointersAndHandles( + std::vector<mojo::Handle>* handles) { + {{ struct_macros.encodes(struct)|indent(2) }} +} + +bool {{class_name}}::DecodePointersAndHandles(mojo::Message* message) { + {{ struct_macros.decodes(struct)|indent(2) }} + return true; +} diff --git a/mojo/public/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/bindings/generators/cpp_templates/struct_macros.tmpl index 538f7f1..9e7706d 100644 --- a/mojo/public/bindings/generators/cpp_templates/struct_macros.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/struct_macros.tmpl @@ -61,22 +61,22 @@ {%- endif %} {%- endmacro %} -{%- macro encodes(struct, param_name) -%} +{%- macro encodes(struct) -%} {%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind -%} -Encode(&{{param_name}}->{{pf.field.name}}_, handles); +mojo::internal::Encode(&{{pf.field.name}}_, handles); {% endfor %} {%- for pf in struct.packed.packed_fields if pf.field.kind|is_handle_kind -%} -EncodeHandle(&{{param_name}}->{{pf.field.name}}_, handles); +mojo::internal::EncodeHandle(&{{pf.field.name}}_, handles); {% endfor %} {%- endmacro -%} -{%- macro decodes(struct, param_name) -%} +{%- macro decodes(struct) -%} {%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind -%} -if (!Decode(&{{param_name}}->{{pf.field.name}}_, message)) +if (!mojo::internal::Decode(&{{pf.field.name}}_, message)) return false; {% endfor %} {%- for pf in struct.packed.packed_fields if pf.field.kind|is_handle_kind -%} -if (!DecodeHandle(&{{param_name}}->{{pf.field.name}}_, &message->handles)) +if (!mojo::internal::DecodeHandle(&{{pf.field.name}}_, &message->handles)) return false; {% endfor %} {%- endmacro -%} diff --git a/mojo/public/bindings/generators/cpp_templates/struct_serialization_definition.tmpl b/mojo/public/bindings/generators/cpp_templates/struct_serialization_definition.tmpl deleted file mode 100644 index faed8f5..0000000 --- a/mojo/public/bindings/generators/cpp_templates/struct_serialization_definition.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -{%- import "struct_macros.tmpl" as struct_macros %} -{%- set class_name = "%s::internal::%s_Data"|format(namespace, struct.name) -%} -{%- set param_name = struct.name|camel_to_underscores %} - -// static -size_t ObjectTraits<{{class_name}}>::ComputeSizeOf( - const {{class_name}}* {{param_name}}) { - return sizeof(*{{param_name}}) -{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} + - mojo::internal::ComputeSizeOf({{param_name}}->{{pf.field.name}}()) -{%- endfor %}; -} - -// static -{{class_name}}* ObjectTraits<{{class_name}}>::Clone( - const {{class_name}}* {{param_name}}, Buffer* buf) { - {{class_name}}* clone = {{class_name}}::New(buf); - memcpy(clone, {{param_name}}, sizeof(*{{param_name}})); -{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} - clone->set_{{pf.field.name}}(mojo::internal::Clone({# - #}{{param_name}}->{{pf.field.name}}(), buf)); -{%- endfor %} -{%- for pf in struct.packed.packed_fields if pf.field.kind|is_handle_kind %} - mojo::internal::ResetIfNonNull({{param_name}}->{{pf.field.name}}()); -{%- endfor %} - return clone; -} - -// static -void ObjectTraits<{{class_name}}>::CloseHandles( - {{class_name}}* {{param_name}}) { -{%- for pf in struct.packed.packed_fields if pf.field.kind|is_object_kind %} - mojo::internal::CloseHandles({{param_name}}->{{pf.field.name}}_.ptr); -{%- endfor %} -{%- if struct|is_struct_with_handles %} - {{struct.name}}_Data_Destructor({{param_name}}); -{%- endif %} -} - -// static -void ObjectTraits<{{class_name}}>::EncodePointersAndHandles( - {{class_name}}* {{param_name}}, std::vector<mojo::Handle>* handles) { - {{ struct_macros.encodes(struct, param_name)|indent(2) }} -} - -// static -bool ObjectTraits<{{class_name}}>::DecodePointersAndHandles( - {{class_name}}* {{param_name}}, mojo::Message* message) { - {{ struct_macros.decodes(struct, param_name)|indent(2) }} - return true; -} diff --git a/mojo/public/bindings/generators/cpp_templates/struct_serialization_traits.tmpl b/mojo/public/bindings/generators/cpp_templates/struct_serialization_traits.tmpl deleted file mode 100644 index d422aaf..0000000 --- a/mojo/public/bindings/generators/cpp_templates/struct_serialization_traits.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{%- set full_class = "%s::internal::%s_Data"|format(namespace, struct.name) %} -{%- set name = struct.name|camel_to_underscores -%} - -template <> -class ObjectTraits<{{full_class}}> { - public: - static size_t ComputeSizeOf(const {{full_class}}* {{name}}); - static {{full_class}}* Clone(const {{full_class}}* {{name}}, Buffer* buf); - static void CloseHandles({{full_class}}* {{name}}); - static void EncodePointersAndHandles({{full_class}}* {{name}}, - std::vector<mojo::Handle>* handles); - static bool DecodePointersAndHandles({{full_class}}* {{name}}, - mojo::Message* message); -}; diff --git a/mojo/public/bindings/lib/array_internal.cc b/mojo/public/bindings/lib/array_internal.cc index a4ea930..17a26b2 100644 --- a/mojo/public/bindings/lib/array_internal.cc +++ b/mojo/public/bindings/lib/array_internal.cc @@ -34,5 +34,26 @@ ArrayDataTraits<bool>::BitRef::operator bool() const { return (*storage_ & mask_) != 0; } +// static +void ArraySerializationHelper<Handle>::EncodePointersAndHandles( + const ArrayHeader* header, + ElementType* elements, + std::vector<Handle>* handles) { + for (uint32_t i = 0; i < header->num_elements; ++i) + EncodeHandle(&elements[i], handles); +} + +// static +bool ArraySerializationHelper<Handle>::DecodePointersAndHandles( + const ArrayHeader* header, + ElementType* elements, + Message* message) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (!DecodeHandle(&elements[i], &message->handles)) + return false; + } + return true; +} + } // namespace internal } // namespace mojo diff --git a/mojo/public/bindings/lib/array_internal.h b/mojo/public/bindings/lib/array_internal.h index ef1c9c2..3894ed7 100644 --- a/mojo/public/bindings/lib/array_internal.h +++ b/mojo/public/bindings/lib/array_internal.h @@ -8,6 +8,7 @@ #include <new> #include "mojo/public/bindings/lib/bindings_internal.h" +#include "mojo/public/bindings/lib/bindings_serialization.h" #include "mojo/public/bindings/lib/buffer.h" #include "mojo/public/bindings/lib/passable.h" #include "mojo/public/system/core_cpp.h" @@ -92,6 +93,100 @@ struct ArrayDataTraits<bool> { } }; +// What follows is code to support the serialization of Array_Data<T>. There +// are two interesting cases: arrays of primitives and arrays of objects. +// Arrays of objects are represented as arrays of pointers to objects. + +template <typename T> +struct ArraySerializationHelper { + typedef T ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + return 0; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector<Handle>* handles) { + } + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message) { + return true; + } +}; + +template <> +struct ArraySerializationHelper<Handle> { + typedef Handle ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + return 0; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector<Handle>* handles); + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message); +}; + +template <typename P> +struct ArraySerializationHelper<P*> { + typedef StructPointer<P> ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + size_t result = 0; + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (elements[i].ptr) + result += elements[i].ptr->ComputeSize(); + } + return result; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (elements[i].ptr) + elements[i].ptr = elements[i].ptr->Clone(buf); + } + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector<Handle>* handles) { + for (uint32_t i = 0; i < header->num_elements; ++i) + Encode(&elements[i], handles); + } + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (!Decode(&elements[i], message)) + return false; + } + return true; + } +}; + template <typename T> class Array_Data { public: @@ -130,9 +225,38 @@ class Array_Data { reinterpret_cast<const char*>(this) + sizeof(*this)); } - private: - friend class internal::ObjectTraits<Array_Data<T> >; + size_t ComputeSize() const { + return Align(header_.num_bytes) + + ArraySerializationHelper<T>::ComputeSizeOfElements(&header_, storage()); + } + Array_Data<T>* Clone(Buffer* buf) const { + Array_Data<T>* clone = New(header_.num_elements, buf); + memcpy(clone->storage(), + storage(), + header_.num_bytes - sizeof(Array_Data<T>)); + + ArraySerializationHelper<T>::CloneElements(&clone->header_, + clone->storage(), buf); + return clone; + } + + void CloseHandles() { + // TODO(darin): Implement! + } + + void EncodePointersAndHandles(std::vector<Handle>* handles) { + ArraySerializationHelper<T>::EncodePointersAndHandles(&header_, storage(), + handles); + } + + bool DecodePointersAndHandles(Message* message) { + return ArraySerializationHelper<T>::DecodePointersAndHandles(&header_, + storage(), + message); + } + + private: Array_Data(size_t num_bytes, size_t num_elements) { header_.num_bytes = static_cast<uint32_t>(num_bytes); header_.num_elements = static_cast<uint32_t>(num_elements); diff --git a/mojo/public/bindings/lib/bindings_serialization.cc b/mojo/public/bindings/lib/bindings_serialization.cc index 4581656..919a4ed 100644 --- a/mojo/public/bindings/lib/bindings_serialization.cc +++ b/mojo/public/bindings/lib/bindings_serialization.cc @@ -6,6 +6,8 @@ #include <assert.h> +#include "mojo/public/bindings/lib/bindings_internal.h" + namespace mojo { namespace internal { @@ -67,26 +69,5 @@ bool DecodeHandle(Handle* handle, std::vector<Handle>* handles) { return true; } -// static -void ArrayHelper<Handle>::EncodePointersAndHandles( - const ArrayHeader* header, - ElementType* elements, - std::vector<Handle>* handles) { - for (uint32_t i = 0; i < header->num_elements; ++i) - EncodeHandle(&elements[i], handles); -} - -// static -bool ArrayHelper<Handle>::DecodePointersAndHandles( - const ArrayHeader* header, - ElementType* elements, - Message* message) { - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (!DecodeHandle(&elements[i], &message->handles)) - return false; - } - return true; -} - } // namespace internal } // namespace mojo diff --git a/mojo/public/bindings/lib/bindings_serialization.h b/mojo/public/bindings/lib/bindings_serialization.h index 863aed4..35f4a1d 100644 --- a/mojo/public/bindings/lib/bindings_serialization.h +++ b/mojo/public/bindings/lib/bindings_serialization.h @@ -5,11 +5,9 @@ #ifndef MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ #define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ -#include <string.h> - #include <vector> -#include "mojo/public/bindings/lib/bindings.h" +#include "mojo/public/bindings/lib/buffer.h" #include "mojo/public/bindings/lib/message.h" namespace mojo { @@ -41,49 +39,13 @@ bool ValidatePointer(const void* ptr, const Message& message); void EncodeHandle(Handle* handle, std::vector<Handle>* handles); bool DecodeHandle(Handle* handle, std::vector<Handle>* handles); -// All objects (structs and arrays) support the following operations: -// - computing size -// - cloning -// - encoding pointers and handles -// - decoding pointers and handles -// -// The following functions are used to select the proper ObjectTraits<> -// specialization. - -template <typename T> -inline size_t ComputeSizeOf(const T* obj) { - return obj ? ObjectTraits<T>::ComputeSizeOf(obj) : 0; -} - -template <typename T> -inline T* Clone(const T* obj, Buffer* buf) { - return obj ? ObjectTraits<T>::Clone(obj, buf) : NULL; -} - -template <typename T> -inline void CloseHandles(T* obj) { - if (obj) - ObjectTraits<T>::CloseHandles(obj); -} - -template <typename T> -inline void EncodePointersAndHandles(T* obj, - std::vector<Handle>* handles) { - ObjectTraits<T>::EncodePointersAndHandles(obj, handles); -} - -template <typename T> -inline bool DecodePointersAndHandles(T* obj, Message* message) { - return ObjectTraits<T>::DecodePointersAndHandles(obj, message); -} - // The following 2 functions are used to encode/decode all objects (structs and // arrays) in a consistent manner. template <typename T> inline void Encode(T* obj, std::vector<Handle>* handles) { if (obj->ptr) - EncodePointersAndHandles(obj->ptr, handles); + obj->ptr->EncodePointersAndHandles(handles); EncodePointer(obj->ptr, &obj->offset); } @@ -93,137 +55,12 @@ inline bool Decode(T* obj, Message* message) { if (obj->ptr) { if (!ValidatePointer(obj->ptr, *message)) return false; - if (!DecodePointersAndHandles(obj->ptr, message)) + if (!obj->ptr->DecodePointersAndHandles(message)) return false; } return true; } -// What follows is code to support the ObjectTraits<> specialization of -// Array_Data<T>. There are two interesting cases: arrays of primitives and -// arrays of objects. Arrays of objects are represented as arrays of pointers -// to objects. - -template <typename T> -struct ArrayHelper { - typedef T ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - return 0; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector<Handle>* handles) { - } - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message) { - return true; - } -}; - -template <> -struct ArrayHelper<Handle> { - typedef Handle ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - return 0; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector<Handle>* handles); - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message); -}; - -template <typename P> -struct ArrayHelper<P*> { - typedef StructPointer<P> ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - size_t result = 0; - for (uint32_t i = 0; i < header->num_elements; ++i) - result += ComputeSizeOf(elements[i].ptr); - return result; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - for (uint32_t i = 0; i < header->num_elements; ++i) - elements[i].ptr = Clone(elements[i].ptr, buf); - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector<Handle>* handles) { - for (uint32_t i = 0; i < header->num_elements; ++i) - Encode(&elements[i], handles); - } - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message) { - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (!Decode(&elements[i], message)) - return false; - } - return true; - } -}; - -template <typename T> -class ObjectTraits<Array_Data<T> > { - public: - static size_t ComputeSizeOf(const Array_Data<T>* array) { - return Align(array->header_.num_bytes) + - ArrayHelper<T>::ComputeSizeOfElements(&array->header_, - array->storage()); - } - - static Array_Data<T>* Clone(const Array_Data<T>* array, Buffer* buf) { - Array_Data<T>* clone = Array_Data<T>::New(array->header_.num_elements, buf); - memcpy(clone->storage(), - array->storage(), - array->header_.num_bytes - sizeof(Array_Data<T>)); - - ArrayHelper<T>::CloneElements(&clone->header_, clone->storage(), buf); - return clone; - } - - static void CloseHandles(Array_Data<T>* array) { - // TODO(darin): Implement! - } - - static void EncodePointersAndHandles(Array_Data<T>* array, - std::vector<Handle>* handles) { - ArrayHelper<T>::EncodePointersAndHandles(&array->header_, array->storage(), - handles); - } - - static bool DecodePointersAndHandles(Array_Data<T>* array, - Message* message) { - return ArrayHelper<T>::DecodePointersAndHandles(&array->header_, - array->storage(), - message); - } -}; - } // namespace internal } // namespace mojo diff --git a/mojo/public/bindings/mojom_bindings_generator.gypi b/mojo/public/bindings/mojom_bindings_generator.gypi index f6d90a8..3d4d580 100644 --- a/mojo/public/bindings/mojom_bindings_generator.gypi +++ b/mojo/public/bindings/mojom_bindings_generator.gypi @@ -26,14 +26,11 @@ '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/module.h.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/module_internal.h.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/params_definition.tmpl', - '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/params_serialization.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_declaration.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_definition.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_destructor.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_macros.tmpl', - '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_serialization_definition.tmpl', - '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/struct_serialization_traits.tmpl', '<(DEPTH)/mojo/public/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '<(DEPTH)/mojo/public/bindings/generators/js_templates/interface_definition.tmpl', '<(DEPTH)/mojo/public/bindings/generators/js_templates/module.js.tmpl', |