3 # Babeltrace native interface Python module
5 # Copyright 2012-2015 EfficiOS Inc.
7 # Author: Danny Serres <danny.serres@efficios.com>
8 # Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 # Permission is hereby granted, free of charge, to any person obtaining a copy
11 # of this software and associated documentation files (the "Software"), to deal
12 # in the Software without restriction, including without limitation the rights
13 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 # copies of the Software, and to permit persons to whom the Software is
15 # furnished to do so, subject to the following conditions:
17 # The above copyright notice and this permission notice shall be included in
18 # all copies or substantial portions of the Software.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 import babeltrace
.nativebt
as nbt
31 from datetime
import datetime
35 class TraceCollection
:
37 A :class:`TraceCollection` is a collection of opened traces.
39 In general, once a trace collection is created, you add one to many
40 independent traces to it using :meth:`add_trace` or
41 :meth:`add_traces_recursive`, and then iterate the ordered events
42 of all traces merged together using :attr:`events`.
44 You may use :meth:`remove_trace` to close and remove a specific
45 trace from a trace collection, although all the traces of a given
46 trace collection will be automatically removed when it is garbage
52 Creates an empty trace collection.
55 self
._tc
= nbt
._bt
_context
_create
()
58 nbt
._bt
_context
_put
(self
._tc
)
60 def add_trace(self
, path
, format_str
):
62 Adds a trace to the trace collection.
64 The trace is located at the file system path *path*. This
65 function **does not** recurse directories to find the trace:
66 *path* must point to the exact trace location (see
67 :meth:`add_traces_recursive` for a recursive version of this
70 *format_str* is a string indicating the Babeltrace type of the
71 trace to add. ``ctf`` is the only currently supported trace
74 Once added, the trace is opened.
76 Returns the corresponding :class:`TraceHandle` instance for
77 this opened trace on success, or ``None`` on error.
80 ret
= nbt
._bt
_context
_add
_trace
(self
._tc
, path
, format_str
,
86 th
= TraceHandle
.__new
__(TraceHandle
)
88 th
._trace
_collection
= self
92 def add_traces_recursive(self
, path
, format_str
):
94 Adds traces to this trace collection by recursively searching
95 in the *path* directory.
97 *format_str* is a string indicating the Babeltrace type of the
98 traces to find and add. ``ctf`` is the only currently supported
101 See also :meth:`add_trace`.
103 Returns a :class:`dict` object mapping full paths to trace
104 handles for each trace found, or ``None`` on error.
111 for fullpath
, dirs
, files
in os
.walk(path
):
112 if "metadata" in files
:
113 trace_handle
= self
.add_trace(fullpath
, format_str
)
115 if trace_handle
is None:
119 trace_handles
[fullpath
] = trace_handle
122 if noTrace
and error
:
127 def remove_trace(self
, trace_handle
):
129 Removes a trace from the trace collection using its trace
130 handle *trace_handle*.
132 :class:`TraceHandle` objects are returned by :meth:`add_trace`
133 and :meth:`add_traces_recursive`.
135 The trace is closed before being removed.
139 nbt
._bt
_context
_remove
_trace
(self
._tc
, trace_handle
._id
)
140 except AttributeError:
141 raise TypeError("in remove_trace, argument 2 must be a TraceHandle instance")
146 Generates the ordered :class:`Event` objects of all the opened
147 traces contained in this trace collection. Iterate this function
148 to iterate actual events.
150 Due to limitations of the native Babeltrace API, only one event
151 may be "alive" at a given time, i.e. a user **should never**
152 store a copy of the events returned by this function for
153 ulterior use. Users shall make sure to copy the information
154 they need *from* an event before accessing the next one.
156 Furthermore, :class:`Event` objects become invalid when the
157 generator goes out of scope as the underlying iterator will be
158 reclaimed. Using an event after the the generator has gone out
159 of scope may result in a crash or data corruption.
162 begin_pos_ptr
= nbt
._bt
_iter
_pos
()
163 end_pos_ptr
= nbt
._bt
_iter
_pos
()
164 begin_pos_ptr
.type = nbt
.SEEK_BEGIN
165 end_pos_ptr
.type = nbt
.SEEK_LAST
167 for event
in self
._events
(begin_pos_ptr
, end_pos_ptr
):
170 def events_timestamps(self
, timestamp_begin
, timestamp_end
):
172 Generates the ordered :class:`Event` objects of all the opened
173 traces contained in this trace collection from *timestamp_begin*
176 See :attr:`events` for notes and limitations.
179 begin_pos_ptr
= nbt
._bt
_iter
_pos
()
180 end_pos_ptr
= nbt
._bt
_iter
_pos
()
181 begin_pos_ptr
.type = end_pos_ptr
.type = nbt
.SEEK_TIME
182 begin_pos_ptr
.u
.seek_time
= timestamp_begin
183 end_pos_ptr
.u
.seek_time
= timestamp_end
185 for event
in self
._events
(begin_pos_ptr
, end_pos_ptr
):
189 def timestamp_begin(self
):
191 Trace collection's begin timestamp.
194 pos_ptr
= nbt
._bt
_iter
_pos
()
195 pos_ptr
.type = nbt
.SEEK_BEGIN
197 return self
._timestamp
_at
_pos
(pos_ptr
)
200 def timestamp_end(self
):
202 Trace collection's end timestamp.
205 pos_ptr
= nbt
._bt
_iter
_pos
()
206 pos_ptr
.type = nbt
.SEEK_LAST
208 return self
._timestamp
_at
_pos
(pos_ptr
)
210 def _timestamp_at_pos(self
, pos_ptr
):
211 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, pos_ptr
, pos_ptr
)
213 if ctf_it_ptr
is None:
214 raise NotImplementedError("Creation of multiple iterators is unsupported.")
216 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
217 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
219 def _events(self
, begin_pos_ptr
, end_pos_ptr
):
220 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, begin_pos_ptr
, end_pos_ptr
)
222 if ctf_it_ptr
is None:
223 raise NotImplementedError("Creation of multiple iterators is unsupported.")
226 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
231 ev
= Event
.__new
__(Event
)
236 except GeneratorExit
:
239 ret
= nbt
._bt
_iter
_next
(nbt
._bt
_ctf
_get
_iter
(ctf_it_ptr
))
244 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
247 # Based on enum bt_clock_type in clock-type.h
255 A :class:`TraceHandle` is a handle allowing the user to manipulate
256 a specific trace directly. It is a unique identifier representing a
257 trace, and is not meant to be instantiated by the user.
261 raise NotImplementedError("TraceHandle cannot be instantiated")
264 return "Babeltrace TraceHandle: trace_id('{0}')".format(self
._id
)
269 Trace handle's numeric ID.
277 Path of the underlying trace.
280 return nbt
._bt
_trace
_handle
_get
_path
(self
._trace
_collection
._tc
,
284 def timestamp_begin(self
):
286 Buffers creation timestamp (nanoseconds since Epoch) of the
290 return nbt
._bt
_trace
_handle
_get
_timestamp
_begin
(self
._trace
_collection
._tc
,
292 _ClockType
.CLOCK_REAL
)
295 def timestamp_end(self
):
297 Buffers destruction timestamp (nanoseconds since Epoch) of the
301 return nbt
._bt
_trace
_handle
_get
_timestamp
_end
(self
._trace
_collection
._tc
,
303 _ClockType
.CLOCK_REAL
)
308 Generates all the :class:`EventDeclaration` objects of the
311 Note that this doesn't generate actual trace *events*, but
312 rather their declarations, i.e. their layouts and metadata.
315 ret
= nbt
._bt
_python
_event
_decl
_listcaller
(self
.id,
316 self
._trace
_collection
._tc
)
318 if not isinstance(ret
, list):
321 ptr_list
, count
= ret
323 for i
in range(count
):
324 tmp
= EventDeclaration
.__new
__(EventDeclaration
)
325 tmp
._ed
= nbt
._bt
_python
_decl
_one
_from
_list
(ptr_list
, i
)
329 class CTFStringEncoding
:
331 CTF string encodings.
347 # Based on the enum in ctf-writer/writer.h
354 BYTE_ORDER_NATIVE
= 0
357 BYTE_ORDER_LITTLE_ENDIAN
= 1
360 BYTE_ORDER_BIG_ENDIAN
= 2
362 #: Network byte order (big-endian)
363 BYTE_ORDER_NETWORK
= 3
365 #: Unknown byte order
366 BYTE_ORDER_UNKNOWN
= 4 # Python-specific entry
369 # enum equivalent, accessible constants
370 # These are taken directly from ctf/events.h
371 # All changes to enums must also be made here
374 CTF numeric type identifiers.
383 #: Floating point number
411 Returns the name of the CTF numeric type identifier *id*.
414 name
= "UNKNOWN_TYPE"
416 attr
for attr
in dir(CTFTypeId
) if not callable(
419 attr
)) and not attr
.startswith("__")]
421 for attr
in constants
:
422 if getattr(CTFTypeId
, attr
) == id:
435 TRACE_PACKET_HEADER
= 0
438 STREAM_PACKET_CONTEXT
= 1
441 STREAM_EVENT_HEADER
= 2
443 #: Stream event context
444 STREAM_EVENT_CONTEXT
= 3
452 def scope_name(scope
):
454 Returns the name of the CTF scope *scope*.
457 name
= "UNKNOWN_SCOPE"
459 attr
for attr
in dir(CTFScope
) if not callable(
462 attr
)) and not attr
.startswith("__")]
464 for attr
in constants
:
465 if getattr(CTFScope
, attr
) == scope
:
472 # Priority of the scopes when searching for event fields
474 CTFScope
.EVENT_FIELDS
,
475 CTFScope
.EVENT_CONTEXT
,
476 CTFScope
.STREAM_EVENT_CONTEXT
,
477 CTFScope
.STREAM_EVENT_HEADER
,
478 CTFScope
.STREAM_PACKET_CONTEXT
,
479 CTFScope
.TRACE_PACKET_HEADER
483 class Event(collections
.Mapping
):
485 An :class:`Event` object represents a trace event. :class:`Event`
486 objects are returned by :attr:`TraceCollection.events` and are
487 not meant to be instantiated by the user.
489 :class:`Event` has a :class:`dict`-like interface for accessing
490 an event's field value by field name:
492 .. code-block:: python
496 If a field name exists in multiple scopes, the value of the first
497 field found is returned. The scopes are searched in the following
500 1. Event fields (:attr:`CTFScope.EVENT_FIELDS`)
501 2. Event context (:attr:`CTFScope.EVENT_CONTEXT`)
502 3. Stream event context (:attr:`CTFScope.STREAM_EVENT_CONTEXT`)
503 4. Event header (:attr:`CTFScope.STREAM_EVENT_HEADER`)
504 5. Packet context (:attr:`CTFScope.STREAM_PACKET_CONTEXT`)
505 6. Packet header (:attr:`CTFScope.TRACE_PACKET_HEADER`)
507 It is still possible to obtain a field's value from a specific
508 scope using :meth:`field_with_scope`.
510 Field values are returned as native Python types, that is:
512 +-----------------------+----------------------------------+
513 | Field type | Python type |
514 +=======================+==================================+
515 | Integer | :class:`int` |
516 +-----------------------+----------------------------------+
517 | Floating point number | :class:`float` |
518 +-----------------------+----------------------------------+
519 | Enumeration | :class:`str` (enumeration label) |
520 +-----------------------+----------------------------------+
521 | String | :class:`str` |
522 +-----------------------+----------------------------------+
523 | Array | :class:`list` of native Python |
525 +-----------------------+----------------------------------+
526 | Sequence | :class:`list` of native Python |
528 +-----------------------+----------------------------------+
529 | Structure | :class:`dict` mapping field |
530 | | names to native Python objects |
531 +-----------------------+----------------------------------+
533 For example, printing the third element of a sequence named ``seq``
534 in a structure named ``my_struct`` of the ``event``'s field named
535 ``my_field`` is done this way:
537 .. code-block:: python
539 print(event['my_field']['my_struct']['seq'][2])
543 raise NotImplementedError("Event cannot be instantiated")
548 Event's name or ``None`` on error.
551 return nbt
._bt
_ctf
_event
_name
(self
._e
)
556 Event's timestamp in cycles or -1 on error.
559 return nbt
._bt
_ctf
_get
_cycles
(self
._e
)
564 Event's timestamp (nanoseconds since Epoch) or -1 on error.
567 return nbt
._bt
_ctf
_get
_timestamp
(self
._e
)
572 Event's timestamp as a standard :class:`datetime.datetime`
575 Note that the :class:`datetime.datetime` class' precision
576 is limited to microseconds, whereas :attr:`timestamp` provides
577 the event's timestamp with a nanosecond resolution.
580 return datetime
.fromtimestamp(self
.timestamp
/ 1E9
)
582 def field_with_scope(self
, field_name
, scope
):
584 Returns the value of a field named *field_name* within the
585 scope *scope*, or ``None`` if the field cannot be found.
587 *scope* must be one of :class:`CTFScope` constants.
590 if scope
not in _scopes
:
591 raise ValueError("Invalid scope provided")
593 field
= self
._field
_with
_scope
(field_name
, scope
)
595 if field
is not None:
598 def field_list_with_scope(self
, scope
):
600 Returns a list of field names in the scope *scope*.
603 if scope
not in _scopes
:
604 raise ValueError("Invalid scope provided")
608 for field
in self
._field
_list
_with
_scope
(scope
):
609 field_names
.append(field
.name
)
616 :class:`TraceHandle` object containing this event, or ``None``
620 ret
= nbt
._bt
_ctf
_event
_get
_handle
_id
(self
._e
)
625 th
= TraceHandle
.__new
__(TraceHandle
)
627 th
._trace
_collection
= self
.get_trace_collection()
632 def trace_collection(self
):
634 :class:`TraceCollection` object containing this event, or
638 trace_collection
= TraceCollection()
639 trace_collection
._tc
= nbt
._bt
_ctf
_event
_get
_context
(self
._e
)
641 if trace_collection
._tc
is not None:
642 return trace_collection
644 def __getitem__(self
, field_name
):
645 field
= self
._field
(field_name
)
647 if field
is not None:
650 raise KeyError(field_name
)
653 for key
in self
.keys():
659 for scope
in _scopes
:
660 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
661 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
663 if isinstance(ret
, list):
668 def __contains__(self
, field_name
):
669 return self
._field
(field_name
) is not None
673 Returns the list of field names.
675 Note: field names are unique within the returned list, although
676 a field name could exist in multiple scopes. Use
677 :meth:`field_list_with_scope` to obtain the list of field names
683 for scope
in _scopes
:
684 for name
in self
.field_list_with_scope(scope
):
685 field_names
.add(name
)
687 return list(field_names
)
689 def get(self
, field_name
, default
=None):
691 Returns the value of the field named *field_name*, or *default*
694 See :class:`Event` note about how fields are retrieved by
695 name when multiple fields share the same name in different
699 field
= self
._field
(field_name
)
708 Generates pairs of (field name, field value).
710 This method iterates :meth:`keys` to find field names, which
711 means some fields could be unavailable if other fields share
712 their names in scopes with higher priorities.
715 for field
in self
.keys():
716 yield (field
, self
[field
])
718 def _field_with_scope(self
, field_name
, scope
):
719 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
721 if scope_ptr
is None:
724 definition_ptr
= nbt
._bt
_ctf
_get
_field
(self
._e
, scope_ptr
, field_name
)
726 if definition_ptr
is None:
729 field
= _Definition(definition_ptr
, scope
)
733 def _field(self
, field_name
):
736 for scope
in _scopes
:
737 field
= self
._field
_with
_scope
(field_name
, scope
)
739 if field
is not None:
744 def _field_list_with_scope(self
, scope
):
746 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
748 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
749 # provide the "count" return value
752 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
754 if isinstance(ret
, list):
755 list_ptr
, count
= ret
757 for i
in range(count
):
758 definition_ptr
= nbt
._bt
_python
_field
_one
_from
_list
(list_ptr
, i
)
760 if definition_ptr
is not None:
761 definition
= _Definition(definition_ptr
, scope
)
762 fields
.append(definition
)
767 class FieldError(Exception):
769 Field error, raised when a field's value cannot be accessed.
772 def __init__(self
, value
):
776 return repr(self
.value
)
779 class EventDeclaration
:
781 An event declaration contains the properties of a class of events,
782 that is, the common properties and fields layout of all the actual
783 recorded events associated with this declaration.
785 This class is not meant to be instantiated by the user. It is
786 returned by :attr:`TraceHandle.events`.
789 MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
792 raise NotImplementedError("EventDeclaration cannot be instantiated")
797 Event's name, or ``None`` on error.
800 return nbt
._bt
_ctf
_get
_decl
_event
_name
(self
._ed
)
805 Event's numeric ID, or -1 on error.
808 id = nbt
._bt
_ctf
_get
_decl
_event
_id
(self
._ed
)
810 if id == self
.MAX_UINT64
:
818 Generates all the event's field declarations, going through
819 each scope in the following order:
821 1. Event fields (:attr:`CTFScope.EVENT_FIELDS`)
822 2. Event context (:attr:`CTFScope.EVENT_CONTEXT`)
823 3. Stream event context (:attr:`CTFScope.STREAM_EVENT_CONTEXT`)
824 4. Event header (:attr:`CTFScope.STREAM_EVENT_HEADER`)
825 5. Packet context (:attr:`CTFScope.STREAM_PACKET_CONTEXT`)
826 6. Packet header (:attr:`CTFScope.TRACE_PACKET_HEADER`)
828 All the generated field declarations inherit
829 :class:`FieldDeclaration`, and are among:
831 * :class:`IntegerFieldDeclaration`
832 * :class:`FloatFieldDeclaration`
833 * :class:`EnumerationFieldDeclaration`
834 * :class:`StringFieldDeclaration`
835 * :class:`ArrayFieldDeclaration`
836 * :class:`SequenceFieldDeclaration`
837 * :class:`StructureFieldDeclaration`
838 * :class:`VariantFieldDeclaration`
841 for scope
in _scopes
:
842 for declaration
in self
.fields_scope(scope
):
845 def fields_scope(self
, scope
):
847 Generates all the field declarations of the event's scope
850 *scope* must be one of :class:`CTFScope` constants.
852 All the generated field declarations inherit
853 :class:`FieldDeclaration`, and are among:
855 * :class:`IntegerFieldDeclaration`
856 * :class:`FloatFieldDeclaration`
857 * :class:`EnumerationFieldDeclaration`
858 * :class:`StringFieldDeclaration`
859 * :class:`ArrayFieldDeclaration`
860 * :class:`SequenceFieldDeclaration`
861 * :class:`StructureFieldDeclaration`
862 * :class:`VariantFieldDeclaration`
864 ret
= nbt
._by
_python
_field
_decl
_listcaller
(self
._ed
, scope
)
866 if not isinstance(ret
, list):
869 list_ptr
, count
= ret
871 for i
in range(count
):
872 field_decl_ptr
= nbt
._bt
_python
_field
_decl
_one
_from
_list
(list_ptr
, i
)
874 if field_decl_ptr
is not None:
875 decl_ptr
= nbt
._bt
_ctf
_get
_decl
_from
_field
_decl
(field_decl_ptr
)
876 name
= nbt
._bt
_ctf
_get
_decl
_field
_name
(field_decl_ptr
)
877 field_declaration
= _create_field_declaration(decl_ptr
, name
,
879 yield field_declaration
882 class FieldDeclaration
:
884 Base class for concrete field declarations.
886 This class is not meant to be instantiated by the user.
890 raise NotImplementedError("FieldDeclaration cannot be instantiated")
893 return "({0}) {1} {2}".format(CTFScope
.scope_name(self
.scope
),
894 CTFTypeId
.type_name(self
.type),
900 Field's name, or ``None`` on error.
908 Field's type (one of :class:`CTFTypeId` constants).
911 return nbt
._bt
_ctf
_field
_type
(self
._fd
)
916 Field's scope (one of :class:`CTFScope` constants).
922 class IntegerFieldDeclaration(FieldDeclaration
):
923 """Do not instantiate."""
926 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
929 def signedness(self
):
931 Return the signedness of an integer:
932 0 if unsigned; 1 if signed; -1 on error.
935 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
939 """Return the base of an int or a negative value on error."""
941 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
944 def byte_order(self
):
946 Return the byte order. One of class ByteOrder's entries.
949 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
952 return ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
954 return ByteOrder
.BYTE_ORDER_BIG_ENDIAN
956 return ByteOrder
.BYTE_ORDER_UNKNOWN
961 Return the size, in bits, of an int or a negative
965 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
970 Return the encoding. One of class CTFStringEncoding's entries.
971 Return a negative value on error.
974 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
977 class EnumerationFieldDeclaration(FieldDeclaration
):
979 Enumeration field declaration.
983 As of this version, this class is missing some properties.
987 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
990 class ArrayFieldDeclaration(FieldDeclaration
):
992 Static array field declaration.
996 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
1001 Static array's fixed length (number of contained elements), or
1002 a negative value on error.
1005 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
1008 def element_declaration(self
):
1010 Underlying element's field declaration.
1013 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
1015 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1018 class SequenceFieldDeclaration(FieldDeclaration
):
1020 Sequence (dynamic array) field declaration.
1024 As of this version, this class is missing some properties.
1028 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
1031 def element_declaration(self
):
1033 Underlying element's field declaration.
1036 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
1038 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1041 class FloatFieldDeclaration(FieldDeclaration
):
1043 Floating point number field declaration.
1047 As of this version, this class is missing some properties.
1051 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
1054 class StructureFieldDeclaration(FieldDeclaration
):
1056 Structure (ordered map of field names to field declarations) field
1061 As of this version, this class is missing some properties.
1065 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
1068 class StringFieldDeclaration(FieldDeclaration
):
1070 String (NULL-terminated array of bytes) field declaration.
1074 As of this version, this class is missing some properties.
1078 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
1081 class VariantFieldDeclaration(FieldDeclaration
):
1083 Variant (dynamic selection between different types) field declaration.
1087 As of this version, this class is missing some properties.
1091 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
1096 Return the last error code encountered while
1097 accessing a field and reset the error flag.
1098 Return 0 if no error, a negative value otherwise.
1101 return nbt
._bt
_ctf
_field
_get
_error
()
1104 def _create_field_declaration(declaration_ptr
, name
, scope
):
1106 Private field declaration factory.
1109 if declaration_ptr
is None:
1110 raise ValueError("declaration_ptr must be valid")
1111 if scope
not in _scopes
:
1112 raise ValueError("Invalid scope provided")
1114 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
1117 if type == CTFTypeId
.INTEGER
:
1118 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
1119 elif type == CTFTypeId
.ENUM
:
1120 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
1121 elif type == CTFTypeId
.ARRAY
:
1122 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
1123 elif type == CTFTypeId
.SEQUENCE
:
1124 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
1125 elif type == CTFTypeId
.FLOAT
:
1126 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
1127 elif type == CTFTypeId
.STRUCT
:
1128 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
1129 elif type == CTFTypeId
.STRING
:
1130 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
1131 elif type == CTFTypeId
.VARIANT
:
1132 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
1136 declaration
._fd
= declaration_ptr
1137 declaration
._s
= scope
1138 declaration
._name
= name
1144 def __init__(self
, definition_ptr
, scope
):
1145 self
._d
= definition_ptr
1148 if scope
not in _scopes
:
1149 ValueError("Invalid scope provided")
1153 """Return the name of a field or None on error."""
1155 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1159 """Return the type of a field or -1 if unknown."""
1161 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1164 def declaration(self
):
1165 """Return the associated Definition object."""
1167 return _create_field_declaration(
1168 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1170 def _get_enum_str(self
):
1172 Return the string matching the current enumeration.
1173 Return None on error.
1176 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1178 def _get_array_element_at(self
, index
):
1180 Return the array's element at position index.
1181 Return None on error
1184 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1186 if array_ptr
is None:
1189 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1191 if definition_ptr
is None:
1194 return _Definition(definition_ptr
, self
.scope
)
1196 def _get_sequence_len(self
):
1198 Return the len of a sequence or a negative
1202 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1204 return nbt
._bt
_sequence
_len
(seq
)
1206 def _get_sequence_element_at(self
, index
):
1208 Return the sequence's element at position index,
1209 otherwise return None
1212 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1215 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1217 if definition_ptr
is not None:
1218 return _Definition(definition_ptr
, self
.scope
)
1220 def _get_uint64(self
):
1222 Return the value associated with the field.
1223 If the field does not exist or is not of the type requested,
1224 the value returned is undefined. To check if an error occured,
1225 use the field_error() function after accessing a field.
1228 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1230 def _get_int64(self
):
1232 Return the value associated with the field.
1233 If the field does not exist or is not of the type requested,
1234 the value returned is undefined. To check if an error occured,
1235 use the field_error() function after accessing a field.
1238 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1240 def _get_char_array(self
):
1242 Return the value associated with the field.
1243 If the field does not exist or is not of the type requested,
1244 the value returned is undefined. To check if an error occurred,
1245 use the field_error() function after accessing a field.
1248 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1252 Return the value associated with the field.
1253 If the field does not exist or is not of the type requested,
1254 the value returned is undefined. To check if an error occurred,
1255 use the field_error() function after accessing a field.
1258 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1260 def _get_float(self
):
1262 Return the value associated with the field.
1263 If the field does not exist or is not of the type requested,
1264 the value returned is undefined. To check if an error occurred,
1265 use the field_error() function after accessing a field.
1268 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1270 def _get_variant(self
):
1272 Return the variant's selected field.
1273 If the field does not exist or is not of the type requested,
1274 the value returned is undefined. To check if an error occurred,
1275 use the field_error() function after accessing a field.
1278 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1280 def _get_struct_field_count(self
):
1282 Return the number of fields contained in the structure.
1283 If the field does not exist or is not of the type requested,
1284 the value returned is undefined.
1287 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1289 def _get_struct_field_at(self
, i
):
1291 Return the structure's field at position i.
1292 If the field does not exist or is not of the type requested,
1293 the value returned is undefined. To check if an error occurred,
1294 use the field_error() function after accessing a field.
1297 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1302 Return the value associated with the field according to its type.
1303 Return None on error.
1309 if id == CTFTypeId
.STRING
:
1310 value
= self
._get
_str
()
1311 elif id == CTFTypeId
.ARRAY
:
1312 element_decl
= self
.declaration
.element_declaration
1314 if ((element_decl
.type == CTFTypeId
.INTEGER
1315 and element_decl
.length
== 8)
1316 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1317 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1321 for i
in range(self
.declaration
.length
):
1322 element
= self
._get
_array
_element
_at
(i
)
1323 value
.append(element
.value
)
1324 elif id == CTFTypeId
.INTEGER
:
1325 if self
.declaration
.signedness
== 0:
1326 value
= self
._get
_uint
64()
1328 value
= self
._get
_int
64()
1329 elif id == CTFTypeId
.ENUM
:
1330 value
= self
._get
_enum
_str
()
1331 elif id == CTFTypeId
.SEQUENCE
:
1332 element_decl
= self
.declaration
.element_declaration
1334 if ((element_decl
.type == CTFTypeId
.INTEGER
1335 and element_decl
.length
== 8)
1336 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1337 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1339 seq_len
= self
._get
_sequence
_len
()
1342 for i
in range(seq_len
):
1343 evDef
= self
._get
_sequence
_element
_at
(i
)
1344 value
.append(evDef
.value
)
1345 elif id == CTFTypeId
.FLOAT
:
1346 value
= self
._get
_float
()
1347 elif id == CTFTypeId
.VARIANT
:
1348 variant
= _Definition
.__new
__(_Definition
)
1349 variant
._d
= self
._get
_variant
()
1350 value
= variant
.value
1351 elif id == CTFTypeId
.STRUCT
:
1354 for i
in range(self
._get
_struct
_field
_count
()):
1355 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1356 value
[member
.name
] = member
.value
1360 "Error occurred while accessing field {} of type {}".format(
1362 CTFTypeId
.type_name(id)))
1368 """Return the scope of a field or None on error."""
1374 # Used to compare to -1ULL in error checks
1375 _MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
1377 class EnumerationMapping
:
1379 Enumeration mapping class. start and end values are inclusive.
1382 def __init__(self
, name
, start
, end
):
1388 def __init__(self
, name
):
1389 self
._c
= nbt
._bt
_ctf
_clock
_create
(name
)
1392 raise ValueError("Invalid clock name.")
1395 nbt
._bt
_ctf
_clock
_put
(self
._c
)
1400 Get the clock's name.
1403 name
= nbt
._bt
_ctf
_clock
_get
_name
(self
._c
)
1406 raise ValueError("Invalid clock instance.")
1411 def description(self
):
1413 Get the clock's description. None if unset.
1416 return nbt
._bt
_ctf
_clock
_get
_description
(self
._c
)
1419 def description(self
, desc
):
1421 Set the clock's description. The description appears in the clock's TSDL
1425 ret
= nbt
._bt
_ctf
_clock
_set
_description
(self
._c
, str(desc
))
1428 raise ValueError("Invalid clock description.")
1431 def frequency(self
):
1433 Get the clock's frequency (Hz).
1436 freq
= nbt
._bt
_ctf
_clock
_get
_frequency
(self
._c
)
1438 if freq
== CTFWriter
._MAX
_UINT
64:
1439 raise ValueError("Invalid clock instance")
1444 def frequency(self
, freq
):
1446 Set the clock's frequency (Hz).
1449 ret
= nbt
._bt
_ctf
_clock
_set
_frequency
(self
._c
, freq
)
1452 raise ValueError("Invalid frequency value.")
1455 def precision(self
):
1457 Get the clock's precision (in clock ticks).
1460 precision
= nbt
._bt
_ctf
_clock
_get
_precision
(self
._c
)
1462 if precision
== CTFWriter
._MAX
_UINT
64:
1463 raise ValueError("Invalid clock instance")
1468 def precision(self
, precision
):
1470 Set the clock's precision (in clock ticks).
1473 ret
= nbt
._bt
_ctf
_clock
_set
_precision
(self
._c
, precision
)
1476 def offset_seconds(self
):
1478 Get the clock's offset in seconds from POSIX.1 Epoch.
1481 offset_s
= nbt
._bt
_ctf
_clock
_get
_offset
_s
(self
._c
)
1483 if offset_s
== CTFWriter
._MAX
_UINT
64:
1484 raise ValueError("Invalid clock instance")
1488 @offset_seconds.setter
1489 def offset_seconds(self
, offset_s
):
1491 Set the clock's offset in seconds from POSIX.1 Epoch.
1494 ret
= nbt
._bt
_ctf
_clock
_set
_offset
_s
(self
._c
, offset_s
)
1497 raise ValueError("Invalid offset value.")
1502 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1505 offset
= nbt
._bt
_ctf
_clock
_get
_offset
(self
._c
)
1507 if offset
== CTFWriter
._MAX
_UINT
64:
1508 raise ValueError("Invalid clock instance")
1513 def offset(self
, offset
):
1515 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1518 ret
= nbt
._bt
_ctf
_clock
_set
_offset
(self
._c
, offset
)
1521 raise ValueError("Invalid offset value.")
1526 Get a clock's absolute attribute. A clock is absolute if the clock
1527 is a global reference across the trace's other clocks.
1530 is_absolute
= nbt
._bt
_ctf
_clock
_get
_is
_absolute
(self
._c
)
1532 if is_absolute
== -1:
1533 raise ValueError("Invalid clock instance")
1535 return False if is_absolute
== 0 else True
1538 def absolute(self
, is_absolute
):
1540 Set a clock's absolute attribute. A clock is absolute if the clock
1541 is a global reference across the trace's other clocks.
1544 ret
= nbt
._bt
_ctf
_clock
_set
_is
_absolute
(self
._c
, int(is_absolute
))
1547 raise ValueError("Could not set the clock's absolute attribute.")
1552 Get a clock's UUID (an object of type UUID).
1558 ret
, value
= nbt
._bt
_python
_ctf
_clock
_get
_uuid
_index
(self
._c
, i
)
1561 raise ValueError("Invalid clock instance")
1563 uuid_list
.append(value
)
1565 return UUID(bytes
=bytes(uuid_list
))
1568 def uuid(self
, uuid
):
1570 Set a clock's UUID (an object of type UUID).
1573 uuid_bytes
= uuid
.bytes
1575 if len(uuid_bytes
) != 16:
1576 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1578 for i
in range(len(uuid_bytes
)):
1579 ret
= nbt
._bt
_python
_ctf
_clock
_set
_uuid
_index
(self
._c
, i
,
1583 raise ValueError("Invalid clock instance")
1588 Get the current time in nanoseconds since the clock's origin (offset and
1589 offset_s attributes).
1592 time
= nbt
._bt
_ctf
_clock
_get
_time
(self
._c
)
1594 if time
== CTFWriter
._MAX
_UINT
64:
1595 raise ValueError("Invalid clock instance")
1600 def time(self
, time
):
1602 Set the current time in nanoseconds since the clock's origin (offset and
1603 offset_s attributes). The clock's value will be sampled as events are
1604 appended to a stream.
1607 ret
= nbt
._bt
_ctf
_clock
_set
_time
(self
._c
, time
)
1610 raise ValueError("Invalid time value.")
1612 class FieldDeclaration
:
1614 FieldDeclaration should not be instantiated directly. Instantiate
1615 one of the concrete FieldDeclaration classes.
1619 # These values are based on the bt_ctf_integer_base enum
1620 # declared in event-types.h.
1621 INTEGER_BASE_UNKNOWN
= -1
1622 INTEGER_BASE_BINARY
= 2
1623 INTEGER_BASE_OCTAL
= 8
1624 INTEGER_BASE_DECIMAL
= 10
1625 INTEGER_BASE_HEXADECIMAL
= 16
1628 if self
._ft
is None:
1629 raise ValueError("FieldDeclaration creation failed.")
1632 nbt
._bt
_ctf
_field
_type
_put
(self
._ft
)
1635 def _create_field_declaration_from_native_instance(
1636 native_field_declaration
):
1638 CTFTypeId
.INTEGER
: CTFWriter
.IntegerFieldDeclaration
,
1639 CTFTypeId
.FLOAT
: CTFWriter
.FloatFieldDeclaration
,
1640 CTFTypeId
.ENUM
: CTFWriter
.EnumerationFieldDeclaration
,
1641 CTFTypeId
.STRING
: CTFWriter
.StringFieldDeclaration
,
1642 CTFTypeId
.STRUCT
: CTFWriter
.StructureFieldDeclaration
,
1643 CTFTypeId
.VARIANT
: CTFWriter
.VariantFieldDeclaration
,
1644 CTFTypeId
.ARRAY
: CTFWriter
.ArrayFieldDeclaration
,
1645 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceFieldDeclaration
1648 field_type_id
= nbt
._bt
_ctf
_field
_type
_get
_type
_id
(native_field_declaration
)
1650 if field_type_id
== CTFTypeId
.UNKNOWN
:
1651 raise TypeError("Invalid field instance")
1653 declaration
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
1654 declaration
._ft
= native_field_declaration
1655 declaration
.__class
__ = type_dict
[field_type_id
]
1660 def alignment(self
):
1662 Get the field declaration's alignment. Returns -1 on error.
1665 return nbt
._bt
_ctf
_field
_type
_get
_alignment
(self
._ft
)
1668 def alignment(self
, alignment
):
1670 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1671 some types, such as structures and string, may impose other alignment
1675 ret
= nbt
._bt
_ctf
_field
_type
_set
_alignment
(self
._ft
, alignment
)
1678 raise ValueError("Invalid alignment value.")
1681 def byte_order(self
):
1683 Get the field declaration's byte order. One of the ByteOrder's constant.
1686 return nbt
._bt
_ctf
_field
_type
_get
_byte
_order
(self
._ft
)
1689 def byte_order(self
, byte_order
):
1691 Set the field declaration's byte order. Use constants defined in the ByteOrder
1695 ret
= nbt
._bt
_ctf
_field
_type
_set
_byte
_order
(self
._ft
, byte_order
)
1698 raise ValueError("Could not set byte order value.")
1700 class IntegerFieldDeclaration(FieldDeclaration
):
1701 def __init__(self
, size
):
1703 Create a new integer field declaration of the given size.
1705 self
._ft
= nbt
._bt
_ctf
_field
_type
_integer
_create
(size
)
1711 Get an integer's size.
1714 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_size
(self
._ft
)
1717 raise ValueError("Could not get Integer's size attribute.")
1724 Get an integer's signedness attribute.
1727 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_signed
(self
._ft
)
1730 raise ValueError("Could not get Integer's signed attribute.")
1737 def signed(self
, signed
):
1739 Set an integer's signedness attribute.
1742 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_signed
(self
._ft
, signed
)
1745 raise ValueError("Could not set Integer's signed attribute.")
1750 Get the integer's base used to pretty-print the resulting trace.
1751 Returns a constant from the FieldDeclaration.IntegerBase class.
1754 return nbt
._bt
_ctf
_field
_type
_integer
_get
_base
(self
._ft
)
1757 def base(self
, base
):
1759 Set the integer's base used to pretty-print the resulting trace.
1760 The base must be a constant of the FieldDeclarationIntegerBase class.
1763 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_base
(self
._ft
, base
)
1766 raise ValueError("Could not set Integer's base.")
1771 Get the integer's encoding (one of the constants of the
1772 CTFStringEncoding class).
1773 Returns a constant from the CTFStringEncoding class.
1776 return nbt
._bt
_ctf
_field
_type
_integer
_get
_encoding
(self
._ft
)
1779 def encoding(self
, encoding
):
1781 An integer encoding may be set to signal that the integer must be printed
1782 as a text character. Must be a constant from the CTFStringEncoding class.
1785 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_encoding
(self
._ft
, encoding
)
1788 raise ValueError("Could not set Integer's encoding.")
1790 class EnumerationFieldDeclaration(FieldDeclaration
):
1791 def __init__(self
, integer_type
):
1793 Create a new enumeration field declaration with the given underlying container type.
1795 isinst
= isinstance(integer_type
, CTFWriter
.IntegerFieldDeclaration
)
1797 if integer_type
is None or not isinst
:
1798 raise TypeError("Invalid integer container.")
1800 self
._ft
= nbt
._bt
_ctf
_field
_type
_enumeration
_create
(integer_type
._ft
)
1804 def container(self
):
1806 Get the enumeration's underlying container type.
1809 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_container
_type
(self
._ft
)
1812 raise TypeError("Invalid enumeration declaration")
1814 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1816 def add_mapping(self
, name
, range_start
, range_end
):
1818 Add a mapping to the enumeration. The range's values are inclusive.
1821 if range_start
< 0 or range_end
< 0:
1822 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
(self
._ft
,
1827 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
_unsigned
(self
._ft
,
1833 raise ValueError("Could not add mapping to enumeration declaration.")
1838 Generator returning instances of EnumerationMapping.
1841 signed
= self
.container
.signed
1843 count
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_count
(self
._ft
)
1845 for i
in range(count
):
1847 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, i
)
1849 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, i
)
1852 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1853 raise TypeError(msg
)
1855 name
, range_start
, range_end
= ret
1856 yield CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1858 def get_mapping_by_name(self
, name
):
1860 Get a mapping by name (EnumerationMapping).
1863 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_name
(self
._ft
, name
)
1868 if self
.container
.signed
:
1869 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1871 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1874 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1875 raise TypeError(msg
)
1877 name
, range_start
, range_end
= ret
1879 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1881 def get_mapping_by_value(self
, value
):
1883 Get a mapping by value (EnumerationMapping).
1887 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_value
(self
._ft
, value
)
1889 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_unsigned
_value
(self
._ft
, value
)
1894 if self
.container
.signed
:
1895 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1897 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1900 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1901 raise TypeError(msg
)
1903 name
, range_start
, range_end
= ret
1905 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1907 class FloatFieldDeclaration(FieldDeclaration
):
1915 Create a new floating point field declaration.
1918 self
._ft
= nbt
._bt
_ctf
_field
_type
_floating
_point
_create
()
1922 def exponent_digits(self
):
1924 Get the number of exponent digits used to store the floating point field.
1927 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_exponent
_digits
(self
._ft
)
1931 "Could not get Floating point exponent digit count")
1935 @exponent_digits.setter
1936 def exponent_digits(self
, exponent_digits
):
1938 Set the number of exponent digits to use to store the floating point field.
1939 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1940 are defined as constants of this class.
1943 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_exponent
_digits
(self
._ft
,
1947 raise ValueError("Could not set exponent digit count.")
1950 def mantissa_digits(self
):
1952 Get the number of mantissa digits used to store the floating point field.
1955 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_mantissa
_digits
(self
._ft
)
1958 raise TypeError("Could not get Floating point mantissa digit count")
1962 @mantissa_digits.setter
1963 def mantissa_digits(self
, mantissa_digits
):
1965 Set the number of mantissa digits to use to store the floating point field.
1966 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1967 are defined as constants of this class.
1970 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_mantissa
_digits
(self
._ft
,
1974 raise ValueError("Could not set mantissa digit count.")
1976 class FloatingPointFieldDeclaration(FloatFieldDeclaration
):
1979 class StructureFieldDeclaration(FieldDeclaration
):
1982 Create a new structure field declaration.
1985 self
._ft
= nbt
._bt
_ctf
_field
_type
_structure
_create
()
1988 def add_field(self
, field_type
, field_name
):
1990 Add a field of type "field_type" to the structure.
1993 ret
= nbt
._bt
_ctf
_field
_type
_structure
_add
_field
(self
._ft
,
1998 raise ValueError("Could not add field to structure.")
2003 Generator returning the structure's field as tuples of (field name, field declaration).
2006 count
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_count
(self
._ft
)
2009 raise TypeError("Could not get Structure field count")
2011 for i
in range(count
):
2012 field_name
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_name
(self
._ft
, i
)
2014 if field_name
is None:
2015 msg
= "Could not get Structure field name at index {}".format(i
)
2016 raise TypeError(msg
)
2018 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_type
(self
._ft
, i
)
2020 if field_type_native
is None:
2021 msg
= "Could not get Structure field type at index {}".format(i
)
2022 raise TypeError(msg
)
2024 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2025 yield (field_name
, field_type
)
2027 def get_field_by_name(self
, name
):
2029 Get a field declaration by name (FieldDeclaration).
2032 field_type_native
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_type
_by
_name
(self
._ft
, name
)
2034 if field_type_native
is None:
2035 msg
= "Could not find Structure field with name {}".format(name
)
2036 raise TypeError(msg
)
2038 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2040 class VariantFieldDeclaration(FieldDeclaration
):
2041 def __init__(self
, enum_tag
, tag_name
):
2043 Create a new variant field declaration.
2046 isinst
= isinstance(enum_tag
, CTFWriter
.EnumerationFieldDeclaration
)
2047 if enum_tag
is None or not isinst
:
2048 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
2050 self
._ft
= nbt
._bt
_ctf
_field
_type
_variant
_create
(enum_tag
._ft
,
2057 Get the variant's tag name.
2060 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_name
(self
._ft
)
2063 raise TypeError("Could not get Variant tag name")
2070 Get the variant's tag type.
2073 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_type
(self
._ft
)
2076 raise TypeError("Could not get Variant tag type")
2078 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2080 def add_field(self
, field_type
, field_name
):
2082 Add a field of type "field_type" to the variant.
2085 ret
= nbt
._bt
_ctf
_field
_type
_variant
_add
_field
(self
._ft
,
2090 raise ValueError("Could not add field to variant.")
2095 Generator returning the variant's field as tuples of (field name, field declaration).
2098 count
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_count
(self
._ft
)
2101 raise TypeError("Could not get Variant field count")
2103 for i
in range(count
):
2104 field_name
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_name
(self
._ft
, i
)
2106 if field_name
is None:
2107 msg
= "Could not get Variant field name at index {}".format(i
)
2108 raise TypeError(msg
)
2110 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_type
(self
._ft
, i
)
2112 if field_type_native
is None:
2113 msg
= "Could not get Variant field type at index {}".format(i
)
2114 raise TypeError(msg
)
2116 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2117 yield (field_name
, field_type
)
2119 def get_field_by_name(self
, name
):
2121 Get a field declaration by name (FieldDeclaration).
2124 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_by
_name
(self
._ft
,
2127 if field_type_native
is None:
2128 msg
= "Could not find Variant field with name {}".format(name
)
2129 raise TypeError(msg
)
2131 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2133 def get_field_from_tag(self
, tag
):
2135 Get a field declaration from tag (EnumerationField).
2138 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_from
_tag
(self
._ft
, tag
._f
)
2140 if field_type_native
is None:
2141 msg
= "Could not find Variant field with tag value {}".format(tag
.value
)
2142 raise TypeError(msg
)
2144 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2146 class ArrayFieldDeclaration(FieldDeclaration
):
2147 def __init__(self
, element_type
, length
):
2149 Create a new array field declaration.
2152 self
._ft
= nbt
._bt
_ctf
_field
_type
_array
_create
(element_type
._ft
,
2157 def element_type(self
):
2159 Get the array's element type.
2162 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_element
_type
(self
._ft
)
2165 raise TypeError("Could not get Array element type")
2167 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2172 Get the array's length.
2175 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_length
(self
._ft
)
2178 raise TypeError("Could not get Array length")
2182 class SequenceFieldDeclaration(FieldDeclaration
):
2183 def __init__(self
, element_type
, length_field_name
):
2185 Create a new sequence field declaration.
2188 self
._ft
= nbt
._bt
_ctf
_field
_type
_sequence
_create
(element_type
._ft
,
2189 str(length_field_name
))
2193 def element_type(self
):
2195 Get the sequence's element type.
2198 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_element
_type
(self
._ft
)
2201 raise TypeError("Could not get Sequence element type")
2203 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2206 def length_field_name(self
):
2208 Get the sequence's length field name.
2211 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_length
_field
_name
(self
._ft
)
2214 raise TypeError("Could not get Sequence length field name")
2218 class StringFieldDeclaration(FieldDeclaration
):
2221 Create a new string field declaration.
2224 self
._ft
= nbt
._bt
_ctf
_field
_type
_string
_create
()
2230 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
2233 return nbt
._bt
_ctf
_field
_type
_string
_get
_encoding
(self
._ft
)
2236 def encoding(self
, encoding
):
2238 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
2241 ret
= nbt
._bt
_ctf
_field
_type
_string
_set
_encoding
(self
._ft
, encoding
)
2243 raise ValueError("Could not set string encoding.")
2246 def create_field(field_type
):
2248 Create an instance of a field.
2250 isinst
= isinstance(field_type
, CTFWriter
.FieldDeclaration
)
2252 if field_type
is None or not isinst
:
2253 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
2255 if isinstance(field_type
, CTFWriter
.IntegerFieldDeclaration
):
2256 return CTFWriter
.IntegerField(field_type
)
2257 elif isinstance(field_type
, CTFWriter
.EnumerationFieldDeclaration
):
2258 return CTFWriter
.EnumerationField(field_type
)
2259 elif isinstance(field_type
, CTFWriter
.FloatFieldDeclaration
):
2260 return CTFWriter
.FloatingPointField(field_type
)
2261 elif isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2262 return CTFWriter
.StructureField(field_type
)
2263 elif isinstance(field_type
, CTFWriter
.VariantFieldDeclaration
):
2264 return CTFWriter
.VariantField(field_type
)
2265 elif isinstance(field_type
, CTFWriter
.ArrayFieldDeclaration
):
2266 return CTFWriter
.ArrayField(field_type
)
2267 elif isinstance(field_type
, CTFWriter
.SequenceFieldDeclaration
):
2268 return CTFWriter
.SequenceField(field_type
)
2269 elif isinstance(field_type
, CTFWriter
.StringFieldDeclaration
):
2270 return CTFWriter
.StringField(field_type
)
2274 Base class, do not instantiate.
2277 def __init__(self
, field_type
):
2278 if not isinstance(field_type
, CTFWriter
.FieldDeclaration
):
2279 raise TypeError("Invalid field_type argument.")
2281 self
._f
= nbt
._bt
_ctf
_field
_create
(field_type
._ft
)
2284 raise ValueError("Field creation failed.")
2287 nbt
._bt
_ctf
_field
_put
(self
._f
)
2290 def _create_field_from_native_instance(native_field_instance
):
2292 CTFTypeId
.INTEGER
: CTFWriter
.IntegerField
,
2293 CTFTypeId
.FLOAT
: CTFWriter
.FloatingPointField
,
2294 CTFTypeId
.ENUM
: CTFWriter
.EnumerationField
,
2295 CTFTypeId
.STRING
: CTFWriter
.StringField
,
2296 CTFTypeId
.STRUCT
: CTFWriter
.StructureField
,
2297 CTFTypeId
.VARIANT
: CTFWriter
.VariantField
,
2298 CTFTypeId
.ARRAY
: CTFWriter
.ArrayField
,
2299 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceField
2302 field_type
= nbt
._bt
_python
_get
_field
_type
(native_field_instance
)
2304 if field_type
== CTFTypeId
.UNKNOWN
:
2305 raise TypeError("Invalid field instance")
2307 field
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
2308 field
._f
= native_field_instance
2309 field
.__class
__ = type_dict
[field_type
]
2314 def declaration(self
):
2315 native_field_type
= nbt
._bt
_ctf
_field
_get
_type
(self
._f
)
2317 if native_field_type
is None:
2318 raise TypeError("Invalid field instance")
2319 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(
2322 class IntegerField(Field
):
2326 Get an integer field's value.
2329 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2332 raise TypeError("Invalid integer instance.")
2335 ret
, value
= nbt
._bt
_ctf
_field
_unsigned
_integer
_get
_value
(self
._f
)
2337 ret
, value
= nbt
._bt
_ctf
_field
_signed
_integer
_get
_value
(self
._f
)
2340 raise ValueError("Could not get integer field value.")
2345 def value(self
, value
):
2347 Set an integer field's value.
2350 if not isinstance(value
, int):
2351 raise TypeError("IntegerField's value must be an int")
2353 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2355 raise TypeError("Invalid integer instance.")
2358 ret
= nbt
._bt
_ctf
_field
_unsigned
_integer
_set
_value
(self
._f
, value
)
2360 ret
= nbt
._bt
_ctf
_field
_signed
_integer
_set
_value
(self
._f
, value
)
2363 raise ValueError("Could not set integer field value.")
2365 class EnumerationField(Field
):
2367 def container(self
):
2369 Return the enumeration's underlying container field (an integer field).
2372 container
= CTFWriter
.IntegerField
.__new
__(CTFWriter
.IntegerField
)
2373 container
._f
= nbt
._bt
_ctf
_field
_enumeration
_get
_container
(self
._f
)
2375 if container
._f
is None:
2376 raise TypeError("Invalid enumeration field type.")
2383 Get the enumeration field's mapping name.
2386 value
= nbt
._bt
_ctf
_field
_enumeration
_get
_mapping
_name
(self
._f
)
2389 raise ValueError("Could not get enumeration's mapping name.")
2394 def value(self
, value
):
2396 Set the enumeration field's value. Must be an integer as mapping names
2400 if not isinstance(value
, int):
2401 raise TypeError("EnumerationField value must be an int")
2403 self
.container
.value
= value
2405 class FloatingPointField(Field
):
2409 Get a floating point field's value.
2412 ret
, value
= nbt
._bt
_ctf
_field
_floating
_point
_get
_value
(self
._f
)
2415 raise ValueError("Could not get floating point field value.")
2420 def value(self
, value
):
2422 Set a floating point field's value.
2425 if not isinstance(value
, int) and not isinstance(value
, float):
2426 raise TypeError("Value must be either a float or an int")
2428 ret
= nbt
._bt
_ctf
_field
_floating
_point
_set
_value
(self
._f
, float(value
))
2431 raise ValueError("Could not set floating point field value.")
2433 # oops!! This class is provided to ensure backward-compatibility since
2434 # a stable release publicly exposed this abomination.
2435 class FloatFieldingPoint(FloatingPointField
):
2438 class StructureField(Field
):
2439 def field(self
, field_name
):
2441 Get the structure's field corresponding to the provided field name.
2444 native_instance
= nbt
._bt
_ctf
_field
_structure
_get
_field
(self
._f
,
2447 if native_instance
is None:
2448 raise ValueError("Invalid field_name provided.")
2450 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2452 class VariantField(Field
):
2453 def field(self
, tag
):
2455 Return the variant's selected field. The "tag" field is the selector enum field.
2458 native_instance
= nbt
._bt
_ctf
_field
_variant
_get
_field
(self
._f
, tag
._f
)
2460 if native_instance
is None:
2461 raise ValueError("Invalid tag provided.")
2463 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2465 class ArrayField(Field
):
2466 def field(self
, index
):
2468 Return the array's field at position "index".
2471 native_instance
= nbt
._bt
_ctf
_field
_array
_get
_field
(self
._f
, index
)
2473 if native_instance
is None:
2474 raise IndexError("Invalid index provided.")
2476 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2478 class SequenceField(Field
):
2482 Get the sequence's length field (IntegerField).
2485 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_length
(self
._f
)
2487 if native_instance
is None:
2490 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2493 def length(self
, length_field
):
2495 Set the sequence's length field (IntegerField).
2498 if not isinstance(length_field
, CTFWriter
.IntegerField
):
2499 raise TypeError("Invalid length field.")
2501 if length_field
.declaration
.signed
:
2502 raise TypeError("Sequence field length must be unsigned")
2504 ret
= nbt
._bt
_ctf
_field
_sequence
_set
_length
(self
._f
, length_field
._f
)
2507 raise ValueError("Could not set sequence length.")
2509 def field(self
, index
):
2511 Return the sequence's field at position "index".
2514 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_field
(self
._f
, index
)
2516 if native_instance
is None:
2517 raise ValueError("Could not get sequence element at index.")
2519 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2521 class StringField(Field
):
2525 Get a string field's value.
2528 return nbt
._bt
_ctf
_field
_string
_get
_value
(self
._f
)
2531 def value(self
, value
):
2533 Set a string field's value.
2536 ret
= nbt
._bt
_ctf
_field
_string
_set
_value
(self
._f
, str(value
))
2539 raise ValueError("Could not set string field value.")
2542 def __init__(self
, name
):
2544 Create a new event class of the given name.
2547 self
._ec
= nbt
._bt
_ctf
_event
_class
_create
(name
)
2549 if self
._ec
is None:
2550 raise ValueError("Event class creation failed.")
2553 nbt
._bt
_ctf
_event
_class
_put
(self
._ec
)
2555 def add_field(self
, field_type
, field_name
):
2557 Add a field of type "field_type" to the event class.
2560 ret
= nbt
._bt
_ctf
_event
_class
_add
_field
(self
._ec
, field_type
._ft
,
2564 raise ValueError("Could not add field to event class.")
2569 Get the event class' name.
2572 name
= nbt
._bt
_ctf
_event
_class
_get
_name
(self
._ec
)
2575 raise TypeError("Could not get EventClass name")
2582 Get the event class' id. Returns a negative value if unset.
2585 id = nbt
._bt
_ctf
_event
_class
_get
_id
(self
._ec
)
2588 raise TypeError("Could not get EventClass id")
2595 Set the event class' id. Throws a TypeError if the event class
2596 is already registered to a stream class.
2599 ret
= nbt
._bt
_ctf
_event
_class
_set
_id
(self
._ec
, id)
2602 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
2605 def stream_class(self
):
2607 Get the event class' stream class. Returns None if unset.
2609 stream_class_native
= nbt
._bt
_ctf
_event
_class
_get
_stream
_class
(self
._ec
)
2611 if stream_class_native
is None:
2614 stream_class
= CTFWriter
.StreamClass
.__new
__(CTFWriter
.StreamClass
)
2615 stream_class
._sc
= stream_class_native
2622 Generator returning the event class' fields as tuples of (field name, field declaration).
2625 count
= nbt
._bt
_ctf
_event
_class
_get
_field
_count
(self
._ec
)
2628 raise TypeError("Could not get EventClass' field count")
2630 for i
in range(count
):
2631 field_name
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_name
(self
._ec
, i
)
2633 if field_name
is None:
2634 msg
= "Could not get EventClass' field name at index {}".format(i
)
2635 raise TypeError(msg
)
2637 field_type_native
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_type
(self
._ec
, i
)
2639 if field_type_native
is None:
2640 msg
= "Could not get EventClass' field type at index {}".format(i
)
2641 raise TypeError(msg
)
2643 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2644 yield (field_name
, field_type
)
2646 def get_field_by_name(self
, name
):
2648 Get a field declaration by name (FieldDeclaration).
2651 field_type_native
= nbt
._bt
_ctf
_event
_class
_get
_field
_by
_name
(self
._ec
, name
)
2653 if field_type_native
is None:
2654 msg
= "Could not find EventClass field with name {}".format(name
)
2655 raise TypeError(msg
)
2657 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2660 def __init__(self
, event_class
):
2662 Create a new event of the given event class.
2665 if not isinstance(event_class
, CTFWriter
.EventClass
):
2666 raise TypeError("Invalid event_class argument.")
2668 self
._e
= nbt
._bt
_ctf
_event
_create
(event_class
._ec
)
2671 raise ValueError("Event creation failed.")
2674 nbt
._bt
_ctf
_event
_put
(self
._e
)
2677 def event_class(self
):
2679 Get the event's class.
2682 event_class_native
= nbt
._bt
_ctf
_event
_get
_class
(self
._e
)
2684 if event_class_native
is None:
2687 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2688 event_class
._ec
= event_class_native
2694 Get a clock from event. Returns None if the event's class
2695 is not registered to a stream class.
2698 clock_instance
= nbt
._bt
_ctf
_event
_get
_clock
(self
._e
)
2700 if clock_instance
is None:
2703 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2704 clock
._c
= clock_instance
2708 def payload(self
, field_name
):
2710 Get a field from event.
2713 native_instance
= nbt
._bt
_ctf
_event
_get
_payload
(self
._e
,
2716 if native_instance
is None:
2717 raise ValueError("Could not get event payload.")
2719 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2721 def set_payload(self
, field_name
, value_field
):
2723 Set a manually created field as an event's payload.
2726 if not isinstance(value
, CTFWriter
.Field
):
2727 raise TypeError("Invalid value type.")
2729 ret
= nbt
._bt
_ctf
_event
_set
_payload
(self
._e
, str(field_name
),
2733 raise ValueError("Could not set event field payload.")
2736 def __init__(self
, name
):
2738 Create a new stream class of the given name.
2741 self
._sc
= nbt
._bt
_ctf
_stream
_class
_create
(name
)
2743 if self
._sc
is None:
2744 raise ValueError("Stream class creation failed.")
2747 nbt
._bt
_ctf
_stream
_class
_put
(self
._sc
)
2752 Get a stream class' name.
2755 name
= nbt
._bt
_ctf
_stream
_class
_get
_name
(self
._sc
)
2758 raise TypeError("Could not get StreamClass name")
2765 Get a stream class' clock.
2768 clock_instance
= nbt
._bt
_ctf
_stream
_class
_get
_clock
(self
._sc
)
2770 if clock_instance
is None:
2773 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2774 clock
._c
= clock_instance
2779 def clock(self
, clock
):
2781 Assign a clock to a stream class.
2784 if not isinstance(clock
, CTFWriter
.Clock
):
2785 raise TypeError("Invalid clock type.")
2787 ret
= nbt
._bt
_ctf
_stream
_class
_set
_clock
(self
._sc
, clock
._c
)
2790 raise ValueError("Could not set stream class clock.")
2795 Get a stream class' id.
2798 ret
= nbt
._bt
_ctf
_stream
_class
_get
_id
(self
._sc
)
2801 raise TypeError("Could not get StreamClass id")
2808 Assign an id to a stream class.
2811 ret
= nbt
._bt
_ctf
_stream
_class
_set
_id
(self
._sc
, id)
2814 raise TypeError("Could not set stream class id.")
2817 def event_classes(self
):
2819 Generator returning the stream class' event classes.
2822 count
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
_count
(self
._sc
)
2825 raise TypeError("Could not get StreamClass' event class count")
2827 for i
in range(count
):
2828 event_class_native
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
(self
._sc
, i
)
2830 if event_class_native
is None:
2831 msg
= "Could not get StreamClass' event class at index {}".format(i
)
2832 raise TypeError(msg
)
2834 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2835 event_class
._ec
= event_class_native
2838 def add_event_class(self
, event_class
):
2840 Add an event class to a stream class. New events can be added even after a
2841 stream has been instantiated and events have been appended. However, a stream
2842 will not accept events of a class that has not been added to the stream
2846 if not isinstance(event_class
, CTFWriter
.EventClass
):
2847 raise TypeError("Invalid event_class type.")
2849 ret
= nbt
._bt
_ctf
_stream
_class
_add
_event
_class
(self
._sc
,
2853 raise ValueError("Could not add event class.")
2856 def packet_context_type(self
):
2858 Get the StreamClass' packet context type (StructureFieldDeclaration)
2861 field_type_native
= nbt
._bt
_ctf
_stream
_class
_get
_packet
_context
_type
(self
._sc
)
2863 if field_type_native
is None:
2864 raise ValueError("Invalid StreamClass")
2866 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2870 @packet_context_type.setter
2871 def packet_context_type(self
, field_type
):
2873 Set a StreamClass' packet context type. Must be of type
2874 StructureFieldDeclaration.
2877 if not isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2878 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2880 ret
= nbt
._bt
_ctf
_stream
_class
_set
_packet
_context
_type
(self
._sc
,
2884 raise ValueError("Failed to set packet context type.")
2888 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
2891 nbt
._bt
_ctf
_stream
_put
(self
._s
)
2894 def discarded_events(self
):
2896 Get a stream's discarded event count.
2899 ret
, count
= nbt
._bt
_ctf
_stream
_get
_discarded
_events
_count
(self
._s
)
2902 raise ValueError("Could not get the stream's discarded events count")
2906 def append_discarded_events(self
, event_count
):
2908 Increase the current packet's discarded event count.
2911 nbt
._bt
_ctf
_stream
_append
_discarded
_events
(self
._s
, event_count
)
2913 def append_event(self
, event
):
2915 Append "event" to the stream's current packet. The stream's associated clock
2916 will be sampled during this call. The event shall not be modified after
2917 being appended to a stream.
2920 ret
= nbt
._bt
_ctf
_stream
_append
_event
(self
._s
, event
._e
)
2923 raise ValueError("Could not append event to stream.")
2926 def packet_context(self
):
2928 Get a Stream's packet context field (a StructureField).
2931 native_field
= nbt
._bt
_ctf
_stream
_get
_packet
_context
(self
._s
)
2933 if native_field
is None:
2934 raise ValueError("Invalid Stream.")
2936 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_field
)
2938 @packet_context.setter
2939 def packet_context(self
, field
):
2941 Set a Stream's packet context field (must be a StructureField).
2944 if not isinstance(field
, CTFWriter
.StructureField
):
2945 raise TypeError("Argument field must be of type StructureField")
2947 ret
= nbt
._bt
_ctf
_stream
_set
_packet
_context
(self
._s
, field
._f
)
2950 raise ValueError("Invalid packet context field.")
2954 The stream's current packet's events will be flushed to disk. Events
2955 subsequently appended to the stream will be added to a new packet.
2958 ret
= nbt
._bt
_ctf
_stream
_flush
(self
._s
)
2961 raise ValueError("Could not flush stream.")
2964 def __init__(self
, path
):
2966 Create a new writer that will produce a trace in the given path.
2969 self
._w
= nbt
._bt
_ctf
_writer
_create
(path
)
2972 raise ValueError("Writer creation failed.")
2975 nbt
._bt
_ctf
_writer
_put
(self
._w
)
2977 def create_stream(self
, stream_class
):
2979 Create a new stream instance and register it to the writer.
2982 if not isinstance(stream_class
, CTFWriter
.StreamClass
):
2983 raise TypeError("Invalid stream_class type.")
2985 stream
= CTFWriter
.Stream
.__new
__(CTFWriter
.Stream
)
2986 stream
._s
= nbt
._bt
_ctf
_writer
_create
_stream
(self
._w
, stream_class
._sc
)
2990 def add_environment_field(self
, name
, value
):
2992 Add an environment field to the trace.
2995 ret
= nbt
._bt
_ctf
_writer
_add
_environment
_field
(self
._w
, str(name
),
2999 raise ValueError("Could not add environment field to trace.")
3001 def add_clock(self
, clock
):
3003 Add a clock to the trace. Clocks assigned to stream classes must be
3004 registered to the writer.
3007 ret
= nbt
._bt
_ctf
_writer
_add
_clock
(self
._w
, clock
._c
)
3010 raise ValueError("Could not add clock to Writer.")
3015 Get the trace's TSDL meta-data.
3018 return nbt
._bt
_ctf
_writer
_get
_metadata
_string
(self
._w
)
3020 def flush_metadata(self
):
3022 Flush the trace's metadata to the metadata file.
3025 nbt
._bt
_ctf
_writer
_flush
_metadata
(self
._w
)
3028 def byte_order(self
):
3030 Get the trace's byte order. Must be a constant from the ByteOrder
3034 raise NotImplementedError("Getter not implemented.")
3037 def byte_order(self
, byte_order
):
3039 Set the trace's byte order. Must be a constant from the ByteOrder
3040 class. Defaults to the host machine's endianness
3043 ret
= nbt
._bt
_ctf
_writer
_set
_byte
_order
(self
._w
, byte_order
)
3046 raise ValueError("Could not set trace's byte order.")