config_parse.py: replace `'...'.format()` with f-strings
[deliverable/barectf.git] / barectf / metadata.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 import enum
25 import collections
26 import barectf
27 import datetime
28
29
30 @enum.unique
31 class ByteOrder(enum.Enum):
32 LE = 0
33 BE = 1
34
35
36 @enum.unique
37 class Encoding(enum.Enum):
38 NONE = 0
39 UTF8 = 1
40 ASCII = 2
41
42
43 class Type:
44 @property
45 def align(self):
46 return None
47
48 @property
49 def size(self):
50 pass
51
52 @property
53 def is_dynamic(self):
54 return False
55
56
57 class PropertyMapping:
58 def __init__(self, object, prop):
59 self._object = object
60 self._prop = prop
61
62 @property
63 def object(self):
64 return self._object
65
66 @property
67 def prop(self):
68 return self.prop
69
70
71 class Integer(Type):
72 def __init__(self, size, byte_order, align=None, signed=False,
73 base=10, encoding=Encoding.NONE, property_mappings=None):
74 self._size = size
75 self._byte_order = byte_order
76
77 if align is None:
78 if size % 8 == 0:
79 self._align = 8
80 else:
81 self._align = 1
82 else:
83 self._align = align
84
85 self._signed = signed
86 self._base = base
87 self._encoding = encoding
88
89 if property_mappings is None:
90 self._property_mappings = []
91 else:
92 self._property_mappings = property_mappings
93
94 @property
95 def signed(self):
96 return self._signed
97
98 @property
99 def byte_order(self):
100 return self._byte_order
101
102 @property
103 def base(self):
104 return self._base
105
106 @property
107 def encoding(self):
108 return self._encoding
109
110 @property
111 def align(self):
112 return self._align
113
114 @property
115 def size(self):
116 return self._size
117
118 @property
119 def property_mappings(self):
120 return self._property_mappings
121
122
123 class FloatingPoint(Type):
124 def __init__(self, exp_size, mant_size, byte_order, align=8):
125 self._exp_size = exp_size
126 self._mant_size = mant_size
127 self._byte_order = byte_order
128 self._align = align
129
130 @property
131 def exp_size(self):
132 return self._exp_size
133
134 @property
135 def mant_size(self):
136 return self._mant_size
137
138 @property
139 def size(self):
140 return self._exp_size + self._mant_size
141
142 @property
143 def byte_order(self):
144 return self._byte_order
145
146 @property
147 def align(self):
148 return self._align
149
150
151 class Enum(Type):
152 def __init__(self, value_type, members=None):
153 self._value_type = value_type
154
155 if members is None:
156 self._members = collections.OrderedDict()
157 else:
158 self._members = members
159
160 @property
161 def align(self):
162 return self._value_type.align
163
164 @property
165 def size(self):
166 return self._value_type.size
167
168 @property
169 def value_type(self):
170 return self._value_type
171
172 @property
173 def members(self):
174 return self._members
175
176 @property
177 def last_value(self):
178 if len(self._members) == 0:
179 return
180
181 return list(self._members.values())[-1][1]
182
183 def value_of(self, label):
184 return self._members[label]
185
186 def label_of(self, value):
187 for label, vrange in self._members.items():
188 if value >= vrange[0] and value <= vrange[1]:
189 return label
190
191 def __getitem__(self, key):
192 if type(key) is str:
193 return self.value_of(key)
194 elif type(key) is int:
195 return self.label_of(key)
196
197 raise TypeError('Wrong subscript type')
198
199
200 class String(Type):
201 def __init__(self, encoding=Encoding.UTF8):
202 self._encoding = encoding.UTF8
203
204 @property
205 def align(self):
206 return 8
207
208 @property
209 def encoding(self):
210 return self._encoding
211
212 @property
213 def is_dynamic(self):
214 return True
215
216
217 class Array(Type):
218 def __init__(self, element_type, length):
219 self._element_type = element_type
220 self._length = length
221
222 @property
223 def align(self):
224 return self._element_type.align
225
226 @property
227 def element_type(self):
228 return self._element_type
229
230 @property
231 def length(self):
232 return self._length
233
234
235 class Struct(Type):
236 def __init__(self, min_align=1, fields=None):
237 self._min_align = min_align
238
239 if fields is None:
240 self._fields = collections.OrderedDict()
241 else:
242 self._fields = fields
243
244 self._align = self.min_align
245
246 for field in self.fields.values():
247 if field.align is None:
248 continue
249
250 if field.align > self._align:
251 self._align = field.align
252
253 @property
254 def min_align(self):
255 return self._min_align
256
257 @property
258 def align(self):
259 return self._align
260
261 @property
262 def fields(self):
263 return self._fields
264
265 def __getitem__(self, key):
266 return self.fields[key]
267
268 def __len__(self):
269 return len(self._fields)
270
271
272 class Trace:
273 def __init__(self, byte_order, uuid=None, packet_header_type=None):
274 self._byte_order = byte_order
275 self._uuid = uuid
276 self._packet_header_type = packet_header_type
277
278 @property
279 def uuid(self):
280 return self._uuid
281
282 @property
283 def byte_order(self):
284 return self._byte_order
285
286 @property
287 def packet_header_type(self):
288 return self._packet_header_type
289
290
291 class Clock:
292 def __init__(self, name, uuid=None, description=None, freq=int(1e9),
293 error_cycles=0, offset_seconds=0, offset_cycles=0,
294 absolute=False, return_ctype='uint32_t'):
295 self._name = name
296 self._uuid = uuid
297 self._description = description
298 self._freq = freq
299 self._error_cycles = error_cycles
300 self._offset_seconds = offset_seconds
301 self._offset_cycles = offset_cycles
302 self._absolute = absolute
303 self._return_ctype = return_ctype
304
305 @property
306 def name(self):
307 return self._name
308
309 @property
310 def uuid(self):
311 return self._uuid
312
313 @property
314 def description(self):
315 return self._description
316
317 @property
318 def error_cycles(self):
319 return self._error_cycles
320
321 @property
322 def freq(self):
323 return self._freq
324
325 @property
326 def offset_seconds(self):
327 return self._offset_seconds
328
329 @property
330 def offset_cycles(self):
331 return self._offset_cycles
332
333 @property
334 def absolute(self):
335 return self._absolute
336
337 @property
338 def return_ctype(self):
339 return self._return_ctype
340
341
342 LogLevel = collections.namedtuple('LogLevel', ['name', 'value'])
343
344
345 class Event:
346 def __init__(self, id, name, log_level=None, payload_type=None,
347 context_type=None):
348 self._id = id
349 self._name = name
350 self._payload_type = payload_type
351 self._log_level = log_level
352 self._context_type = context_type
353
354 @property
355 def id(self):
356 return self._id
357
358 @property
359 def name(self):
360 return self._name
361
362 @property
363 def log_level(self):
364 return self._log_level
365
366 @property
367 def context_type(self):
368 return self._context_type
369
370 @property
371 def payload_type(self):
372 return self._payload_type
373
374 def __getitem__(self, key):
375 if self.payload_type is None:
376 raise KeyError(key)
377
378 return self.payload_type[key]
379
380
381 class Stream:
382 def __init__(self, id, name=None, packet_context_type=None,
383 event_header_type=None, event_context_type=None,
384 events=None):
385 self._id = id
386 self._name = name
387 self._packet_context_type = packet_context_type
388 self._event_header_type = event_header_type
389 self._event_context_type = event_context_type
390
391 if events is None:
392 self._events = collections.OrderedDict()
393 else:
394 self._events = events
395
396 @property
397 def name(self):
398 return self._name
399
400 @property
401 def id(self):
402 return self._id
403
404 @property
405 def packet_context_type(self):
406 return self._packet_context_type
407
408 @property
409 def event_header_type(self):
410 return self._event_header_type
411
412 @property
413 def event_context_type(self):
414 return self._event_context_type
415
416 @property
417 def events(self):
418 return self._events
419
420
421 class Metadata:
422 def __init__(self, trace, env=None, clocks=None, streams=None,
423 default_stream_name=None):
424 self._trace = trace
425 version_tuple = barectf.get_version_tuple()
426 self._env = collections.OrderedDict([
427 ('domain', 'bare'),
428 ('tracer_name', 'barectf'),
429 ('tracer_major', version_tuple[0]),
430 ('tracer_minor', version_tuple[1]),
431 ('tracer_patch', version_tuple[2]),
432 ('barectf_gen_date', str(datetime.datetime.now().isoformat())),
433 ])
434
435 if env is not None:
436 self._env.update(env)
437
438 if clocks is None:
439 self._clocks = collections.OrderedDict()
440 else:
441 self._clocks = clocks
442
443 if streams is None:
444 self._streams = collections.OrderedDict()
445 else:
446 self._streams = streams
447
448 self._default_stream_name = default_stream_name
449
450 @property
451 def trace(self):
452 return self._trace
453
454 @property
455 def env(self):
456 return self._env
457
458 @property
459 def clocks(self):
460 return self._clocks
461
462 @property
463 def streams(self):
464 return self._streams
465
466 @property
467 def default_stream_name(self):
468 return self._default_stream_name
469
470 @property
471 def default_stream(self):
472 if self._default_stream_name in self._streams:
473 return self._streams[self._default_stream_name]
This page took 0.03854 seconds and 4 git commands to generate.