• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 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
5import mojom
6
7# mojom_data provides a mechanism to turn mojom Modules to dictionaries and
8# back again. This can be used to persist a mojom Module created progromatically
9# or to read a dictionary from code or a file.
10# Example:
11# test_dict = {
12#   'name': 'test',
13#   'namespace': 'testspace',
14#   'structs': [{
15#     'name': 'teststruct',
16#     'fields': [
17#       {'name': 'testfield1', 'kind': 'i32'},
18#       {'name': 'testfield2', 'kind': 'a:i32', 'ordinal': 42}]}],
19#   'interfaces': [{
20#     'name': 'Server',
21#     'methods': [{
22#       'name': 'Foo',
23#       'parameters': [{
24#         'name': 'foo', 'kind': 'i32'},
25#         {'name': 'bar', 'kind': 'a:x:teststruct'}],
26#     'ordinal': 42}]}]
27# }
28# test_module = mojom_data.ModuleFromData(test_dict)
29
30
31# Used to create a subclass of str that supports sorting by index, to make
32# pretty printing maintain the order.
33def istr(index, string):
34  class IndexedString(str):
35    def __lt__(self, other):
36      return self.__index__ < other.__index__
37
38  istr = IndexedString(string)
39  istr.__index__ = index
40  return istr
41
42def KindToData(kind):
43  return kind.spec
44
45def KindFromData(kinds, data):
46  if kinds.has_key(data):
47    return kinds[data]
48  if data.startswith('a:'):
49    kind = mojom.Array()
50    kind.kind = KindFromData(kinds, data[2:])
51  else:
52    kind = mojom.Kind()
53  kind.spec = data
54  kinds[data] = kind
55  return kind
56
57def StructToData(struct):
58  return {
59    istr(0, 'name'): struct.name,
60    istr(1, 'fields'): map(FieldToData, struct.fields)
61  }
62
63def StructFromData(kinds, data):
64  struct = mojom.Struct()
65  struct.name = data['name']
66  struct.spec = 'x:' + struct.name
67  kinds[struct.spec] = struct
68  struct.fields = map(lambda field: FieldFromData(kinds, field), data['fields'])
69  return struct
70
71def FieldToData(field):
72  data = {
73    istr(0, 'name'): field.name,
74    istr(1, 'kind'): KindToData(field.kind)
75  }
76  if field.ordinal != None:
77    data[istr(2, 'ordinal')] = field.ordinal
78  if field.default != None:
79    data[istr(3, 'default')] = field.default
80  return data
81
82def FieldFromData(kinds, data):
83  field = mojom.Field()
84  field.name = data['name']
85  field.kind = KindFromData(kinds, data['kind'])
86  field.ordinal = data.get('ordinal')
87  field.default = data.get('default')
88  return field
89
90def ParameterToData(parameter):
91  data = {
92    istr(0, 'name'): parameter.name,
93    istr(1, 'kind'): parameter.kind.spec
94  }
95  if parameter.ordinal != None:
96    data[istr(2, 'ordinal')] = parameter.ordinal
97  if parameter.default != None:
98    data[istr(3, 'default')] = parameter.default
99  return data
100
101def ParameterFromData(kinds, data):
102  parameter = mojom.Parameter()
103  parameter.name = data['name']
104  parameter.kind = KindFromData(kinds, data['kind'])
105  parameter.ordinal = data.get('ordinal')
106  parameter.default = data.get('default')
107  return parameter
108
109def MethodToData(method):
110  data = {
111    istr(0, 'name'):       method.name,
112    istr(1, 'parameters'): map(ParameterToData, method.parameters)
113  }
114  if method.ordinal != None:
115    data[istr(2, 'ordinal')] = method.ordinal
116  return data
117
118def MethodFromData(kinds, data):
119  method = mojom.Method()
120  method.name = data['name']
121  method.ordinal = data.get('ordinal')
122  method.default = data.get('default')
123  method.parameters = map(
124    lambda parameter: ParameterFromData(kinds, parameter), data['parameters'])
125  return method
126
127def InterfaceToData(interface):
128  return {
129    istr(0, 'name'):    interface.name,
130    istr(1, 'peer'):    interface.peer,
131    istr(2, 'methods'): map(MethodToData, interface.methods)
132  }
133
134def InterfaceFromData(kinds, data):
135  interface = mojom.Interface()
136  interface.name = data['name']
137  interface.peer = data['peer']
138  interface.methods = map(
139    lambda method: MethodFromData(kinds, method), data['methods'])
140  return interface
141
142def EnumFieldFromData(kinds, data):
143  field = mojom.EnumField()
144  field.name = data['name']
145  field.value = data['value']
146  return field
147
148def EnumFromData(kinds, data):
149  enum = mojom.Enum()
150  enum.name = data['name']
151  enum.fields = map(
152    lambda field: EnumFieldFromData(kinds, field), data['fields'])
153  return enum
154
155def ModuleToData(module):
156  return {
157    istr(0, 'name'):       module.name,
158    istr(1, 'namespace'):  module.namespace,
159    istr(2, 'structs'):    map(StructToData, module.structs),
160    istr(3, 'interfaces'): map(InterfaceToData, module.interfaces)
161  }
162
163def ModuleFromData(data):
164  kinds = {}
165  for kind in mojom.PRIMITIVES:
166    kinds[kind.spec] = kind
167
168  module = mojom.Module()
169  module.name = data['name']
170  module.namespace = data['namespace']
171  module.structs = map(
172    lambda struct: StructFromData(kinds, struct), data['structs'])
173  module.interfaces = map(
174    lambda interface: InterfaceFromData(kinds, interface), data['interfaces'])
175  module.enums = map(
176    lambda enum: EnumFromData(kinds, enum), data['enums'])
177  return module
178
179def OrderedModuleFromData(data):
180  module = ModuleFromData(data)
181  next_interface_ordinal = 0
182  for interface in module.interfaces:
183    next_ordinal = 0
184    for method in interface.methods:
185      if method.ordinal is None:
186        method.ordinal = next_ordinal
187      next_ordinal = method.ordinal + 1
188  return module
189