summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mojo/mojo_edk_tests.gyp3
-rw-r--r--mojo/mojo_public.gyp13
-rw-r--r--mojo/public/cpp/bindings/tests/BUILD.gn3
-rw-r--r--mojo/public/cpp/bindings/tests/struct_traits_unittest.cc40
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc29
-rw-r--r--mojo/public/cpp/bindings/tests/struct_with_traits_impl.h78
-rw-r--r--mojo/public/interfaces/bindings/tests/BUILD.gn11
-rw-r--r--mojo/public/interfaces/bindings/tests/struct_with_traits.mojom16
-rw-r--r--mojo/public/interfaces/bindings/tests/struct_with_traits.typemap14
-rw-r--r--mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom2
-rw-r--r--mojo/public/interfaces/bindings/tests/test_native_types.mojom5
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl1
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl47
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl29
14 files changed, 279 insertions, 12 deletions
diff --git a/mojo/mojo_edk_tests.gyp b/mojo/mojo_edk_tests.gyp
index 71489d6..e55389c 100644
--- a/mojo/mojo_edk_tests.gyp
+++ b/mojo/mojo_edk_tests.gyp
@@ -56,6 +56,7 @@
'mojo_public.gyp:mojo_public_test_interfaces',
'mojo_public.gyp:mojo_public_test_interfaces_blink',
'mojo_public.gyp:mojo_public_test_interfaces_chromium',
+ 'mojo_public.gyp:mojo_public_test_interfaces_struct_traits',
'mojo_public.gyp:mojo_public_test_utils',
'mojo_public.gyp:mojo_utility',
],
@@ -94,6 +95,8 @@
'public/cpp/bindings/tests/string_unittest.cc',
'public/cpp/bindings/tests/struct_traits_unittest.cc',
'public/cpp/bindings/tests/struct_unittest.cc',
+ 'public/cpp/bindings/tests/struct_with_traits_impl.cc',
+ 'public/cpp/bindings/tests/struct_with_traits_impl.h',
'public/cpp/bindings/tests/sync_method_unittest.cc',
'public/cpp/bindings/tests/type_conversion_unittest.cc',
'public/cpp/bindings/tests/union_unittest.cc',
diff --git a/mojo/mojo_public.gyp b/mojo/mojo_public.gyp
index 18f3b75f..d833edd 100644
--- a/mojo/mojo_public.gyp
+++ b/mojo/mojo_public.gyp
@@ -376,6 +376,19 @@
'includes': [ 'mojom_bindings_generator_explicit.gypi' ],
},
{
+ 'target_name': 'mojo_public_test_interfaces_struct_traits',
+ 'type': 'static_library',
+ 'variables': {
+ 'mojom_extra_generator_args': [
+ '--typemap', '<(DEPTH)/mojo/public/interfaces/bindings/tests/struct_with_traits.typemap',
+ ],
+ },
+ 'sources': [
+ 'public/interfaces/bindings/tests/struct_with_traits.mojom',
+ ],
+ 'includes': [ 'mojom_bindings_generator.gypi' ],
+ },
+ {
'target_name': 'mojo_public_test_interfaces_mojom_blink',
'type': 'none',
'variables': {
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index 507ec8c..cb5029e 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -42,6 +42,8 @@ source_set("tests") {
"string_unittest.cc",
"struct_traits_unittest.cc",
"struct_unittest.cc",
+ "struct_with_traits_impl.cc",
+ "struct_with_traits_impl.h",
"sync_method_unittest.cc",
"type_conversion_unittest.cc",
"union_unittest.cc",
@@ -62,6 +64,7 @@ source_set("tests") {
"//mojo/public/interfaces/bindings/tests:test_interfaces_blink",
"//mojo/public/interfaces/bindings/tests:test_interfaces_chromium",
"//mojo/public/interfaces/bindings/tests:test_interfaces_experimental",
+ "//mojo/public/interfaces/bindings/tests:test_struct_traits_interfaces",
"//testing/gtest",
]
}
diff --git a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
index 07d7750..02fb53f 100644
--- a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
@@ -10,7 +10,9 @@
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/tests/rect_blink.h"
#include "mojo/public/cpp/bindings/tests/rect_chromium.h"
+#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h"
#include "mojo/public/cpp/bindings/weak_binding_set.h"
+#include "mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-blink.h"
#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-chromium.h"
#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h"
@@ -95,10 +97,12 @@ class BlinkRectServiceImpl : public blink::RectService {
};
// A test which runs both Chromium and Blink implementations of a RectService.
-class StructTraitsTest : public testing::Test {
+class StructTraitsTest : public testing::Test,
+ public TraitsTestService {
public:
StructTraitsTest() {}
+ protected:
void BindToChromiumService(mojo::InterfaceRequest<RectService> request) {
chromium_bindings_.AddBinding(&chromium_service_, std::move(request));
}
@@ -107,7 +111,18 @@ class StructTraitsTest : public testing::Test {
blink_bindings_.AddBinding(&blink_service_, std::move(request));
}
+ TraitsTestServicePtr GetTraitsTestProxy() {
+ return traits_test_bindings_.CreateInterfacePtrAndBind(this);
+ }
+
private:
+ // TraitsTestService:
+ void PassStructWithTraits(
+ const StructWithTraitsImpl& s,
+ const PassStructWithTraitsCallback& callback) override {
+ callback.Run(s);
+ }
+
base::MessageLoop loop_;
ChromiumRectServiceImpl chromium_service_;
@@ -115,6 +130,8 @@ class StructTraitsTest : public testing::Test {
BlinkRectServiceImpl blink_service_;
mojo::WeakBindingSet<blink::RectService> blink_bindings_;
+
+ mojo::WeakBindingSet<TraitsTestService> traits_test_bindings_;
};
} // namespace
@@ -181,5 +198,26 @@ TEST_F(StructTraitsTest, BlinkProxyToChromiumService) {
}
}
+TEST_F(StructTraitsTest, FieldTypes) {
+ StructWithTraitsImpl input;
+ input.set_bool(true);
+ input.set_uint32(7);
+ input.set_uint64(42);
+ input.set_string("hello world!");
+
+ base::RunLoop loop;
+ TraitsTestServicePtr proxy = GetTraitsTestProxy();
+ proxy->PassStructWithTraits(
+ input,
+ [&] (const StructWithTraitsImpl& passed) {
+ EXPECT_EQ(input.get_bool(), passed.get_bool());
+ EXPECT_EQ(input.get_uint32(), passed.get_uint32());
+ EXPECT_EQ(input.get_uint64(), passed.get_uint64());
+ EXPECT_EQ(input.get_string(), passed.get_string());
+ loop.Quit();
+ });
+ loop.Run();
+}
+
} // namespace test
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc
new file mode 100644
index 0000000..ee08ecf
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h"
+
+#include "mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.h"
+
+namespace mojo {
+namespace test {
+
+StructWithTraitsImpl::StructWithTraitsImpl() {}
+
+StructWithTraitsImpl::~StructWithTraitsImpl() {}
+
+} // namespace test
+
+// static
+bool StructTraits<test::StructWithTraits, test::StructWithTraitsImpl>::Read(
+ test::StructWithTraits_Reader r,
+ test::StructWithTraitsImpl* out) {
+ out->set_bool(r.f_bool());
+ out->set_uint32(r.f_uint32());
+ out->set_uint64(r.f_uint64());
+ out->set_string(r.f_string().as_string());
+ return true;
+}
+
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h
new file mode 100644
index 0000000..d56dae5
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h
@@ -0,0 +1,78 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/strings/string_piece.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
+
+namespace mojo {
+namespace test {
+
+// The mojom types are forward-declared to avoid circular dependencies between
+// this and generated headers.
+class StructWithTraits;
+class StructWithTraits_Reader;
+
+// A type which knows how to look like a mojo::test::StructWithTraits mojom type
+// by way of mojo::StructTraits.
+class StructWithTraitsImpl {
+ public:
+ StructWithTraitsImpl();
+ ~StructWithTraitsImpl();
+
+ void set_bool(bool value) { bool_ = value; }
+ bool get_bool() const { return bool_; }
+
+ void set_uint32(uint32_t value) { uint32_ = value; }
+ uint32_t get_uint32() const { return uint32_; }
+
+ void set_uint64(uint64_t value) { uint64_ = value; }
+ uint64_t get_uint64() const { return uint64_; }
+
+ void set_string(std::string value) { string_ = value; }
+ base::StringPiece get_string() const { return string_; }
+
+ private:
+ bool bool_ = false;
+ uint32_t uint32_ = 0;
+ uint64_t uint64_ = 0;
+ std::string string_;
+};
+
+} // namespace test
+
+template <>
+struct StructTraits<test::StructWithTraits, test::StructWithTraitsImpl> {
+ // Deserialization to test::StructTraitsImpl.
+ static bool Read(test::StructWithTraits_Reader r,
+ test::StructWithTraitsImpl* out);
+
+ // Fields in test::StructWithTraits.
+ // See src/mojo/public/interfaces/bindings/tests/test_native_types.mojom.
+ static bool f_bool(const test::StructWithTraitsImpl& value) {
+ return value.get_bool();
+ }
+
+ static uint32_t f_uint32(const test::StructWithTraitsImpl& value) {
+ return value.get_uint32();
+ }
+
+ static uint64_t f_uint64(const test::StructWithTraitsImpl& value) {
+ return value.get_uint64();
+ }
+
+ static base::StringPiece f_string(const test::StructWithTraitsImpl& value) {
+ return value.get_string();
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn
index 7758a65..42f16c3 100644
--- a/mojo/public/interfaces/bindings/tests/BUILD.gn
+++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -29,6 +29,17 @@ mojom("test_interfaces") {
with_environment = false
}
+mojom("test_struct_traits_interfaces") {
+ testonly = true
+ sources = [
+ "struct_with_traits.mojom",
+ ]
+
+ typemaps = [ "struct_with_traits.typemap" ]
+
+ with_environment = false
+}
+
mojom("test_interfaces_experimental") {
testonly = true
sources = [
diff --git a/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom b/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom
new file mode 100644
index 0000000..1ac8fe8
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom
@@ -0,0 +1,16 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module mojo.test;
+
+struct StructWithTraits {
+ bool f_bool;
+ uint32 f_uint32;
+ uint64 f_uint64;
+ string f_string;
+};
+
+interface TraitsTestService {
+ PassStructWithTraits(StructWithTraits s) => (StructWithTraits passed);
+};
diff --git a/mojo/public/interfaces/bindings/tests/struct_with_traits.typemap b/mojo/public/interfaces/bindings/tests/struct_with_traits.typemap
new file mode 100644
index 0000000..244c471
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/struct_with_traits.typemap
@@ -0,0 +1,14 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+{
+ "c++": {
+ "mojo.test.StructWithTraits": {
+ "typename": "mojo::test::StructWithTraitsImpl",
+ "headers": [
+ "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h"
+ ]
+ }
+ }
+}
diff --git a/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom b/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
index 62ff7a7..b331d21 100644
--- a/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
@@ -7,7 +7,7 @@ module mojo.test;
interface FooInterface {};
struct StructContainsAssociated {
- associated FooInterface foo_interface;
+ associated FooInterface? foo_interface;
associated FooInterface& foo_request;
};
diff --git a/mojo/public/interfaces/bindings/tests/test_native_types.mojom b/mojo/public/interfaces/bindings/tests/test_native_types.mojom
index ff7d252..ddb88cf 100644
--- a/mojo/public/interfaces/bindings/tests/test_native_types.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_native_types.mojom
@@ -23,11 +23,10 @@ interface PicklePasser {
=> (array<array<PickledStruct>> passed);
};
-// Used to verify support for native serialization of mojom-defined structs.
-// This is tested with a typemap applied to the Rect type from rect.mojom.
+// Used to verify support for native serialization of mojom-defined structs
+// using StrucTraits with different variants of the Rect type from rect.mojom.
interface RectService {
AddRect(Rect r);
GetLargestRect() => (Rect largest);
};
-
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 2691e772..fa7dd15 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <ostream>
+#include "base/strings/string_piece.h"
#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
index a2cee64..d0ef30a4 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
@@ -53,8 +53,13 @@ class {{struct.name}}_Reader {
{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
{%- set kind = pf.field.kind -%}
{%- set name = pf.field.name -%}
+{%- if kind|is_nullable_kind %}
+ bool has_{{name}}() const;
+{%- endif %}
{%- if kind|is_struct_kind and not kind|is_native_only_kind %}
{{kind|get_name_for_kind}}::Reader {{name}}() const;
+{%- elif kind|is_string_kind %}
+ base::StringPiece {{name}}() const;
{%- elif kind|is_union_kind %}
// TODO(rockot): Support reading unions. ({{name}}() omitted)
{%- elif kind|is_object_kind %}
@@ -86,10 +91,21 @@ struct {{struct.name}}_SerializerTraits_ {
static size_t GetSize(const NativeType& input) {
size_t size = sizeof(internal::{{struct.name}}_Data);
{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
-{%- if pf.field.kind|is_object_kind %}
- NOTREACHED() << "Mojom struct traits only support POD fields at this time. "
- << "Cannot determine the size of field {{pf.field.name}}";
+ do {
+{%- if pf.field.kind|is_nullable_kind %}
+ if (!mojo::StructTraits<{{struct.name}}, NativeType>
+ ::has_{{pf.field.name}}(input))
+ break;
+{%- endif %}
+{%- if pf.field.kind|is_string_kind %}
+ size += mojo::internal::String_Data::Traits::GetStorageSize(
+ static_cast<uint32_t>(mojo::StructTraits<{{struct.name}}, NativeType>
+ ::{{pf.field.name}}(input).size()));
+{%- elif pf.field.kind|is_object_kind %}
+ NOTREACHED() << "Unsupported field type for StructTraits: "
+ << "{{pf.field.name}}";
{%- endif %}
+ } while (false);
{%- endfor %}
return size;
}
@@ -99,11 +115,30 @@ struct {{struct.name}}_SerializerTraits_ {
internal::{{struct.name}}_Data** output) {
internal::{{struct.name}}_Data* result =
internal::{{struct.name}}_Data::New(buffer);
-{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
+{%- for pf in struct.packed.packed_fields_in_ordinal_order -%}
{%- set name = pf.field.name -%}
{%- set kind = pf.field.kind %}
- result->{{name}} = mojo::StructTraits<{{struct.name}}, NativeType>
- ::{{name}}(input);
+ do {
+{%- if kind|is_nullable_kind %}
+ if (!mojo::StructTraits<{{struct.name}}, NativeType>
+ ::has_{{name}}(input))
+ break;
+{%- endif %}
+{%- if kind|is_string_kind %}
+ base::StringPiece input_{{name}} =
+ mojo::StructTraits<{{struct.name}}, NativeType>::{{name}}(input);
+ result->{{name}}.ptr =
+ mojo::internal::String_Data::New(input_{{name}}.size(), buffer);
+ memcpy(result->{{name}}.ptr->storage(), input_{{name}}.data(),
+ input_{{name}}.size());
+{%- elif kind|is_object_kind %}
+ NOTREACHED() << "Unsupported field type for StructTraits: "
+ << "{{pf.field.name}}";
+{%- else %}
+ result->{{name}} = mojo::StructTraits<{{struct.name}}, NativeType>
+ ::{{name}}(input);
+{%- endif %}
+ } while (false);
{%- endfor %}
*output = result;
}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl
index e6577b9..485a8ec 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl
@@ -39,11 +39,38 @@ bool Deserialize_(internal::{{struct.name}}_Data* input,
{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
{%- set name = pf.field.name -%}
-{%- set kind = pf.field.kind -%}
+{%- set kind = pf.field.kind %}
+{%- if kind|is_nullable_kind %}
+bool {{struct.name}}_Reader::has_{{name}}() const {
+{%- if kind|is_union_kind %}
+ return !data_->{{name}}.is_null();
+{%- elif kind|is_object_kind %}
+ return data_->{{name}}.ptr != nullptr;
+{%- elif kind|is_interface_kind %}
+ return data_->{{name}}.handle.is_valid();
+{%- elif kind|is_interface_request_kind %}
+ return data_->{{name}}.is_valid();
+{%- elif kind|is_associated_interface_kind %}
+ return data_->{{name}}.interface_id == mojo::internal::kInvalidInterfaceId;
+{%- elif kind|is_associated_interface_request_kind %}
+ return data_->{{name}} == mojo::internal::kInvalidInterfaceId;
+{%- elif kind|is_any_handle_kind %}
+ return data_->{{name}}.is_valid();
+{%- else %}
+ return !!data_->{{name}};
+{%- endif %}
+}
+{%- endif %}
{%- if kind|is_struct_kind and not kind|is_native_only_kind %}
{{kind|get_name_for_kind}}_Reader {{struct.name}}_Reader::{{name}}() const {
return {{kind|get_name_for_kind}}_Reader(data_->{{name}}.ptr, context_);
}
+{%- elif kind|is_string_kind %}
+base::StringPiece {{struct.name}}_Reader::{{name}}() const {
+ DCHECK(data_->{{name}}.ptr);
+ return base::StringPiece(data_->{{name}}.ptr->storage(),
+ data_->{{name}}.ptr->size());
+}
{%- endif %}
{%- endfor %}