diff options
author | qsr <qsr@chromium.org> | 2014-10-13 06:55:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-13 13:55:51 +0000 |
commit | a456ad3f2208af7d4f529a25d33354ae2626cfd3 (patch) | |
tree | 88fa726fec6ed93a2d99d22626276d760d63aae5 /mojo | |
parent | 98ff22abeecf0c949bfcbab1a85dcba93f8d2285 (diff) | |
download | chromium_src-a456ad3f2208af7d4f529a25d33354ae2626cfd3.zip chromium_src-a456ad3f2208af7d4f529a25d33354ae2626cfd3.tar.gz chromium_src-a456ad3f2208af7d4f529a25d33354ae2626cfd3.tar.bz2 |
mojo: Add maps to java bindings.
BUG=413863
R=ppi@chromium.org,erg@chromium.org
Review URL: https://codereview.chromium.org/648683003
Cr-Commit-Position: refs/heads/master@{#299295}
Diffstat (limited to 'mojo')
5 files changed, 90 insertions, 23 deletions
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java index b18e5c5..d97547f 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java @@ -4,6 +4,7 @@ package org.chromium.mojo.bindings; +import org.chromium.mojo.bindings.Struct.DataHeader; import org.chromium.mojo.system.AsyncWaiter; import org.chromium.mojo.system.Handle; @@ -29,16 +30,14 @@ public class BindingsHelper { public static final int POINTER_SIZE = 8; /** - * The value used for the expected length of a non-fixed size array. + * The header for a serialized map element. */ - public static final int UNSPECIFIED_ARRAY_LENGTH = -1; + public static final DataHeader MAP_STRUCT_HEADER = new DataHeader(24, 2); /** - * Align |size| on {@link BindingsHelper#ALIGNMENT}. + * The value used for the expected length of a non-fixed size array. */ - public static int align(int size) { - return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); - } + public static final int UNSPECIFIED_ARRAY_LENGTH = -1; /** * Passed as |arrayNullability| when neither the array nor its elements are nullable. @@ -66,6 +65,13 @@ public class BindingsHelper { /** * Align |size| on {@link BindingsHelper#ALIGNMENT}. */ + public static int align(int size) { + return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); + } + + /** + * Align |size| on {@link BindingsHelper#ALIGNMENT}. + */ public static long align(long size) { return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); } diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java index efb9842..80ed9d1 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java @@ -145,6 +145,21 @@ public class Decoder { } /** + * Deserializes a {@link DataHeader} at the given offset and checks if it is correct for a map. + */ + public void readDataHeaderForMap() { + DataHeader si = readDataHeader(); + if (si.size != BindingsHelper.MAP_STRUCT_HEADER.size) { + throw new DeserializationException( + "Incorrect header for map. The size is incorrect."); + } + if (si.numFields != BindingsHelper.MAP_STRUCT_HEADER.numFields) { + throw new DeserializationException( + "Incorrect header for map. The number of fields is incorrect."); + } + } + + /** * Deserializes a byte at the given offset. */ public byte readByte(int offset) { diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java index e3b2bfe..ef04f6d 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java @@ -422,6 +422,11 @@ public class Encoder { } } + public Encoder encoderForMap(int offset) { + encodePointerToNextUnclaimedData(offset); + return getEncoderAtDataOffset(BindingsHelper.MAP_STRUCT_HEADER); + } + /** * Encodes an array of {@link InterfaceRequest}. */ diff --git a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl index 2fc4439..d95a4d4 100644 --- a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl +++ b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl @@ -1,44 +1,68 @@ {% from "constant_definition.tmpl" import constant_def %} {% from "enum_definition.tmpl" import enum_def %} -{%- macro array_expected_length(kind) -%} -{%- if kind|is_fixed_array_kind -%} -{{kind.length}} -{%- else -%} -org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH -{%- endif -%} -{%- endmacro -%} - {% macro encode(variable, kind, offset, bit, level=0) %} {% if kind|is_pointer_array_kind %} {% set sub_kind = kind.kind %} if ({{variable}} == null) { encoder{{level}}.encodeNullPointer({{offset}}, {{kind|is_nullable_kind|java_true_false}}); } else { - org.chromium.mojo.bindings.Encoder encoder{{level + 1}} = encoder{{level}}.encodePointerArray({{variable}}.length, {{offset}}, {{array_expected_length(kind)}}); + org.chromium.mojo.bindings.Encoder encoder{{level + 1}} = encoder{{level}}.encodePointerArray({{variable}}.length, {{offset}}, {{kind|array_expected_length}}); for (int i{{level}} = 0; i{{level}} < {{variable}}.length; ++i{{level}}) { {{encode(variable~'[i'~level~']', sub_kind, 'DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i'~level, 0, level+1)|indent(8)}} } } +{% elif kind|is_map_kind %} +if ({{variable}} == null) { + encoder{{level}}.encodeNullPointer({{offset}}, {{kind|is_nullable_kind|java_true_false}}); +} else { + org.chromium.mojo.bindings.Encoder encoder{{level + 1}} = encoder{{level}}.encoderForMap({{offset}}); + int size{{level}} = {{variable}}.size(); + {{kind.key_kind|java_type}}[] keys{{level}} = {{kind.key_kind|array|new_array('size'~level)}}; + {{kind.value_kind|java_type}}[] values{{level}} = {{kind.value_kind|array|new_array('size'~level)}}; + int index{{level}} = 0; + for (java.util.Map.Entry<{{kind.key_kind|java_type(true)}}, {{kind.value_kind|java_type(true)}}> entry{{level}} : {{variable}}.entrySet()) { + keys{{level}}[index{{level}}] = entry{{level}}.getKey(); + values{{level}}[index{{level}}] = entry{{level}}.getValue(); + } + {{encode('keys'~level, kind.key_kind|array, 'DataHeader.HEADER_SIZE', 0, level+1)|indent(4)}} + {{encode('values'~level, kind.value_kind|array, 'DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE', 0, level+1)|indent(4)}} +} {% else %} encoder{{level}}.{{kind|encode_method(variable, offset, bit)}}; {% endif %} {% endmacro %} {% macro decode(variable, kind, offset, bit, level=0) %} -{% if kind|is_struct_kind or kind|is_pointer_array_kind %} +{% if kind|is_struct_kind or kind|is_pointer_array_kind or kind|is_map_kind %} org.chromium.mojo.bindings.Decoder decoder{{level+1}} = decoder{{level}}.readPointer({{offset}}, {{kind|is_nullable_kind|java_true_false}}); {% if kind|is_struct_kind %} {{variable}} = {{kind|java_type}}.decode(decoder{{level+1}}); -{% else %}{# kind|is_pointer_array_kind #} +{% else %}{# kind|is_pointer_array_kind or is_map_kind #} if (decoder{{level+1}} == null) { {{variable}} = null; } else { - DataHeader si{{level+1}} = decoder{{level+1}}.readDataHeaderForPointerArray({{array_expected_length(kind)}}); +{% if kind|is_map_kind %} + decoder{{level+1}}.readDataHeaderForMap(); + {{kind.key_kind|java_type}}[] keys{{level}}; + {{kind.value_kind|java_type}}[] values{{level}}; + { + {{decode('keys'~level, kind.key_kind|array, 'DataHeader.HEADER_SIZE', 0, level+1)|indent(8)}} + } + { + {{decode('values'~level, kind.value_kind|array('keys'~level~'.length'), 'DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE', 0, level+1)|indent(8)}} + } + {{variable}} = new java.util.HashMap<{{kind.key_kind|java_type(true)}}, {{kind.value_kind|java_type(true)}}>(); + for (int index{{level}} = 0; index{{level}} < keys{{level}}.length; ++index{{level}}) { + {{variable}}.put(keys{{level}}[index{{level}}], values{{level}}[index{{level}}]); + } +{% else %} + DataHeader si{{level+1}} = decoder{{level+1}}.readDataHeaderForPointerArray({{kind|array_expected_length}}); {{variable}} = {{kind|new_array('si'~(level+1)~'.numFields')}}; for (int i{{level+1}} = 0; i{{level+1}} < si{{level+1}}.numFields; ++i{{level+1}}) { {{decode(variable~'[i'~(level+1)~']', kind.kind, 'DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i'~(level+1), 0, level+1)|indent(8)}} } +{% endif %} } {% endif %} {% else %} diff --git a/mojo/public/tools/bindings/generators/mojom_java_generator.py b/mojo/public/tools/bindings/generators/mojom_java_generator.py index 043d9e3..bf0c80a 100644 --- a/mojo/public/tools/bindings/generators/mojom_java_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_java_generator.py @@ -181,11 +181,7 @@ def AppendEncodeDecodeParams(initial_params, context, kind, bit): else: params.append(GetJavaTrueFalse(mojom.IsNullableKind(kind))) if mojom.IsAnyArrayKind(kind): - if mojom.IsFixedArrayKind(kind): - params.append(str(kind.length)) - else: - params.append( - 'org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH'); + params.append(GetArrayExpectedLength(kind)) if mojom.IsInterfaceKind(kind): params.append('%s.MANAGER' % GetJavaType(context, kind)) if mojom.IsAnyArrayKind(kind) and mojom.IsInterfaceKind(kind.kind): @@ -253,6 +249,10 @@ def GetJavaType(context, kind, boxed=False): if mojom.IsInterfaceRequestKind(kind): return ('org.chromium.mojo.bindings.InterfaceRequest<%s>' % GetNameForKind(context, kind.kind)) + if mojom.IsMapKind(kind): + return 'java.util.Map<%s, %s>' % ( + GetBoxedJavaType(context, kind.key_kind), + GetBoxedJavaType(context, kind.value_kind)) if mojom.IsAnyArrayKind(kind): return '%s[]' % GetJavaType(context, kind.kind) if mojom.IsEnumKind(kind): @@ -323,6 +323,20 @@ def ExpressionToText(context, token, kind_spec=''): return 'java.lang.Float.NaN' return token +def GetArrayKind(kind, size = None): + if size is None: + return mojom.Array(kind) + else: + array = mojom.FixedArray(0, kind) + array.java_map_size = size + return array + +def GetArrayExpectedLength(kind): + if mojom.IsFixedArrayKind(kind): + return getattr(kind, 'java_map_size', str(kind.length)) + else: + return 'org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH' + def IsPointerArrayKind(kind): if not mojom.IsAnyArrayKind(kind): return False @@ -379,6 +393,8 @@ def ZipContentInto(root, zip_filename): class Generator(generator.Generator): java_filters = { + 'array': GetArrayKind, + 'array_expected_length': GetArrayExpectedLength, 'interface_response_name': GetInterfaceResponseName, 'constant_value': ConstantValue, 'default_value': DefaultValue, @@ -389,6 +405,7 @@ class Generator(generator.Generator): 'has_method_without_response': HasMethodWithoutResponse, 'is_fixed_array_kind': mojom.IsFixedArrayKind, 'is_handle': mojom.IsNonInterfaceHandleKind, + 'is_map_kind': mojom.IsMapKind, 'is_nullable_kind': mojom.IsNullableKind, 'is_pointer_array_kind': IsPointerArrayKind, 'is_struct_kind': mojom.IsStructKind, |