1 # The MIT License (MIT)
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
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:
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
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.
24 import barectf
.version
as barectf_version
25 from typing
import Optional
, Any
, FrozenSet
, Mapping
, Iterator
, Set
, Union
27 from barectf
.typing
import Count
, Alignment
, _OptStr
, Id
28 import collections
.abc
36 class ByteOrder(enum
.Enum
):
43 def alignment(self
) -> Alignment
:
44 raise NotImplementedError
47 def size_is_dynamic(self
):
51 class _BitArrayFieldType(_FieldType
):
52 def __init__(self
, size
: Count
, byte_order
: Optional
[ByteOrder
] = None,
53 alignment
: Alignment
= Alignment(1)):
55 self
._byte
_order
= byte_order
56 self
._alignment
= alignment
59 def size(self
) -> Count
:
63 def byte_order(self
) -> Optional
[ByteOrder
]:
64 return self
._byte
_order
67 def alignment(self
) -> Alignment
:
68 return self
._alignment
71 class DisplayBase(enum
.Enum
):
78 class _IntegerFieldType(_BitArrayFieldType
):
79 def __init__(self
, size
: Count
, byte_order
: Optional
[ByteOrder
] = None,
80 alignment
: Optional
[Alignment
] = None,
81 preferred_display_base
: DisplayBase
= DisplayBase
.DECIMAL
):
83 alignment
= Alignment(8 if size
% 8 == 0 else 1)
85 super().__init
__(size
, byte_order
, alignment
)
86 self
._preferred
_display
_base
= preferred_display_base
89 def preferred_display_base(self
) -> DisplayBase
:
90 return self
._preferred
_display
_base
93 class UnsignedIntegerFieldType(_IntegerFieldType
):
94 def __init__(self
, *args
):
95 super().__init
__(*args
)
96 self
._mapped
_clk
_type
_name
= None
99 class SignedIntegerFieldType(_IntegerFieldType
):
103 class EnumerationFieldTypeMappingRange
:
104 def __init__(self
, lower
: int, upper
: int):
109 def lower(self
) -> int:
113 def upper(self
) -> int:
116 def __eq__(self
, other
: Any
) -> bool:
117 if type(other
) is not type(self
):
120 return (self
._lower
, self
._upper
) == (other
._lower
, other
._upper
)
122 def __hash__(self
) -> int:
123 return hash((self
._lower
, self
._upper
))
125 def contains(self
, value
: int) -> bool:
126 return self
._lower
<= value
<= self
._upper
129 class EnumerationFieldTypeMapping
:
130 def __init__(self
, ranges
: Set
[EnumerationFieldTypeMappingRange
]):
131 self
._ranges
= frozenset(ranges
)
134 def ranges(self
) -> FrozenSet
[EnumerationFieldTypeMappingRange
]:
137 def ranges_contain_value(self
, value
: int) -> bool:
138 return any([rg
.contains(value
) for rg
in self
._ranges
])
141 _EnumFtMappings
= Mapping
[str, EnumerationFieldTypeMapping
]
144 class EnumerationFieldTypeMappings(collections
.abc
.Mapping
):
145 def __init__(self
, mappings
: _EnumFtMappings
):
146 self
._mappings
= {label
: mapping
for label
, mapping
in mappings
.items()}
148 def __getitem__(self
, key
: str) -> EnumerationFieldTypeMapping
:
149 return self
._mappings
[key
]
151 def __iter__(self
) -> Iterator
[str]:
152 return iter(self
._mappings
)
154 def __len__(self
) -> int:
155 return len(self
._mappings
)
158 class _EnumerationFieldType(_IntegerFieldType
):
159 def __init__(self
, size
: Count
, byte_order
: Optional
[ByteOrder
] = None,
160 alignment
: Optional
[Alignment
] = None,
161 preferred_display_base
: DisplayBase
= DisplayBase
.DECIMAL
,
162 mappings
: Optional
[_EnumFtMappings
] = None):
163 super().__init
__(size
, byte_order
, alignment
, preferred_display_base
)
164 self
._mappings
= EnumerationFieldTypeMappings({})
166 if mappings
is not None:
167 self
._mappings
= EnumerationFieldTypeMappings(mappings
)
170 def mappings(self
) -> EnumerationFieldTypeMappings
:
171 return self
._mappings
173 def labels_for_value(self
, value
: int) -> Set
[str]:
176 for label
, mapping
in self
._mappings
.items():
177 if mapping
.ranges_contain_value(value
):
183 class UnsignedEnumerationFieldType(_EnumerationFieldType
, UnsignedIntegerFieldType
):
187 class SignedEnumerationFieldType(_EnumerationFieldType
, SignedIntegerFieldType
):
191 class RealFieldType(_BitArrayFieldType
):
195 class StringFieldType(_FieldType
):
197 def alignment(self
) -> Alignment
:
201 def size_is_dynamic(self
):
205 class _ArrayFieldType(_FieldType
):
206 def __init__(self
, element_field_type
: _FieldType
):
207 self
._element
_field
_type
= element_field_type
210 def element_field_type(self
) -> _FieldType
:
211 return self
._element
_field
_type
214 def alignment(self
) -> Alignment
:
215 return self
._element
_field
_type
.alignment
218 class StaticArrayFieldType(_ArrayFieldType
):
219 def __init__(self
, length
: Count
, element_field_type
: _FieldType
):
220 super().__init
__(element_field_type
)
221 self
._length
= length
224 def length(self
) -> Count
:
228 class StructureFieldTypeMember
:
229 def __init__(self
, field_type
: _FieldType
):
230 self
._field
_type
= field_type
233 def field_type(self
) -> _FieldType
:
234 return self
._field
_type
237 _StructFtMembers
= Mapping
[str, StructureFieldTypeMember
]
240 class StructureFieldTypeMembers(collections
.abc
.Mapping
):
241 def __init__(self
, members
: _StructFtMembers
):
242 self
._members
= collections
.OrderedDict()
244 for name
, member
in members
.items():
245 assert type(member
) is StructureFieldTypeMember
246 self
._members
[name
] = member
248 def __getitem__(self
, key
: str) -> StructureFieldTypeMember
:
249 return self
._members
[key
]
251 def __iter__(self
) -> Iterator
[str]:
252 return iter(self
._members
)
254 def __len__(self
) -> int:
255 return len(self
._members
)
258 class StructureFieldType(_FieldType
):
259 def __init__(self
, minimum_alignment
: Alignment
= Alignment(1),
260 members
: Optional
[_StructFtMembers
] = None):
261 self
._minimum
_alignment
= minimum_alignment
262 self
._members
= StructureFieldTypeMembers({})
264 if members
is not None:
265 self
._members
= StructureFieldTypeMembers(members
)
267 self
._set
_alignment
()
269 def _set_alignment(self
):
270 self
._alignment
: Alignment
= self
._minimum
_alignment
272 for member
in self
._members
.values():
273 if member
.field_type
.alignment
> self
._alignment
:
274 self
._alignment
= member
.field_type
.alignment
277 def minimum_alignment(self
) -> Alignment
:
278 return self
._minimum
_alignment
281 def alignment(self
) -> Alignment
:
282 return self
._alignment
285 def size_is_dynamic(self
):
286 return any([member
.field_type
.size_is_dynamic
for member
in self
.members
.values()])
289 def members(self
) -> StructureFieldTypeMembers
:
296 def __eq__(self
, other
: Any
) -> bool:
297 if type(other
) is not type(self
):
300 return self
._name
== other
._name
302 def __lt__(self
, other
: '_UniqueByName'):
303 assert type(self
) is type(other
)
304 return self
._name
< other
._name
306 def __hash__(self
) -> int:
307 return hash(self
._name
)
310 _OptFt
= Optional
[_FieldType
]
311 _OptStructFt
= Optional
[StructureFieldType
]
312 LogLevel
= typing
.NewType('LogLevel', int)
315 class EventType(_UniqueByName
):
316 def __init__(self
, name
: str, log_level
: Optional
[LogLevel
] = None,
317 specific_context_field_type
: _OptStructFt
= None, payload_field_type
: _OptStructFt
= None):
318 self
._id
: Optional
[Id
] = None
320 self
._log
_level
= log_level
321 self
._specific
_context
_field
_type
= specific_context_field_type
322 self
._payload
_field
_type
= payload_field_type
325 def id(self
) -> Optional
[Id
]:
329 def name(self
) -> str:
333 def log_level(self
) -> Optional
[LogLevel
]:
334 return self
._log
_level
337 def specific_context_field_type(self
) -> _OptStructFt
:
338 return self
._specific
_context
_field
_type
341 def payload_field_type(self
) -> _OptStructFt
:
342 return self
._payload
_field
_type
345 class ClockTypeOffset
:
346 def __init__(self
, seconds
: int = 0, cycles
: Count
= Count(0)):
347 self
._seconds
= seconds
348 self
._cycles
= cycles
351 def seconds(self
) -> int:
355 def cycles(self
) -> Count
:
359 _OptUuid
= Optional
[uuidp
.UUID
]
362 class ClockType(_UniqueByName
):
363 def __init__(self
, name
: str, frequency
: Count
= Count(int(1e9
)), uuid
: _OptUuid
= None,
364 description
: _OptStr
= None, precision
: Count
= Count(0),
365 offset
: Optional
[ClockTypeOffset
] = None, origin_is_unix_epoch
: bool = False):
367 self
._frequency
= frequency
369 self
._description
= description
370 self
._precision
= precision
371 self
._offset
= ClockTypeOffset()
373 if offset
is not None:
374 self
._offset
= offset
376 self
._origin
_is
_unix
_epoch
= origin_is_unix_epoch
379 def name(self
) -> str:
383 def frequency(self
) -> Count
:
384 return self
._frequency
387 def uuid(self
) -> _OptUuid
:
391 def description(self
) -> _OptStr
:
392 return self
._description
395 def precision(self
) -> Count
:
396 return self
._precision
399 def offset(self
) -> ClockTypeOffset
:
403 def origin_is_unix_epoch(self
) -> bool:
404 return self
._origin
_is
_unix
_epoch
407 DEFAULT_FIELD_TYPE
= 'default'
408 _DefaultableUIntFt
= Union
[str, UnsignedIntegerFieldType
]
409 _OptDefaultableUIntFt
= Optional
[_DefaultableUIntFt
]
410 _OptUIntFt
= Optional
[UnsignedIntegerFieldType
]
413 class StreamTypePacketFeatures
:
414 def __init__(self
, total_size_field_type
: _DefaultableUIntFt
= DEFAULT_FIELD_TYPE
,
415 content_size_field_type
: _DefaultableUIntFt
= DEFAULT_FIELD_TYPE
,
416 beginning_time_field_type
: _OptDefaultableUIntFt
= None,
417 end_time_field_type
: _OptDefaultableUIntFt
= None,
418 discarded_events_counter_field_type
: _OptDefaultableUIntFt
= None):
419 def get_ft(user_ft
: _OptDefaultableUIntFt
) -> _OptUIntFt
:
420 if user_ft
== DEFAULT_FIELD_TYPE
:
421 return UnsignedIntegerFieldType(64)
423 return typing
.cast(_OptUIntFt
, user_ft
)
425 self
._total
_size
_field
_type
= get_ft(total_size_field_type
)
426 self
._content
_size
_field
_type
= get_ft(content_size_field_type
)
427 self
._beginning
_time
_field
_type
= get_ft(beginning_time_field_type
)
428 self
._end
_time
_field
_type
= get_ft(end_time_field_type
)
429 self
._discarded
_events
_counter
_field
_type
= get_ft(discarded_events_counter_field_type
)
432 def total_size_field_type(self
) -> _OptUIntFt
:
433 return self
._total
_size
_field
_type
436 def content_size_field_type(self
) -> _OptUIntFt
:
437 return self
._content
_size
_field
_type
440 def beginning_time_field_type(self
) -> _OptUIntFt
:
441 return self
._beginning
_time
_field
_type
444 def end_time_field_type(self
) -> _OptUIntFt
:
445 return self
._end
_time
_field
_type
448 def discarded_events_counter_field_type(self
) -> _OptUIntFt
:
449 return self
._discarded
_events
_counter
_field
_type
452 class StreamTypeEventFeatures
:
453 def __init__(self
, type_id_field_type
: _OptDefaultableUIntFt
= DEFAULT_FIELD_TYPE
,
454 time_field_type
: _OptDefaultableUIntFt
= None):
455 def get_ft(user_ft
: _OptDefaultableUIntFt
) -> _OptUIntFt
:
456 if user_ft
== DEFAULT_FIELD_TYPE
:
457 return UnsignedIntegerFieldType(64)
459 return typing
.cast(_OptUIntFt
, user_ft
)
461 self
._type
_id
_field
_type
= get_ft(type_id_field_type
)
462 self
._time
_field
_type
= get_ft(time_field_type
)
465 def type_id_field_type(self
) -> _OptUIntFt
:
466 return self
._type
_id
_field
_type
469 def time_field_type(self
) -> _OptUIntFt
:
470 return self
._time
_field
_type
473 class StreamTypeFeatures
:
474 def __init__(self
, packet_features
: Optional
[StreamTypePacketFeatures
] = None,
475 event_features
: Optional
[StreamTypeEventFeatures
] = None):
476 self
._packet
_features
= StreamTypePacketFeatures()
478 if packet_features
is not None:
479 self
._packet
_features
= packet_features
481 self
._event
_features
= StreamTypeEventFeatures()
483 if event_features
is not None:
484 self
._event
_features
= event_features
487 def packet_features(self
) -> StreamTypePacketFeatures
:
488 return self
._packet
_features
491 def event_features(self
) -> StreamTypeEventFeatures
:
492 return self
._event
_features
495 class StreamType(_UniqueByName
):
496 def __init__(self
, name
: str, event_types
: Set
[EventType
],
497 default_clock_type
: Optional
[ClockType
] = None,
498 features
: Optional
[StreamTypeFeatures
] = None,
499 packet_context_field_type_extra_members
: Optional
[_StructFtMembers
] = None,
500 event_common_context_field_type
: _OptStructFt
= None):
501 self
._id
: Optional
[Id
] = None
503 self
._default
_clock
_type
= default_clock_type
504 self
._event
_common
_context
_field
_type
= event_common_context_field_type
505 self
._event
_types
= frozenset(event_types
)
508 for index
, ev_type
in enumerate(sorted(self
._event
_types
, key
=lambda evt
: evt
.name
)):
509 assert ev_type
._id
is None
510 ev_type
._id
= Id(index
)
512 self
._set
_features
(features
)
513 self
._packet
_context
_field
_type
_extra
_members
= StructureFieldTypeMembers({})
515 if packet_context_field_type_extra_members
is not None:
516 self
._packet
_context
_field
_type
_extra
_members
= StructureFieldTypeMembers(packet_context_field_type_extra_members
)
518 self
._set
_pkt
_ctx
_ft
()
519 self
._set
_ev
_header
_ft
()
521 def _set_features(self
, features
: Optional
[StreamTypeFeatures
]):
522 if features
is not None:
523 self
._features
= features
527 pkt_beginning_time_ft
= None
528 pkt_end_time_ft
= None
530 if self
._default
_clock
_type
is not None:
531 # Automatic time field types because the stream type has a
532 # default clock type.
533 ev_time_ft
= DEFAULT_FIELD_TYPE
534 pkt_beginning_time_ft
= DEFAULT_FIELD_TYPE
535 pkt_end_time_ft
= DEFAULT_FIELD_TYPE
537 self
._features
= StreamTypeFeatures(StreamTypePacketFeatures(beginning_time_field_type
=pkt_beginning_time_ft
,
538 end_time_field_type
=pkt_end_time_ft
),
539 StreamTypeEventFeatures(time_field_type
=ev_time_ft
))
541 def _set_ft_mapped_clk_type_name(self
, ft
: Optional
[UnsignedIntegerFieldType
]):
545 if self
._default
_clock
_type
is not None:
546 assert isinstance(ft
, UnsignedIntegerFieldType
)
547 ft
._mapped
_clk
_type
_name
= self
._default
_clock
_type
.name
549 def _set_pkt_ctx_ft(self
):
552 def add_member_if_exists(name
: str, ft
: _FieldType
, set_mapped_clk_type_name
: bool = False):
556 if set_mapped_clk_type_name
:
557 self
._set
_ft
_mapped
_clk
_type
_name
(typing
.cast(UnsignedIntegerFieldType
, ft
))
559 members
[name
] = StructureFieldTypeMember(ft
)
561 members
= collections
.OrderedDict([
564 StructureFieldTypeMember(self
._features
.packet_features
.total_size_field_type
)
568 StructureFieldTypeMember(self
._features
.packet_features
.content_size_field_type
)
572 add_member_if_exists('timestamp_begin',
573 self
._features
.packet_features
.beginning_time_field_type
, True)
574 add_member_if_exists('timestamp_end', self
._features
.packet_features
.end_time_field_type
,
576 add_member_if_exists('events_discarded',
577 self
._features
.packet_features
.discarded_events_counter_field_type
)
579 if self
._packet
_context
_field
_type
_extra
_members
is not None:
580 for name
, field_type
in self
._packet
_context
_field
_type
_extra
_members
.items():
581 assert name
not in members
582 members
[name
] = field_type
584 self
._pkt
_ctx
_ft
= StructureFieldType(8, members
)
586 def _set_ev_header_ft(self
):
587 members
= collections
.OrderedDict()
589 if self
._features
.event_features
.type_id_field_type
is not None:
590 members
['id'] = StructureFieldTypeMember(self
._features
.event_features
.type_id_field_type
)
592 if self
._features
.event_features
.time_field_type
is not None:
593 ft
= self
._features
.event_features
.time_field_type
594 self
._set
_ft
_mapped
_clk
_type
_name
(ft
)
595 members
['timestamp'] = StructureFieldTypeMember(ft
)
597 self
._ev
_header
_ft
= StructureFieldType(8, members
)
600 def id(self
) -> Optional
[Id
]:
604 def name(self
) -> str:
608 def default_clock_type(self
) -> Optional
[ClockType
]:
609 return self
._default
_clock
_type
612 def features(self
) -> StreamTypeFeatures
:
613 return self
._features
616 def packet_context_field_type_extra_members(self
) -> StructureFieldTypeMembers
:
617 return self
._packet
_context
_field
_type
_extra
_members
620 def event_common_context_field_type(self
) -> _OptStructFt
:
621 return self
._event
_common
_context
_field
_type
624 def event_types(self
) -> FrozenSet
[EventType
]:
625 return self
._event
_types
628 _OptUuidFt
= Optional
[Union
[str, StaticArrayFieldType
]]
631 class TraceTypeFeatures
:
632 def __init__(self
, magic_field_type
: _OptDefaultableUIntFt
= DEFAULT_FIELD_TYPE
,
633 uuid_field_type
: _OptUuidFt
= None,
634 stream_type_id_field_type
: _OptDefaultableUIntFt
= DEFAULT_FIELD_TYPE
):
635 def get_field_type(user_ft
: Optional
[Union
[str, _FieldType
]], default_ft
: _FieldType
) -> _OptFt
:
636 if user_ft
== DEFAULT_FIELD_TYPE
:
639 return typing
.cast(_OptFt
, user_ft
)
641 self
._magic
_field
_type
= typing
.cast(_OptUIntFt
, get_field_type(magic_field_type
,
642 UnsignedIntegerFieldType(32)))
643 self
._uuid
_field
_type
= typing
.cast(Optional
[StaticArrayFieldType
], get_field_type(uuid_field_type
,
644 StaticArrayFieldType(Count(16),
645 UnsignedIntegerFieldType(8))))
646 self
._stream
_type
_id
_field
_type
= typing
.cast(_OptUIntFt
, get_field_type(stream_type_id_field_type
,
647 UnsignedIntegerFieldType(64)))
650 def magic_field_type(self
) -> _OptUIntFt
:
651 return self
._magic
_field
_type
654 def uuid_field_type(self
) -> Optional
[StaticArrayFieldType
]:
655 return self
._uuid
_field
_type
658 def stream_type_id_field_type(self
) -> _OptUIntFt
:
659 return self
._stream
_type
_id
_field
_type
663 def __init__(self
, stream_types
: Set
[StreamType
], default_byte_order
: ByteOrder
,
664 uuid
: _OptUuid
= None, features
: Optional
[TraceTypeFeatures
] = None):
665 self
._default
_byte
_order
= default_byte_order
666 self
._stream
_types
= frozenset(stream_types
)
669 for index
, stream_type
in enumerate(sorted(self
._stream
_types
, key
=lambda st
: st
.name
)):
670 assert stream_type
._id
is None
671 stream_type
._id
= Id(index
)
674 self
._set
_features
(features
)
675 self
._set
_pkt
_header
_ft
()
676 self
._set
_fts
_effective
_byte
_order
()
678 def _set_features(self
, features
: Optional
[TraceTypeFeatures
]):
679 if features
is not None:
680 self
._features
= features
683 # automatic UUID field type because the trace type has a UUID
684 uuid_ft
= None if self
._uuid
is None else DEFAULT_FIELD_TYPE
685 self
._features
= TraceTypeFeatures(uuid_field_type
=uuid_ft
)
687 def _set_pkt_header_ft(self
):
688 members
= collections
.OrderedDict()
690 def add_member_if_exists(name
: str, ft
: _OptFt
):
694 members
[name
] = StructureFieldTypeMember(ft
)
696 add_member_if_exists('magic', self
._features
.magic_field_type
)
697 add_member_if_exists('uuid', self
._features
.uuid_field_type
)
698 add_member_if_exists('stream_id', self
._features
.stream_type_id_field_type
)
699 self
._pkt
_header
_ft
= StructureFieldType(8, members
)
701 def _set_fts_effective_byte_order(self
):
702 def set_ft_effective_byte_order(ft
: _OptFt
):
706 if isinstance(ft
, _BitArrayFieldType
):
707 if ft
._byte
_order
is None:
708 assert self
._default
_byte
_order
is not None
709 ft
._byte
_order
= self
._default
_byte
_order
710 elif isinstance(ft
, StaticArrayFieldType
):
711 set_ft_effective_byte_order(ft
.element_field_type
)
712 elif isinstance(ft
, StructureFieldType
):
713 for member
in ft
.members
.values():
714 set_ft_effective_byte_order(member
.field_type
)
716 # packet header field type
717 set_ft_effective_byte_order(self
._pkt
_header
_ft
)
719 # stream type field types
720 for stream_type
in self
._stream
_types
:
721 set_ft_effective_byte_order(stream_type
._pkt
_ctx
_ft
)
722 set_ft_effective_byte_order(stream_type
._ev
_header
_ft
)
723 set_ft_effective_byte_order(stream_type
._event
_common
_context
_field
_type
)
725 # event type field types
726 for ev_type
in stream_type
.event_types
:
727 set_ft_effective_byte_order(ev_type
._specific
_context
_field
_type
)
728 set_ft_effective_byte_order(ev_type
._payload
_field
_type
)
731 def default_byte_order(self
) -> ByteOrder
:
732 return self
._default
_byte
_order
735 def uuid(self
) -> _OptUuid
:
739 def stream_types(self
) -> FrozenSet
[StreamType
]:
740 return self
._stream
_types
742 def stream_type(self
, name
: str) -> Optional
[StreamType
]:
743 for cand_stream_type
in self
._stream
_types
:
744 if cand_stream_type
.name
== name
:
745 return cand_stream_type
750 def features(self
) -> TraceTypeFeatures
:
751 return self
._features
754 def clock_types(self
) -> Set
[ClockType
]:
757 for stream_type
in self
._stream
_types
:
758 if stream_type
.default_clock_type
is not None:
759 clk_types
.add(stream_type
.default_clock_type
)
764 _EnvEntry
= Union
[str, int]
765 _EnvEntries
= Mapping
[str, _EnvEntry
]
768 class TraceEnvironment(collections
.abc
.Mapping
):
769 def __init__(self
, environment
: _EnvEntries
):
770 self
._env
= {name
: value
for name
, value
in environment
.items()}
772 def __getitem__(self
, key
: str) -> _EnvEntry
:
773 return self
._env
[key
]
775 def __iter__(self
) -> Iterator
[str]:
776 return iter(self
._env
)
778 def __len__(self
) -> int:
779 return len(self
._env
)
783 def __init__(self
, type: TraceType
, environment
: Optional
[_EnvEntries
] = None):
785 self
._set
_env
(environment
)
787 def _set_env(self
, environment
: Optional
[_EnvEntries
]):
788 init_env
= collections
.OrderedDict([
790 ('tracer_name', 'barectf'),
791 ('tracer_major', barectf_version
.__major
_version
__),
792 ('tracer_minor', barectf_version
.__minor
_version
__),
793 ('tracer_patch', barectf_version
.__patch
_version
__),
794 ('barectf_gen_date', str(datetime
.datetime
.now().isoformat())),
797 if environment
is None:
800 init_env
.update(environment
)
801 self
._env
= TraceEnvironment(typing
.cast(_EnvEntries
, init_env
))
804 def type(self
) -> TraceType
:
808 def environment(self
) -> TraceEnvironment
:
812 _ClkTypeCTypes
= Mapping
[ClockType
, str]
815 class ClockTypeCTypes(collections
.abc
.Mapping
):
816 def __init__(self
, c_types
: _ClkTypeCTypes
):
817 self
._c
_types
= {clk_type
: c_type
for clk_type
, c_type
in c_types
.items()}
819 def __getitem__(self
, key
: ClockType
) -> str:
820 return self
._c
_types
[key
]
822 def __iter__(self
) -> Iterator
[ClockType
]:
823 return iter(self
._c
_types
)
825 def __len__(self
) -> int:
826 return len(self
._c
_types
)
829 class ConfigurationCodeGenerationHeaderOptions
:
830 def __init__(self
, identifier_prefix_definition
: bool = False,
831 default_stream_type_name_definition
: bool = False):
832 self
._identifier
_prefix
_definition
= identifier_prefix_definition
833 self
._default
_stream
_type
_name
_definition
= default_stream_type_name_definition
836 def identifier_prefix_definition(self
) -> bool:
837 return self
._identifier
_prefix
_definition
840 def default_stream_type_name_definition(self
) -> bool:
841 return self
._default
_stream
_type
_name
_definition
844 class ConfigurationCodeGenerationOptions
:
845 def __init__(self
, identifier_prefix
: str = 'barectf_', file_name_prefix
: str = 'barectf',
846 default_stream_type
: Optional
[StreamType
] = None,
847 header_options
: Optional
[ConfigurationCodeGenerationHeaderOptions
] = None,
848 clock_type_c_types
: Optional
[_ClkTypeCTypes
] = None):
849 self
._identifier
_prefix
= identifier_prefix
850 self
._file
_name
_prefix
= file_name_prefix
851 self
._default
_stream
_type
= default_stream_type
853 self
._header
_options
= ConfigurationCodeGenerationHeaderOptions()
855 if header_options
is not None:
856 self
._header
_options
= header_options
858 self
._clock
_type
_c
_types
= ClockTypeCTypes({})
860 if clock_type_c_types
is not None:
861 self
._clock
_type
_c
_types
= ClockTypeCTypes(clock_type_c_types
)
864 def identifier_prefix(self
) -> str:
865 return self
._identifier
_prefix
868 def file_name_prefix(self
) -> str:
869 return self
._file
_name
_prefix
872 def default_stream_type(self
) -> Optional
[StreamType
]:
873 return self
._default
_stream
_type
876 def header_options(self
) -> ConfigurationCodeGenerationHeaderOptions
:
877 return self
._header
_options
880 def clock_type_c_types(self
) -> ClockTypeCTypes
:
881 return self
._clock
_type
_c
_types
884 class ConfigurationOptions
:
886 code_generation_options
: Optional
[ConfigurationCodeGenerationOptions
] = None):
887 self
._code
_generation
_options
= ConfigurationCodeGenerationOptions()
889 if code_generation_options
is not None:
890 self
._code
_generation
_options
= code_generation_options
893 def code_generation_options(self
) -> ConfigurationCodeGenerationOptions
:
894 return self
._code
_generation
_options
898 def __init__(self
, trace
: Trace
, options
: Optional
[ConfigurationOptions
] = None):
900 self
._options
= ConfigurationOptions()
902 if options
is not None:
903 self
._options
= options
905 clk_type_c_types
= self
._options
.code_generation_options
.clock_type_c_types
907 for stream_type
in trace
.type.stream_types
:
908 def_clk_type
= stream_type
.default_clock_type
910 if def_clk_type
is None:
913 if def_clk_type
not in clk_type_c_types
:
914 clk_type_c_types
._c
_types
[def_clk_type
] = 'uint32_t'
917 def trace(self
) -> Trace
:
921 def options(self
) -> ConfigurationOptions
: