3 # Babeltrace writer interface Python module
5 # Copyright 2012-2017 EfficiOS Inc.
7 # Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 # Permission is hereby granted, free of charge, to any person obtaining a copy
10 # of this software and associated documentation files (the "Software"), to deal
11 # in the Software without restriction, including without limitation the rights
12 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 # copies of the Software, and to permit persons to whom the Software is
14 # furnished to do so, subject to the following conditions:
16 # The above copyright notice and this permission notice shall be included in
17 # all copies or substantial portions of the Software.
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 import babeltrace
.common
as common
31 class EnumerationMapping
:
33 Mapping from an enumeration label to a range of integers.
36 def __init__(self
, name
, start
, end
):
38 Creates an enumeration mapping, where label *name* is mapped to
39 the [*start*, *end*] range of integers (*end* is included).
41 Set *start* and *end* to the same value to create an enumeration
42 mapping to a single value.
45 self
._enum
_mapping
= bt2
._EnumerationFieldTypeMapping(self
, start
, end
)
49 return self
._enum
_mapping
.name
53 return self
._enum
_mapping
.lower
57 return self
._enum
_mapping
.upper
62 A CTF clock allows the description of the system's clock topology, as
63 well as the definition of each clock's parameters.
65 :class:`Clock` objects must be registered to a :class:`Writer`
66 object (see :meth:`Writer.add_clock`), as well as be registered to
67 a :class:`StreamClass` object (see :attr:`StreamClass.clock`).
70 def __init__(self
, name
):
72 Creates a default CTF clock named *name*.
74 :exc:`ValueError` is raised on error.
78 self
._clock
= bt2
.CtfWriterClock(name
)
80 raise ValueError("Invalid clock name.")
88 Set this attribute to change the clock's name.
90 :exc:`ValueError` is raised on error.
94 return self
._clock
.name
96 raise ValueError("Invalid clock instance.")
99 def description(self
):
101 Clock description (string).
103 Set this attribute to change the clock's description.
105 :exc:`ValueError` is raised on error.
109 return self
._clock
.description
111 raise ValueError("Invalid clock instance.")
114 def description(self
, desc
):
116 self
._clock
.description
= desc
118 raise ValueError("Invalid clock description.")
123 Clock frequency in Hz (integer).
125 Set this attribute to change the clock's frequency.
127 :exc:`ValueError` is raised on error.
131 return self
._clock
.frequency
133 raise ValueError("Invalid clock instance.")
136 def frequency(self
, freq
):
138 self
._clock
.frequency
= freq
140 raise ValueError("Invalid frequency value.")
145 Clock precision in clock ticks (integer).
147 Set this attribute to change the clock's precision.
149 :exc:`ValueError` is raised on error.
153 return self
._clock
.precision
155 raise ValueError("Invalid clock instance.")
158 def precision(self
, precision
):
160 self
._clock
.precision
= precision
162 raise ValueError("Invalid precision value.")
165 def offset_seconds(self
):
167 Clock offset in seconds since POSIX.1 Epoch (integer).
169 Set this attribute to change the clock's offset in seconds.
171 :exc:`ValueError` is raised on error.
175 return self
._clock
.offset
.seconds
177 raise ValueError("Invalid clock instance.")
179 @offset_seconds.setter
180 def offset_seconds(self
, offset_s
):
182 self
._clock
.offset
= bt2
.ClockClassOffset(offset_s
,
183 self
._clock
.offset
.cycles
)
185 raise ValueError("Invalid offset value.")
190 Clock offset in ticks since (POSIX.1 Epoch +
191 :attr:`offset_seconds`).
193 Set this attribute to change the clock's offset.
195 :exc:`ValueError` is raised on error.
199 return self
._clock
.offset
.cycles
201 raise ValueError("Invalid clock instance.")
204 def offset(self
, offset
):
206 self
._clock
.offset
= bt2
.ClockClassOffset(self
._clock
.offset
.seconds
,
209 raise ValueError("Invalid offset value.")
214 ``True`` if this clock is absolute, i.e. if the clock is a
215 global reference across the other clocks of the trace.
217 Set this attribute to change the clock's absolute state
220 :exc:`ValueError` is raised on error.
224 return self
._clock
.is_absolute
226 raise ValueError("Invalid clock instance.")
229 def absolute(self
, is_absolute
):
231 self
._clock
.is_absolute
= is_absolute
233 raise ValueError("Could not set the clock absolute attribute.")
238 Clock UUID (an :class:`uuid.UUID` object).
240 Set this attribute to change the clock's UUID.
242 :exc:`ValueError` is raised on error.
246 return self
._clock
.uuid
248 raise ValueError("Invalid clock instance.")
251 def uuid(self
, uuid
):
252 uuid_bytes
= uuid
.bytes
254 if len(uuid_bytes
) != 16:
256 "Invalid UUID provided. UUID length must be 16 bytes")
259 self
._clock
.uuid
= uuid
261 raise ValueError("Invalid clock instance.")
266 Clock current time; nanoseconds (integer) since clock origin
267 (POSIX.1 Epoch + :attr:`offset_seconds` + :attr:`offset`).
269 Set this attribute to change the clock's current time.
271 :exc:`ValueError` is raised on error.
274 raise NotImplementedError("Getter not implemented.")
277 def time(self
, time
):
279 self
._clock
.time
= time
281 raise ValueError("Invalid time value.")
286 Display base of an integer.
304 # keep this for backward compatibility
305 INTEGER_BASE_UNKNOWN
= -1
306 INTEGER_BASE_BINARY
= 2
307 INTEGER_BASE_OCTAL
= 8
308 INTEGER_BASE_DECIMAL
= 10
309 INTEGER_BASE_HEXADECIMAL
= 16
312 _BT2_BYTE_ORDER_TO_BYTE_ORDER
= {
313 bt2
.ByteOrder
.NATIVE
: common
.ByteOrder
.BYTE_ORDER_NATIVE
,
314 bt2
.ByteOrder
.LITTLE_ENDIAN
: common
.ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
,
315 bt2
.ByteOrder
.BIG_ENDIAN
: common
.ByteOrder
.BYTE_ORDER_BIG_ENDIAN
,
316 bt2
.ByteOrder
.NETWORK
: common
.ByteOrder
.BYTE_ORDER_NETWORK
,
319 _BYTE_ORDER_TO_BT2_BYTE_ORDER
= {
320 common
.ByteOrder
.BYTE_ORDER_NATIVE
: bt2
.ByteOrder
.NATIVE
,
321 common
.ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
: bt2
.ByteOrder
.LITTLE_ENDIAN
,
322 common
.ByteOrder
.BYTE_ORDER_BIG_ENDIAN
: bt2
.ByteOrder
.BIG_ENDIAN
,
323 common
.ByteOrder
.BYTE_ORDER_NETWORK
: bt2
.ByteOrder
.NETWORK
,
326 _BT2_ENCODING_TO_ENCODING
= {
327 bt2
.Encoding
.NONE
: common
.CTFStringEncoding
.NONE
,
328 bt2
.Encoding
.ASCII
: common
.CTFStringEncoding
.ASCII
,
329 bt2
.Encoding
.UTF8
: common
.CTFStringEncoding
.UTF8
,
332 _ENCODING_TO_BT2_ENCODING
= {
333 common
.CTFStringEncoding
.NONE
: bt2
.Encoding
.NONE
,
334 common
.CTFStringEncoding
.ASCII
: bt2
.Encoding
.ASCII
,
335 common
.CTFStringEncoding
.UTF8
: bt2
.Encoding
.UTF8
,
339 class FieldDeclaration
:
341 Base class of all field declarations. This class is not meant to
342 be instantiated by the user; use one of the concrete field
343 declaration subclasses instead.
346 class IntegerBase(IntegerBase
):
350 if self
._field
_type
is None:
351 raise ValueError("FieldDeclaration creation failed.")
354 def _create_field_declaration(field_type
):
356 if type(field_type
) not in _BT2_FIELD_TYPE_TO_BT_DECLARATION
:
357 raise TypeError("Invalid field declaration instance.")
359 declaration
= Field
.__new
__(Field
)
360 declaration
._field
_type
= field_type
361 declaration
.__class
__ = _BT2_FIELD_TYPE_TO_BT_DECLARATION
[
368 Field alignment in bits (integer).
370 Set this attribute to change this field's alignment.
372 :exc:`ValueError` is raised on error.
376 return self
._field
_type
.alignment
379 "Could not get alignment field declaration attribute.")
382 def alignment(self
, alignment
):
384 self
._field
_type
.alignment
= alignment
386 raise ValueError("Invalid alignment value.")
389 def byte_order(self
):
391 Field byte order (one of :class:`babeltrace.common.ByteOrder`
394 Set this attribute to change this field's byte order.
396 :exc:`ValueError` is raised on error.
400 return _BT2_BYTE_ORDER_TO_BYTE_ORDER
[self
._field
_type
.byte_order
]
403 "Could not get byte order field declaration attribute.")
406 def byte_order(self
, byte_order
):
408 self
._field
_type
.byte_order
= _BYTE_ORDER_TO_BT2_BYTE_ORDER
[byte_order
]
410 raise ValueError("Could not set byte order value.")
417 Integer encoding (one of
418 :class:`babeltrace.common.CTFStringEncoding` constants).
420 Set this attribute to change this field's encoding.
422 :exc:`ValueError` is raised on error.
426 return _BT2_ENCODING_TO_ENCODING
[self
._field
_type
.encoding
]
428 raise ValueError("Could not get field encoding.")
431 def encoding(self
, encoding
):
433 self
._field
_type
.encoding
= _ENCODING_TO_BT2_ENCODING
[encoding
]
435 raise ValueError("Could not set field encoding.")
438 class IntegerFieldDeclaration(FieldDeclaration
, _EncodingProp
):
440 Integer field declaration.
443 def __init__(self
, size
):
445 Creates an integer field declaration of size *size* bits.
447 :exc:`ValueError` is raised on error.
450 self
._field
_type
= bt2
.IntegerFieldType(size
)
456 Integer size in bits (integer).
458 Set this attribute to change this integer's size.
460 :exc:`ValueError` is raised on error.
464 return self
._field
_type
.size
466 raise ValueError("Could not get Integer size attribute.")
471 ``True`` if this integer is signed.
473 Set this attribute to change this integer's signedness
476 :exc:`ValueError` is raised on error.
480 return self
._field
_type
.is_signed
482 raise ValueError("Could not get Integer signed attribute.")
485 def signed(self
, signed
):
487 self
._field
_type
.is_signed
= signed
489 raise ValueError("Could not set Integer signed attribute.")
494 Integer display base (one of :class:`IntegerBase` constants).
496 Set this attribute to change this integer's display base.
498 :exc:`ValueError` is raised on error.
502 return self
._field
_type
.base
504 raise ValueError("Could not get Integer base attribute.")
507 def base(self
, base
):
509 self
._field
_type
.base
= base
511 raise ValueError("Could not set Integer base.")
514 class EnumerationFieldDeclaration(FieldDeclaration
):
516 Enumeration field declaration. A CTF enumeration maps labels to
520 def __init__(self
, integer_type
):
522 Creates an enumeration field declaration, with *integer_type*
523 being the underlying :class:`IntegerFieldDeclaration` for storing
526 :exc:`ValueError` is raised on error.
529 isinst
= isinstance(integer_type
, IntegerFieldDeclaration
)
531 if integer_type
is None or not isinst
:
532 raise TypeError("Invalid integer container.")
534 self
._field
_type
= bt2
.EnumerationFieldType(integer_type
._field
_type
)
540 Underlying container (:class:`IntegerFieldDeclaration`).
542 :exc:`TypeError` is raised on error.
546 return FieldDeclaration
._create
_field
_declaration
(
547 self
._field
_type
.integer_field_type
)
549 raise TypeError("Invalid enumeration declaration")
551 def add_mapping(self
, name
, range_start
, range_end
):
553 Adds a mapping to the enumeration field declaration, from the
554 label named *name* to range [*range_start*, *range_end*], where
555 *range_start* and *range_end* are integers included in the
558 :exc:`ValueError` is raised on error.
562 self
._field
_type
.add_mapping(name
, range_start
, range_end
)
565 "Could not add mapping to enumeration declaration.")
570 Generates the mappings of this enumeration field declaration
571 (:class:`EnumerationMapping` objects).
573 :exc:`TypeError` is raised on error.
576 for mapping
in self
._field
_type
:
577 yield EnumerationMapping(mapping
.name
, mapping
.lower
,
580 def get_mapping_by_name(self
, name
):
582 Returns the :class:`EnumerationMapping` object for the label
585 :exc:`TypeError` is raised on error.
589 mappings
= list(self
._field
_type
.mappings_by_name(name
))
592 'Could not get enumeration mappings by name \'{}\''.format(
598 mapping
= mappings
[0]
599 return EnumerationMapping(mapping
.name
, mapping
.lower
, mapping
.upper
)
601 def get_mapping_by_value(self
, value
):
603 Returns the :class:`EnumerationMapping` object for the value
606 :exc:`TypeError` is raised on error.
610 mappings
= list(self
._field
_type
.mappings_by_value(value
))
613 'Could not get enumeration mappings by value \'{}\''.format(
619 mapping
= mappings
[0]
620 return EnumerationMapping(mapping
.name
, mapping
.lower
, mapping
.upper
)
623 class FloatingPointFieldDeclaration(FieldDeclaration
):
625 Floating point number field declaration.
627 A CTF floating point number is a made of three sections: the sign
628 bit, the exponent bits, and the mantissa bits. The most significant
629 bit of the resulting binary word is the sign bit, and is included
630 in the number of mantissa bits.
633 `IEEE 754 <http://en.wikipedia.org/wiki/IEEE_floating_point>`_
634 single precision floating point number is represented on a 32-bit
635 word using an 8-bit exponent (``e``) and a 24-bit mantissa (``m``),
636 the latter count including the sign bit (``s``)::
638 s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
640 The IEEE 754 double precision floating point number uses an
641 11-bit exponent and a 53-bit mantissa.
644 #: IEEE 754 single precision floating point number exponent size
647 #: IEEE 754 double precision floating point number exponent size
650 #: IEEE 754 single precision floating point number mantissa size
653 #: IEEE 754 double precision floating point number mantissa size
658 Creates a floating point number field declaration.
660 :exc:`ValueError` is raised on error.
663 self
._field
_type
= bt2
.FloatingPointNumberFieldType()
667 def exponent_digits(self
):
669 Floating point number exponent section size in bits (integer).
671 Set this attribute to change the floating point number's
672 exponent section's size. You may use :attr:`FLT_EXP_DIG` or
673 :attr:`DBL_EXP_DIG` for IEEE 754 floating point numbers.
675 :exc:`ValueError` is raised on error.
679 return self
._field
_type
.exponent_size
682 "Could not get Floating point exponent digit count")
684 @exponent_digits.setter
685 def exponent_digits(self
, exponent_digits
):
687 self
._field
_type
.exponent_size
= exponent_digits
689 raise ValueError("Could not set exponent digit count.")
692 def mantissa_digits(self
):
694 Floating point number mantissa section size in bits (integer).
696 Set this attribute to change the floating point number's
697 mantissa section's size. You may use :attr:`FLT_MANT_DIG` or
698 :attr:`DBL_MANT_DIG` for IEEE 754 floating point numbers.
700 :exc:`ValueError` is raised on error.
704 return self
._field
_type
.mantissa_size
707 "Could not get Floating point mantissa digit count")
709 @mantissa_digits.setter
710 def mantissa_digits(self
, mantissa_digits
):
712 self
._field
_type
.mantissa_size
= mantissa_digits
714 raise ValueError("Could not set mantissa digit count.")
717 class FloatFieldDeclaration(FloatingPointFieldDeclaration
):
721 class StructureFieldDeclaration(FieldDeclaration
):
723 Structure field declaration, i.e. an ordered mapping from field
724 names to field declarations.
729 Creates an empty structure field declaration.
731 :exc:`ValueError` is raised on error.
734 self
._field
_type
= bt2
.StructureFieldType()
737 def add_field(self
, field_type
, field_name
):
739 Appends one :class:`FieldDeclaration` *field_type* named
740 *field_name* to the structure's ordered map.
742 :exc:`ValueError` is raised on error.
746 self
._field
_type
.append_field(field_name
, field_type
._field
_type
)
748 raise ValueError("Could not add field to structure.")
753 Generates the (field name, :class:`FieldDeclaration`) pairs
756 :exc:`TypeError` is raised on error.
759 for name
, field_type
in self
._field
_type
.items():
761 FieldDeclaration
._create
_field
_declaration
(
764 def get_field_by_name(self
, name
):
766 Returns the :class:`FieldDeclaration` mapped to the field name
767 *name* in this structure.
769 :exc:`TypeError` is raised on error.
772 if name
not in self
._field
_type
:
773 msg
= "Could not find Structure field with name {}".format(name
)
776 field_type
= self
._field
_type
[name
]
777 return FieldDeclaration
._create
_field
_declaration
(
781 class VariantFieldDeclaration(FieldDeclaration
):
783 Variant field declaration.
785 A CTF variant is a dynamic selection between different fields.
786 The value of a *tag* (a CTF enumeration) determines what is the
787 current selected field. All the possible fields must be added to
788 its field declaration before using an actual variant field.
791 def __init__(self
, enum_tag
, tag_name
):
793 Creates an empty variant field declaration with tag field
794 declaration *enum_tag* (instance of
795 :class:`EnumerationFieldDeclaration`) named *tag_name*
798 :exc:`ValueError` is raised on error.
801 isinst
= isinstance(enum_tag
, EnumerationFieldDeclaration
)
802 if enum_tag
is None or not isinst
:
803 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
805 self
._field
_type
= bt2
.VariantFieldType(tag_name
=tag_name
,
806 tag_field_type
=enum_tag
._field
_type
)
812 Variant field declaration tag name.
814 :exc:`TypeError` is raised on error.
818 self
._field
_type
.tag_name
820 raise TypeError("Could not get Variant tag name")
825 Variant field declaration tag field declaration
826 (:class:`EnumerationFieldDeclaration` object).
828 :exc:`TypeError` is raised on error.
832 return FieldDeclaration
._create
_field
_declaration
(
833 self
._field
_type
.tag_field_type
)
835 raise TypeError("Could not get Variant tag type")
837 def add_field(self
, field_type
, field_name
):
839 Registers the :class:`FieldDeclaration` object *field_type*
840 as the variant's selected type when the variant's tag's current
841 label is *field_name*.
843 :exc:`ValueError` is raised on error.
847 self
._field
_type
.append_field(name
=field_name
, field_type
=field_type
._field
_type
)
849 raise ValueError("Could not add field to variant.")
854 Generates the (field name, :class:`FieldDeclaration`) pairs
855 of this variant field declaration.
857 :exc:`TypeError` is raised on error.
860 for name
, member
in self
._field
_type
.items():
861 yield (name
, FieldDeclaration
._create
_field
_declaration
(member
))
863 def get_field_by_name(self
, name
):
865 Returns the :class:`FieldDeclaration` selected when the
866 variant's tag's current label is *name*.
868 :exc:`TypeError` is raised on error.
871 if name
not in self
._field
_type
:
873 'Could not find Variant field with name {}'.format(name
))
875 field_type
= self
._field
_type
[name
]
876 return FieldDeclaration
._create
_field
_declaration
(field_type
)
878 def get_field_from_tag(self
, tag
):
880 Returns the :class:`FieldDeclaration` selected by the current
881 label of the :class:`EnumerationField` *tag*.
883 :exc:`TypeError` is raised on error.
887 return create_field(self
).field(tag
).declaration
889 raise TypeError('Could not get Variant field declaration.')
892 class ArrayFieldDeclaration(FieldDeclaration
):
894 Static array field declaration.
897 def __init__(self
, element_type
, length
):
899 Creates a static array field declaration of *length*
900 elements of type *element_type* (:class:`FieldDeclaration`).
902 :exc:`ValueError` is raised on error.
906 self
._field
_type
= bt2
.ArrayFieldType(element_type
._field
_type
, length
)
908 raise ValueError('Failed to create ArrayFieldDeclaration.')
912 def element_type(self
):
914 Type of the elements of this this static array (subclass of
915 :class:`FieldDeclaration`).
917 :exc:`TypeError` is raised on error.
921 return FieldDeclaration
._create
_field
_declaration
(
922 self
._field
_type
.element_field_type
)
924 raise TypeError("Could not get Array element type")
929 Length of this static array (integer).
931 :exc:`TypeError` is raised on error.
935 return self
._field
_type
.length
937 raise TypeError("Could not get Array length")
940 class SequenceFieldDeclaration(FieldDeclaration
):
942 Sequence (dynamic array) field declaration.
945 def __init__(self
, element_type
, length_field_name
):
947 Creates a sequence field declaration of
948 elements of type *element_type* (:class:`FieldDeclaration`).
949 The length of a sequence field based on this sequence field
950 declaration is obtained by retrieving the dynamic integer
951 value of the field named *length_field_name*.
953 :exc:`ValueError` is raised on error.
957 self
._field
_type
= bt2
.SequenceFieldType(element_type
, length_field_name
)
959 raise ValueError('Failed to create SequenceFieldDeclaration.')
963 def element_type(self
):
965 Type of the elements of this sequence (subclass of
966 :class:`FieldDeclaration`).
968 :exc:`TypeError` is raised on error.
972 return FieldDeclaration
._create
_field
_declaration
(
973 self
._field
_type
.element_field_type
)
975 raise TypeError("Could not get Sequence element type")
978 def length_field_name(self
):
980 Name of the integer field defining the dynamic length of
981 sequence fields based on this sequence field declaration.
983 :exc:`TypeError` is raised on error.
987 return self
._field
_type
.length_name
989 raise TypeError("Could not get Sequence element type")
992 class StringFieldDeclaration(FieldDeclaration
, _EncodingProp
):
994 String (NULL-terminated array of bytes) field declaration.
999 Creates a string field declaration.
1001 :exc:`ValueError` is raised on error.
1004 self
._field
_type
= bt2
.StringFieldType()
1009 def create_field(field_type
):
1011 Create an instance of a field.
1013 isinst
= isinstance(field_type
, FieldDeclaration
)
1015 if field_type
is None or not isinst
:
1016 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
1018 if isinstance(field_type
, IntegerFieldDeclaration
):
1019 return IntegerField(field_type
)
1020 elif isinstance(field_type
, EnumerationFieldDeclaration
):
1021 return EnumerationField(field_type
)
1022 elif isinstance(field_type
, FloatFieldDeclaration
):
1023 return FloatingPointField(field_type
)
1024 elif isinstance(field_type
, StructureFieldDeclaration
):
1025 return StructureField(field_type
)
1026 elif isinstance(field_type
, VariantFieldDeclaration
):
1027 return VariantField(field_type
)
1028 elif isinstance(field_type
, ArrayFieldDeclaration
):
1029 return ArrayField(field_type
)
1030 elif isinstance(field_type
, SequenceFieldDeclaration
):
1031 return SequenceField(field_type
)
1032 elif isinstance(field_type
, StringFieldDeclaration
):
1033 return StringField(field_type
)
1038 Base class of all fields. This class is not meant to be
1039 instantiated by the user, and neither are its subclasses. Use
1040 :meth:`Event.payload` to access specific, concrete fields of
1044 def __init__(self
, field_type
):
1045 if not isinstance(field_type
, FieldDeclaration
):
1046 raise TypeError("Invalid field_type argument.")
1049 self
._f
= field_type
._field
_type
()
1051 raise ValueError("Field creation failed.")
1054 def _create_field(bt2_field
):
1056 bt2
._IntegerField
: IntegerField
,
1057 bt2
._FloatingPointNumberField
: FloatingPointField
,
1058 bt2
._EnumerationField
: EnumerationField
,
1059 bt2
._StringField
: StringField
,
1060 bt2
._StructureField
: StructureField
,
1061 bt2
._VariantField
: VariantField
,
1062 bt2
._ArrayField
: ArrayField
,
1063 bt2
._SequenceField
: SequenceField
1066 if type(bt2_field
) not in type_dict
:
1067 raise TypeError("Invalid field instance.")
1069 field
= Field
.__new
__(Field
)
1070 field
._f
= bt2_field
1071 field
.__class
__ = type_dict
[type(bt2_field
)]
1076 def declaration(self
):
1078 Field declaration (subclass of :class:`FieldDeclaration`).
1080 :exc:`TypeError` is raised on error.
1083 return FieldDeclaration
._create
_field
_declaration
(self
._f
.field_type
)
1086 class IntegerField(Field
):
1088 Integer field, based on an :class:`IntegerFieldDeclaration` object.
1094 Integer value (:class:`int`).
1096 Set this attribute to change the integer field's value.
1098 :exc:`ValueError` or :exc:`TypeError` are raised on error.
1104 ValueError('Could not get integer field value.')
1107 def value(self
, value
):
1109 self
._f
.value
= value
1111 raise ValueError("Could not set integer field value.")
1114 class EnumerationField(Field
):
1116 Enumeration field, based on an
1117 :class:`EnumerationFieldDeclaration` object.
1121 def container(self
):
1123 Underlying container (:class:`IntegerField`).
1125 :exc:`TypeError` is raised on error.
1129 return Field
._create
_field
(self
._f
.integer_field
)
1131 raise TypeError("Invalid enumeration field type.")
1136 Current label of this enumeration field (:class:`str`).
1138 Set this attribute to an integer (:class:`int`) to change the
1139 enumeration field's value.
1141 :exc:`ValueError` is raised on error.
1145 bt2_enum_ft
= self
._f
.field_type
1146 mappings
= list(bt2_enum_ft
.mappings_by_value(self
._f
.value
))
1147 return mappings
[0].name
1149 raise ValueError("Could not get enumeration mapping name.")
1152 def value(self
, value
):
1153 if not isinstance(value
, int):
1154 raise TypeError("EnumerationField value must be an int")
1156 self
._f
.value
= value
1159 class FloatingPointField(Field
):
1161 Floating point number field, based on a
1162 :class:`FloatingPointFieldDeclaration` object.
1168 Floating point number value (:class:`float`).
1170 Set this attribute to change the floating point number field's
1173 :exc:`ValueError` or :exc:`TypeError` are raised on error.
1179 raise ValueError("Could not get floating point field value.")
1182 def value(self
, value
):
1184 self
._f
.value
= value
1186 raise ValueError("Could not set floating point field value.")
1189 # This class is provided to ensure backward-compatibility since a stable
1190 # release publicly exposed this... abomination.
1191 class FloatFieldingPoint(FloatingPointField
):
1195 class StructureField(Field
):
1197 Structure field, based on a
1198 :class:`StructureFieldDeclaration` object.
1201 def field(self
, field_name
):
1203 Returns the structure :class:`Field` named *field_name*.
1205 :exc:`ValueError` is raised on error.
1209 return Field
._create
_field
(self
._f
[field_name
])
1211 raise ValueError("Invalid field_name provided.")
1214 class VariantField(Field
):
1216 Variant field, based on a
1217 :class:`VariantFieldDeclaration` object.
1220 def field(self
, tag
):
1222 Returns the :class:`Field` selected by the current label of
1223 *tag* (:class:`EnumerationField`).
1225 :exc:`ValueError` is raised on error.
1229 return Field
._create
_field
(self
._f
.field(tag
._f
))
1231 raise ValueError("Invalid tag provided.")
1234 class ArrayField(Field
):
1236 Static array field, based on an
1237 :class:`ArrayFieldDeclaration` object.
1240 def field(self
, index
):
1242 Returns the :class:`Field` at index *index* in this static
1245 :exc:`IndexError` is raised on error.
1249 return Field
._create
_field
(self
._f
[index
])
1251 raise IndexError("Invalid index provided.")
1254 class SequenceField(Field
):
1256 Sequence (dynamic array) field, based on a
1257 :class:`SequenceFieldDeclaration` object.
1263 Sequence length (:class:`IntegerField`).
1265 Set this attribute to change the sequence length's integer
1266 field (integer must be unsigned).
1268 :exc:`ValueError` or :exc:`TypeError` are raised on error.
1272 length_field
= self
._f
.length_field
1273 if length_field
is None:
1275 return Field
._create
_field
(length_field
)
1277 raise ValueError('Invalid sequence field.')
1280 def length(self
, length_field
):
1281 if not isinstance(length_field
, IntegerField
):
1282 raise TypeError("Invalid length field.")
1284 if length_field
.declaration
.signed
:
1285 raise TypeError("Sequence field length must be unsigned")
1288 self
._f
.length_field
= length_field
._f
1290 raise ValueError("Could not set sequence length.")
1292 def field(self
, index
):
1294 Returns the :class:`Field` at index *index* in this sequence.
1296 :exc:`ValueError` is raised on error.
1300 return Field
._create
_field
(self
._f
[index
])
1302 raise IndexError("Invalid index provided.")
1305 class StringField(Field
):
1307 String (NULL-terminated array of bytes) field.
1313 String value (:class:`str`).
1315 Set this attribute to change the string's value.
1317 :exc:`ValueError` or :exc:`TypeError` are raised on error.
1323 raise ValueError('Could not get string field value.')
1326 def value(self
, value
):
1328 self
._f
.value
= value
1330 raise ValueError("Could not set string field value.")
1335 An event class contains the properties of specific
1336 events (:class:`Event`). Any concrete event must be linked with an
1337 :class:`EventClass`.
1339 Some attributes are automatically set when creating an event class.
1340 For example, if no numeric ID is explicitly set using the
1341 :attr:`id` attribute, a default, unique ID within the stream class
1342 containing this event class will be created when needed.
1345 def __init__(self
, name
):
1347 Creates an event class named *name*.
1349 :exc:`ValueError` is raised on error.
1352 self
._ec
= bt2
.EventClass(name
)
1354 if self
._ec
is None:
1355 raise ValueError("Event class creation failed.")
1357 def add_field(self
, field_type
, field_name
):
1359 Adds a field declaration *field_type* named *field_name* to
1362 *field_type* must be one of:
1364 * :class:`IntegerFieldDeclaration`
1365 * :class:`FloatingPointFieldDeclaration`
1366 * :class:`EnumerationFieldDeclaration`
1367 * :class:`StringFieldDeclaration`
1368 * :class:`ArrayFieldDeclaration`
1369 * :class:`SequenceFieldDeclaration`
1370 * :class:`StructureFieldDeclaration`
1371 * :class:`VariantFieldDeclaration`
1373 :exc:`ValueError` is raised on error.
1377 self
._ec
.payload_field_type
.append_field(field_name
,
1378 field_type
._field
_type
)
1380 raise ValueError("Could not add field to event class.")
1389 return self
._ec
.name
1391 raise TypeError("Could not get EventClass name")
1396 Event class' numeric ID.
1398 Set this attribute to assign a numeric ID to this event class.
1399 This ID must be unique amongst all the event class IDs of a
1402 :exc:`TypeError` is raised on error.
1408 raise TypeError("Could not get EventClass id")
1415 raise TypeError("Can't change an EventClass id after it has been assigned to a stream class.")
1418 def stream_class(self
):
1420 :class:`StreamClass` object containing this event class,
1421 or ``None`` if not set.
1424 bt2_stream_class
= self
._ec
.stream_class
1425 if bt2_stream_class
is None:
1428 stream_class
= StreamClass
.__new
__(StreamClass
)
1429 stream_class
._stream
_class
= bt2_stream_class
1436 Generates the (field name, :class:`FieldDeclaration`) pairs of
1439 :exc:`TypeError` is raised on error.
1442 return FieldDeclaration
._create
_field
_declaration
(
1443 self
._ec
.payload_field_type
).fields
1445 def get_field_by_name(self
, name
):
1447 Returns the :class:`FieldDeclaration` object named *name* in
1450 :exc:`TypeError` is raised on error.
1453 return FieldDeclaration
._create
_field
_declaration
(
1454 self
._ec
.payload_field_type
)[name
]
1459 Events are specific instances of event classes
1460 (:class:`EventClass`), which means they may contain actual,
1461 concrete field values.
1464 def __init__(self
, event_class
):
1466 Creates an event linked with the :class:`EventClass`
1469 :exc:`ValueError` is raised on error.
1472 if not isinstance(event_class
, EventClass
):
1473 raise TypeError("Invalid event_class argument.")
1476 self
._e
= event_class
._ec
()
1478 raise ValueError("Event creation failed.")
1481 def event_class(self
):
1483 :class:`EventClass` object to which this event is linked.
1486 event_class
= EventClass
.__new
__(EventClass
)
1487 event_class
._ec
= self
._e
.event_class
1492 :class:`Clock` object used by this object, or ``None`` if
1493 the event class is not registered to a stream class.
1497 bt2_clock
= self
._e
.event_class
.stream_class
.clock
1501 clock
= Clock
.__new
__(Clock
)
1502 clock
._c
= bt2_clock
1505 def payload(self
, field_name
):
1507 Returns the :class:`Field` object named *field_name* in this
1510 The returned field object is created using the event class'
1511 field declaration named *field_name*.
1513 The return type is one of:
1515 * :class:`IntegerField`
1516 * :class:`FloatingPointField`
1517 * :class:`EnumerationField`
1518 * :class:`StringField`
1519 * :class:`ArrayField`
1520 * :class:`SequenceField`
1521 * :class:`StructureField`
1522 * :class:`VariantField`
1524 :exc:`TypeError` is raised on error.
1528 return Field
._create
_field
(self
._e
.payload_field
[field_name
])
1530 raise TypeError('Could not get field from event.')
1532 def set_payload(self
, field_name
, value_field
):
1534 Set the event's field named *field_name* to the manually
1535 created :class:`Field` object *value_field*.
1537 *value_field*'s type must be one of:
1539 * :class:`IntegerField`
1540 * :class:`FloatingPointField`
1541 * :class:`EnumerationField`
1542 * :class:`StringField`
1543 * :class:`ArrayField`
1544 * :class:`SequenceField`
1545 * :class:`StructureField`
1546 * :class:`VariantField`
1548 :exc:`ValueError` is raised on error.
1551 if not isinstance(value_field
, Field
):
1552 raise TypeError("Invalid value type.")
1555 self
._e
.payload_field
[field_name
] = value_field
._f
1557 raise ValueError("Could not set event field payload.")
1560 def stream_context(self
):
1562 Stream event context field (instance of
1563 :class:`StructureField`).
1565 Set this attribute to assign a stream event context field
1568 :exc:`ValueError` is raised on error.
1572 return Field
._create
_field
(self
._e
.context_field
)
1574 raise ValueError("Invalid Stream.")
1576 @stream_context.setter
1577 def stream_context(self
, field
):
1578 if not isinstance(field
, StructureField
):
1579 raise TypeError("Argument field must be of type StructureField")
1582 self
._e
.context_field
= field
._f
1584 raise ValueError("Invalid stream context field.")
1589 A stream class contains the properties of specific
1590 streams (:class:`Stream`). Any concrete stream must be linked with
1591 a :class:`StreamClass`, usually by calling
1592 :meth:`Writer.create_stream`.
1594 Some attributes are automatically set when creating a stream class.
1595 For example, if no clock is explicitly set using the
1596 :attr:`clock` attribute, a default clock will be created
1600 def __init__(self
, name
):
1602 Creates a stream class named *name*.
1604 :exc:`ValueError` is raised on error.
1608 # Set default event header and packet context.
1609 event_header_type
= bt2
.StructureFieldType()
1610 uint32_ft
= bt2
.IntegerFieldType(32)
1611 uint64_ft
= bt2
.IntegerFieldType(64)
1612 event_header_type
.append_field('id', uint32_ft
)
1613 event_header_type
.append_field('timestamp', uint64_ft
)
1615 packet_context_type
= bt2
.StructureFieldType()
1616 packet_context_type
.append_field('timestamp_begin', uint64_ft
)
1617 packet_context_type
.append_field('timestamp_end', uint64_ft
)
1618 packet_context_type
.append_field('content_size', uint64_ft
)
1619 packet_context_type
.append_field('packet_size', uint64_ft
)
1620 packet_context_type
.append_field('events_discarded', uint64_ft
)
1621 sc
= bt2
.StreamClass(name
,
1622 event_header_field_type
=event_header_type
,
1623 packet_context_field_type
=packet_context_type
)
1624 self
._stream
_class
= sc
1626 raise ValueError("Stream class creation failed.")
1633 :exc:`TypeError` is raised on error.
1637 return self
._stream
_class
.name
1639 raise TypeError("Could not get StreamClass name")
1644 Stream class' clock (:class:`Clock` object).
1646 Set this attribute to change the clock of this stream class.
1648 :exc:`ValueError` is raised on error.
1651 if self
._stream
_class
.clock
is None:
1654 clock
= Clock
.__new
__(Clock
)
1655 clock
._c
= self
._stream
_class
.clock
1659 def clock(self
, clock
):
1660 if not isinstance(clock
, Clock
):
1661 raise TypeError("Invalid clock type.")
1664 self
._stream
_class
.clock
= clock
._clock
1666 raise ValueError("Could not set stream class clock.")
1671 Stream class' numeric ID.
1673 Set this attribute to change the ID of this stream class.
1675 :exc:`ValueError` is raised on error.
1679 return self
._stream
_class
.id
1681 raise TypeError("Could not get StreamClass id")
1686 self
._stream
_class
.id = id
1688 raise TypeError("Could not set stream class id.")
1691 def event_classes(self
):
1693 Generates the event classes (:class:`EventClass` objects) of
1696 :exc:`TypeError` is raised on error.
1699 for bt2_ec
in self
._stream
_class
.values():
1700 event_class
= EventClass
.__new
__(EventClass
)
1701 event_class
._ec
= bt2_ec
1704 def add_event_class(self
, event_class
):
1706 Registers the :class:`EventClass` *event_class* to this stream
1709 Once the event class is registered, it will be generated as one
1710 of the event classes generated by :attr:`event_classes`.
1712 :exc:`ValueError` is raised on error.
1715 if not isinstance(event_class
, EventClass
):
1716 raise TypeError("Invalid event_class type.")
1719 self
._stream
_class
.add_event_class(event_class
._ec
)
1721 raise ValueError("Could not add event class.")
1724 def packet_context_type(self
):
1726 Stream packet context declaration.
1728 Set this attribute to change the stream packet context
1729 declaration (must be an instance of
1730 :class:`StructureFieldDeclaration`).
1732 :exc:`ValueError` is raised on error.
1737 bt2_field_type
= self
._stream
_class
.packet_context_field_type
1738 if bt2_field_type
is None:
1739 raise ValueError("Invalid StreamClass")
1741 field_type
= FieldDeclaration
._create
_field
_declaration
(
1745 raise ValueError("Invalid StreamClass")
1747 @packet_context_type.setter
1748 def packet_context_type(self
, field_type
):
1749 if field_type
is not None and not isinstance(field_type
,
1750 StructureFieldDeclaration
):
1751 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
1753 bt2_field_type
= None if field_type
is None else field_type
._field
_type
1755 self
._stream
_class
.packet_context_field_type
= bt2_field_type
1757 raise ValueError("Failed to set packet context type.")
1760 def event_context_type(self
):
1762 Stream event context declaration.
1764 Set this attribute to change the stream event context
1765 declaration (must be an instance of
1766 :class:`StructureFieldDeclaration`).
1768 :exc:`ValueError` is raised on error.
1773 bt2_field_type
= self
._stream
_class
.event_context_field_type
1774 if bt2_field_type
is None:
1775 raise ValueError("Invalid StreamClass")
1777 field_type
= FieldDeclaration
._create
_field
_declaration
(
1781 raise ValueError("Invalid StreamClass")
1783 @event_context_type.setter
1784 def event_context_type(self
, field_type
):
1785 if field_type
is not None and not isinstance(field_type
,
1786 StructureFieldDeclaration
):
1787 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
1789 bt2_field_type
= None if field_type
is None else field_type
._field
_type
1791 self
._stream
_class
.event_context_field_type
= bt2_field_type
1793 raise ValueError("Failed to set event context type.")
1798 Streams are specific instances of stream classes, which means they
1799 may contain actual, concrete events.
1801 :class:`Stream` objects are returned by
1802 :meth:`Writer.create_stream`; they are not meant to be
1803 instantiated by the user.
1805 Concrete :class:`Event` objects are appended to
1806 :class:`Stream` objects using :meth:`append_event`.
1808 When :meth:`flush` is called, a CTF packet is created, containing
1809 all the appended events since the last flush. Although the stream
1810 is flushed on object destruction, it is **strongly recommended**
1811 that the user call :meth:`flush` manually before exiting the
1812 script, as :meth:`__del__` is not always reliable.
1816 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
1819 def discarded_events(self
):
1821 Number of discarded (lost) events in this stream so far.
1823 :exc:`ValueError` is raised on error.
1827 return self
._s
.discarded_events_count
1829 raise ValueError("Could not get the stream discarded events count")
1831 def append_discarded_events(self
, event_count
):
1833 Appends *event_count* discarded events to this stream.
1836 self
._s
.append_discarded_events(event_count
)
1838 def append_event(self
, event
):
1840 Appends event *event* (:class:`Event` object) to this stream.
1842 The stream's associated clock will be sampled during this call.
1843 *event* **shall not** be modified after being appended to this
1846 :exc:`ValueError` is raised on error.
1850 self
._s
.append_event(event
._e
)
1852 raise ValueError("Could not append event to stream.")
1855 def packet_context(self
):
1857 Stream packet context field (instance of
1858 :class:`StructureField`).
1860 Set this attribute to assign a stream packet context field
1863 :exc:`ValueError` is raised on error.
1866 bt2_field
= self
._s
.packet_context_field
1867 if bt2_field
is None:
1868 raise ValueError("Invalid Stream.")
1870 return Field
._create
_field
(bt2_field
)
1872 @packet_context.setter
1873 def packet_context(self
, field
):
1874 if not isinstance(field
, StructureField
):
1875 raise TypeError("Argument field must be of type StructureField")
1878 self
._s
.packet_context_field
= field
._f
1880 raise ValueError("Invalid packet context field.")
1884 Flushes the current packet of this stream to disk. Events
1885 subsequently appended to the stream will be added to a new
1888 :exc:`ValueError` is raised on error.
1894 raise ValueError('Failed to flush CTF writer stream')
1899 This object is the CTF writer API context. It oversees its streams
1900 and clocks, and is responsible for writing one CTF trace.
1903 def __init__(self
, path
):
1905 Creates a CTF writer, initializing a new CTF trace at path
1908 *path* must be an existing directory, since a CTF trace is
1909 made of multiple files.
1911 :exc:`ValueError` is raised if the creation fails.
1915 self
._w
= bt2
.CtfWriter(path
)
1917 raise ValueError("Writer creation failed.")
1919 def create_stream(self
, stream_class
):
1921 Creates and registers a new stream based on stream class
1924 This is the standard way of creating a :class:`Stream` object:
1925 the user is not allowed to instantiate this class.
1927 Returns a new :class:`Stream` object.
1930 if not isinstance(stream_class
, StreamClass
):
1931 raise TypeError("Invalid stream_class type.")
1933 if stream_class
._stream
_class
.trace
is None:
1934 self
._w
.trace
.add_stream_class(stream_class
._stream
_class
)
1936 stream
= Stream
.__new
__(Stream
)
1937 stream
._s
= stream_class
._stream
_class
()
1938 stream
.__class
__ = Stream
1941 def add_environment_field(self
, name
, value
):
1943 Sets the CTF environment variable named *name* to value *value*
1944 (converted to a string).
1946 :exc:`ValueError` or `TypeError` is raised on error.
1949 if type(name
) != str:
1950 raise TypeError("Field name must be a string.")
1954 if type(value
) != str and type(value
) != int:
1955 raise TypeError("Value type is not supported.")
1958 self
._w
.trace
.env
[name
] = value
1960 raise ValueError("Could not add environment field to trace.")
1962 def add_clock(self
, clock
):
1964 Registers :class:`Clock` object *clock* to the writer.
1966 You *must* register CTF clocks assigned to stream classes
1969 :exc:`ValueError` is raised if the creation fails.
1973 self
._w
.add_clock(clock
._clock
)
1975 raise ValueError("Could not add clock to Writer.")
1980 Current metadata of this trace (:class:`str`).
1983 return self
._w
.metadata_string
1985 def flush_metadata(self
):
1987 Flushes the trace's metadata to the metadata file.
1990 self
._w
.flush_metadata()
1993 def byte_order(self
):
1995 Native byte order of this trace (one of
1996 :class:`babeltrace.common.ByteOrder` constants).
1998 This is the actual byte order that is used when a field
2000 :attr:`babeltrace.common.ByteOrder.BYTE_ORDER_NATIVE`
2003 Set this attribute to change the trace's native byte order.
2005 Defaults to the host machine's endianness.
2007 :exc:`ValueError` is raised on error.
2009 raise NotImplementedError("Getter not implemented.")
2012 def byte_order(self
, byte_order
):
2014 self
._w
.trace
.native_byte_order
= _BYTE_ORDER_TO_BT2_BYTE_ORDER
[byte_order
]
2016 raise ValueError("Could not set trace byte order.")
2019 _BT2_FIELD_TYPE_TO_BT_DECLARATION
= {
2020 bt2
.IntegerFieldType
: IntegerFieldDeclaration
,
2021 bt2
.FloatingPointNumberFieldType
: FloatFieldDeclaration
,
2022 bt2
.EnumerationFieldType
: EnumerationFieldDeclaration
,
2023 bt2
.StringFieldType
: StringFieldDeclaration
,
2024 bt2
.StructureFieldType
: StructureFieldDeclaration
,
2025 bt2
.ArrayFieldType
: ArrayFieldDeclaration
,
2026 bt2
.SequenceFieldType
: SequenceFieldDeclaration
,
2027 bt2
.VariantFieldType
: VariantFieldDeclaration
,