def testBools(self): struct = mojom.Struct('test') struct.AddField('bit0', mojom.BOOL) struct.AddField('bit1', mojom.BOOL) struct.AddField('int', mojom.INT32) struct.AddField('bit2', mojom.BOOL) struct.AddField('bit3', mojom.BOOL) struct.AddField('bit4', mojom.BOOL) struct.AddField('bit5', mojom.BOOL) struct.AddField('bit6', mojom.BOOL) struct.AddField('bit7', mojom.BOOL) struct.AddField('bit8', mojom.BOOL) ps = pack.PackedStruct(struct) self.assertEqual(10, len(ps.packed_fields)) # First 8 bits packed together. for i in range(8): pf = ps.packed_fields[i] self.assertEqual(0, pf.offset) self.assertEqual("bit%d" % i, pf.field.mojom_name) self.assertEqual(i, pf.bit) # Ninth bit goes into second byte. self.assertEqual("bit8", ps.packed_fields[8].field.mojom_name) self.assertEqual(1, ps.packed_fields[8].offset) self.assertEqual(0, ps.packed_fields[8].bit) # int comes last. self.assertEqual("int", ps.packed_fields[9].field.mojom_name) self.assertEqual(4, ps.packed_fields[9].offset)
def testGetVersionInfoComplexOrder(self): """Tests pack.GetVersionInfo() using a struct whose definition order, ordinal order and pack order for fields are all different. """ struct = mojom.Struct('test') struct.AddField('field_3', mojom.BOOL, ordinal=3, attributes={'MinVersion': 3}) struct.AddField('field_0', mojom.INT32, ordinal=0) struct.AddField('field_1', mojom.INT64, ordinal=1, attributes={'MinVersion': 2}) struct.AddField('field_2', mojom.INT64, ordinal=2, attributes={'MinVersion': 3}) ps = pack.PackedStruct(struct) versions = pack.GetVersionInfo(ps) self.assertEquals(3, len(versions)) self.assertEquals(0, versions[0].version) self.assertEquals(1, versions[0].num_fields) self.assertEquals(16, versions[0].num_bytes) self.assertEquals(2, versions[1].version) self.assertEquals(2, versions[1].num_fields) self.assertEquals(24, versions[1].num_bytes) self.assertEquals(3, versions[2].version) self.assertEquals(4, versions[2].num_fields) self.assertEquals(32, versions[2].num_bytes)
def _GetResponseStructFromMethod(self, method): params_class = "%s_%s_ResponseParams" % ( GetNameForElement(method.interface), GetNameForElement(method)) struct = mojom.Struct(params_class, module=method.interface.module) for param in method.response_parameters: struct.AddField("out%s" % GetNameForElement(param), param.kind, param.ordinal, attributes=param.attributes) return self._AddStructComputedData(False, struct)
def testAllTypes(self): return self._CheckPackSequence( (mojom.BOOL, mojom.INT8, mojom.STRING, mojom.UINT8, mojom.INT16, mojom.DOUBLE, mojom.UINT16, mojom.INT32, mojom.UINT32, mojom.INT64, mojom.FLOAT, mojom.STRING, mojom.HANDLE, mojom.UINT64, mojom.Struct('test'), mojom.Array(), mojom.STRING.MakeNullableKind()), (1, 2, 4, 5, 7, 3, 6, 8, 9, 10, 11, 13, 12, 14, 15, 16, 17, 18), (0, 1, 2, 4, 6, 8, 16, 24, 28, 32, 40, 44, 48, 56, 64, 72, 80, 88))
def testOrdinalOrder(self): struct = mojom.Struct('test') struct.AddField('testfield1', mojom.INT32, 2) struct.AddField('testfield2', mojom.INT32, 1) ps = pack.PackedStruct(struct) self.assertEqual(2, len(ps.packed_fields)) self.assertEqual('testfield2', ps.packed_fields[0].field.mojom_name) self.assertEqual('testfield1', ps.packed_fields[1].field.mojom_name)
def testNonInterfaceAsInterfaceRequest(self): """Tests that a non-interface cannot be used for interface requests.""" module = mojom.Module('test_module', 'test_namespace') struct = mojom.Struct('TestStruct', module=module) with self.assertRaises(Exception) as e: mojom.InterfaceRequest(struct) self.assertEquals( e.exception.__str__(), 'Interface request requires \'x:TestStruct\' to be an interface.')
def _GetResponseStructFromMethod(method): """Converts a method's response_parameters into the fields of a struct.""" params_class = "%s_%s_ResponseParams" % (method.interface.mojom_name, method.mojom_name) struct = mojom.Struct(params_class, module=method.interface.module) for param in method.response_parameters: struct.AddField(param.mojom_name, param.kind, param.ordinal, attributes=param.attributes) _AddStructComputedData(False, struct) return struct
def GetResponseStructFromMethod(method): params_class = "%s_%s_ResponseParams" % (GetNameForElement(method.interface), GetNameForElement(method)) struct = mojom.Struct(params_class, module=method.interface.module) for param in method.response_parameters: struct.AddField("out%s" % GetNameForElement(param), param.kind, param.ordinal) struct.packed = pack.PackedStruct(struct) struct.bytes = pack.GetByteLayout(struct.packed) struct.versions = pack.GetVersionInfo(struct.packed) return struct
def testGetVersionInfoEmptyStruct(self): """Tests that pack.GetVersionInfo() never returns an empty list, even for empty structs. """ struct = mojom.Struct('test') ps = pack.PackedStruct(struct) versions = pack.GetVersionInfo(ps) self.assertEquals(1, len(versions)) self.assertEquals(0, versions[0].version) self.assertEquals(0, versions[0].num_fields) self.assertEquals(8, versions[0].num_bytes)
def testNullableTypes(self): kinds = (mojom.STRING.MakeNullableKind(), mojom.HANDLE.MakeNullableKind(), mojom.Struct('test_struct').MakeNullableKind(), mojom.DCPIPE.MakeNullableKind(), mojom.Array().MakeNullableKind(), mojom.DPPIPE.MakeNullableKind(), mojom.Array(length=5).MakeNullableKind(), mojom.MSGPIPE.MakeNullableKind(), mojom.Interface('test_interface').MakeNullableKind(), mojom.SHAREDBUFFER.MakeNullableKind(), mojom.InterfaceRequest().MakeNullableKind()) fields = (1, 2, 4, 3, 5, 6, 8, 7, 9, 10, 11) offsets = (0, 8, 12, 16, 24, 32, 36, 40, 48, 56, 60) return self._CheckPackSequence(kinds, fields, offsets)
def testPaddingPackedOutOfOrderByOrdinal(self): struct = mojom.Struct('test') struct.AddField('testfield1', mojom.INT8) struct.AddField('testfield3', mojom.UINT8, 3) struct.AddField('testfield2', mojom.INT32, 2) ps = pack.PackedStruct(struct) self.assertEqual(3, len(ps.packed_fields)) # Second byte should be packed in behind first, altering order. self.assertEqual('testfield1', ps.packed_fields[0].field.mojom_name) self.assertEqual('testfield3', ps.packed_fields[1].field.mojom_name) self.assertEqual('testfield2', ps.packed_fields[2].field.mojom_name) # Second byte should be packed with first. self.assertEqual(0, ps.packed_fields[0].offset) self.assertEqual(1, ps.packed_fields[1].offset) self.assertEqual(4, ps.packed_fields[2].offset)
def _Struct(module, parsed_struct): """ Args: module: {mojom.Module} Module currently being constructed. parsed_struct: {ast.Struct} Parsed struct. Returns: {mojom.Struct} AST struct. """ struct = mojom.Struct(module=module) struct.mojom_name = parsed_struct.mojom_name struct.native_only = parsed_struct.body is None struct.spec = 'x:' + module.mojom_namespace + '.' + struct.mojom_name module.kinds[struct.spec] = struct if struct.native_only: struct.enums = [] struct.constants = [] struct.fields_data = [] else: struct.enums = list( map( lambda enum: _Enum(module, enum, struct), _ElemsOfType(parsed_struct.body, ast.Enum, parsed_struct.mojom_name))) struct.constants = list( map( lambda constant: _Constant(module, constant, struct), _ElemsOfType(parsed_struct.body, ast.Const, parsed_struct.mojom_name))) # Stash fields parsed_struct here temporarily. struct.fields_data = _ElemsOfType(parsed_struct.body, ast.StructField, parsed_struct.mojom_name) struct.attributes = _AttributeListToDict(parsed_struct.attribute_list) # Enforce that a [Native] attribute is set to make native-only struct # declarations more explicit. if struct.native_only: if not struct.attributes or not struct.attributes.get('Native', False): raise Exception("Native-only struct declarations must include a " + "Native attribute.") if struct.attributes and struct.attributes.get('CustomSerializer', False): struct.custom_serializer = True return struct
def testImportFromDataNoMissingImports(self): """Tests that unions, structs, interfaces and enums are imported.""" module = mojom.Module('test_module', 'test_namespace') imported_module = mojom.Module('import_module', 'import_namespace') #TODO(azani): Init values in module.py. #TODO(azani): Test that values are imported. imported_module.values = {} imported_data = {'module' : imported_module} struct = mojom.Struct('TestStruct', module=module) imported_module.kinds[struct.spec] = struct union = mojom.Union('TestUnion', module=module) imported_module.kinds[union.spec] = union interface = mojom.Interface('TestInterface', module=module) imported_module.kinds[interface.spec] = interface enum = mojom.Enum('TestEnum', module=module) imported_module.kinds[enum.spec] = enum data.ImportFromData(module, imported_data) # Test that the kind was imported. self.assertIn(struct.spec, module.kinds) self.assertEquals(struct.name, module.kinds[struct.spec].name) self.assertIn(union.spec, module.kinds) self.assertEquals(union.name, module.kinds[union.spec].name) self.assertIn(interface.spec, module.kinds) self.assertEquals(interface.name, module.kinds[interface.spec].name) self.assertIn(enum.spec, module.kinds) self.assertEquals(enum.name, module.kinds[enum.spec].name) # Test that the imported kind is a copy and not the original. self.assertIsNot(struct, module.kinds[struct.spec]) self.assertIsNot(union, module.kinds[union.spec]) self.assertIsNot(interface, module.kinds[interface.spec]) self.assertIsNot(enum, module.kinds[enum.spec])
def _Struct(module, parsed_struct): """ Args: module: {mojom.Module} Module currently being constructed. parsed_struct: {ast.Struct} Parsed struct. Returns: {mojom.Struct} AST struct. """ struct = mojom.Struct(module=module) struct.mojom_name = parsed_struct.mojom_name struct.native_only = parsed_struct.body is None struct.spec = 'x:' + module.GetNamespacePrefix() + struct.mojom_name module.kinds[struct.spec] = struct struct.enums = [] struct.constants = [] struct.fields_data = [] if not struct.native_only: _ProcessElements( parsed_struct.mojom_name, parsed_struct.body, { ast.Enum: lambda enum: struct.enums.append(_Enum(module, enum, struct)), ast.Const: lambda const: struct.constants.append( _Constant(module, const, struct)), ast.StructField: struct.fields_data.append, }) struct.attributes = _AttributeListToDict(parsed_struct.attribute_list) # Enforce that a [Native] attribute is set to make native-only struct # declarations more explicit. if struct.native_only: if not struct.attributes or not struct.attributes.get('Native', False): raise Exception("Native-only struct declarations must include a " + "Native attribute.") if struct.attributes and struct.attributes.get('CustomSerializer', False): struct.custom_serializer = True return struct
def _CheckPackSequence(self, kinds, fields, offsets): """Checks the pack order and offsets of a sequence of mojom.Kinds. Args: kinds: A sequence of mojom.Kinds that specify the fields that are to be created. fields: The expected order of the resulting fields, with the integer "1" first. offsets: The expected order of offsets, with the integer "0" first. """ struct = mojom.Struct('test') index = 1 for kind in kinds: struct.AddField('%d' % index, kind) index += 1 ps = pack.PackedStruct(struct) num_fields = len(ps.packed_fields) self.assertEquals(len(kinds), num_fields) for i in xrange(num_fields): self.assertEquals('%d' % fields[i], ps.packed_fields[i].field.name) self.assertEquals(offsets[i], ps.packed_fields[i].offset)
def testMinVersion(self): """Tests that |min_version| is properly set for packed fields.""" struct = mojom.Struct('test') struct.AddField('field_2', mojom.BOOL, 2) struct.AddField('field_0', mojom.INT32, 0) struct.AddField('field_1', mojom.INT64, 1) ps = pack.PackedStruct(struct) self.assertEquals('field_0', ps.packed_fields[0].field.name) self.assertEquals('field_2', ps.packed_fields[1].field.name) self.assertEquals('field_1', ps.packed_fields[2].field.name) self.assertEquals(0, ps.packed_fields[0].min_version) self.assertEquals(0, ps.packed_fields[1].min_version) self.assertEquals(0, ps.packed_fields[2].min_version) struct.fields[0].attributes = {'MinVersion': 1} ps = pack.PackedStruct(struct) self.assertEquals(0, ps.packed_fields[0].min_version) self.assertEquals(1, ps.packed_fields[1].min_version) self.assertEquals(0, ps.packed_fields[2].min_version)
def testZeroFields(self): struct = mojom.Struct('test') ps = pack.PackedStruct(struct) self.assertEqual(0, len(ps.packed_fields))
def testOneField(self): struct = mojom.Struct('test') struct.AddField('testfield1', mojom.INT8) ps = pack.PackedStruct(struct) self.assertEqual(1, len(ps.packed_fields))