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
):
1019 """Do not instantiate."""
1022 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
1025 def element_declaration(self
):
1027 Return element declaration.
1030 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
1032 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1035 class FloatFieldDeclaration(FieldDeclaration
):
1036 """Do not instantiate."""
1039 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
1042 class StructureFieldDeclaration(FieldDeclaration
):
1043 """Do not instantiate."""
1046 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
1049 class StringFieldDeclaration(FieldDeclaration
):
1050 """Do not instantiate."""
1053 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
1056 class VariantFieldDeclaration(FieldDeclaration
):
1057 """Do not instantiate."""
1060 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
1065 Return the last error code encountered while
1066 accessing a field and reset the error flag.
1067 Return 0 if no error, a negative value otherwise.
1070 return nbt
._bt
_ctf
_field
_get
_error
()
1073 def _create_field_declaration(declaration_ptr
, name
, scope
):
1075 Private field declaration factory.
1078 if declaration_ptr
is None:
1079 raise ValueError("declaration_ptr must be valid")
1080 if scope
not in _scopes
:
1081 raise ValueError("Invalid scope provided")
1083 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
1086 if type == CTFTypeId
.INTEGER
:
1087 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
1088 elif type == CTFTypeId
.ENUM
:
1089 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
1090 elif type == CTFTypeId
.ARRAY
:
1091 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
1092 elif type == CTFTypeId
.SEQUENCE
:
1093 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
1094 elif type == CTFTypeId
.FLOAT
:
1095 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
1096 elif type == CTFTypeId
.STRUCT
:
1097 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
1098 elif type == CTFTypeId
.STRING
:
1099 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
1100 elif type == CTFTypeId
.VARIANT
:
1101 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
1105 declaration
._fd
= declaration_ptr
1106 declaration
._s
= scope
1107 declaration
._name
= name
1113 def __init__(self
, definition_ptr
, scope
):
1114 self
._d
= definition_ptr
1117 if scope
not in _scopes
:
1118 ValueError("Invalid scope provided")
1122 """Return the name of a field or None on error."""
1124 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1128 """Return the type of a field or -1 if unknown."""
1130 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1133 def declaration(self
):
1134 """Return the associated Definition object."""
1136 return _create_field_declaration(
1137 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1139 def _get_enum_str(self
):
1141 Return the string matching the current enumeration.
1142 Return None on error.
1145 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1147 def _get_array_element_at(self
, index
):
1149 Return the array's element at position index.
1150 Return None on error
1153 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1155 if array_ptr
is None:
1158 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1160 if definition_ptr
is None:
1163 return _Definition(definition_ptr
, self
.scope
)
1165 def _get_sequence_len(self
):
1167 Return the len of a sequence or a negative
1171 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1173 return nbt
._bt
_sequence
_len
(seq
)
1175 def _get_sequence_element_at(self
, index
):
1177 Return the sequence's element at position index,
1178 otherwise return None
1181 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1184 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1186 if definition_ptr
is not None:
1187 return _Definition(definition_ptr
, self
.scope
)
1189 def _get_uint64(self
):
1191 Return the value associated with the field.
1192 If the field does not exist or is not of the type requested,
1193 the value returned is undefined. To check if an error occured,
1194 use the field_error() function after accessing a field.
1197 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1199 def _get_int64(self
):
1201 Return the value associated with the field.
1202 If the field does not exist or is not of the type requested,
1203 the value returned is undefined. To check if an error occured,
1204 use the field_error() function after accessing a field.
1207 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1209 def _get_char_array(self
):
1211 Return the value associated with the field.
1212 If the field does not exist or is not of the type requested,
1213 the value returned is undefined. To check if an error occurred,
1214 use the field_error() function after accessing a field.
1217 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1221 Return the value associated with the field.
1222 If the field does not exist or is not of the type requested,
1223 the value returned is undefined. To check if an error occurred,
1224 use the field_error() function after accessing a field.
1227 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1229 def _get_float(self
):
1231 Return the value associated with the field.
1232 If the field does not exist or is not of the type requested,
1233 the value returned is undefined. To check if an error occurred,
1234 use the field_error() function after accessing a field.
1237 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1239 def _get_variant(self
):
1241 Return the variant's selected field.
1242 If the field does not exist or is not of the type requested,
1243 the value returned is undefined. To check if an error occurred,
1244 use the field_error() function after accessing a field.
1247 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1249 def _get_struct_field_count(self
):
1251 Return the number of fields contained in the structure.
1252 If the field does not exist or is not of the type requested,
1253 the value returned is undefined.
1256 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1258 def _get_struct_field_at(self
, i
):
1260 Return the structure's field at position i.
1261 If the field does not exist or is not of the type requested,
1262 the value returned is undefined. To check if an error occurred,
1263 use the field_error() function after accessing a field.
1266 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1271 Return the value associated with the field according to its type.
1272 Return None on error.
1278 if id == CTFTypeId
.STRING
:
1279 value
= self
._get
_str
()
1280 elif id == CTFTypeId
.ARRAY
:
1281 element_decl
= self
.declaration
.element_declaration
1283 if ((element_decl
.type == CTFTypeId
.INTEGER
1284 and element_decl
.length
== 8)
1285 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1286 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1290 for i
in range(self
.declaration
.length
):
1291 element
= self
._get
_array
_element
_at
(i
)
1292 value
.append(element
.value
)
1293 elif id == CTFTypeId
.INTEGER
:
1294 if self
.declaration
.signedness
== 0:
1295 value
= self
._get
_uint
64()
1297 value
= self
._get
_int
64()
1298 elif id == CTFTypeId
.ENUM
:
1299 value
= self
._get
_enum
_str
()
1300 elif id == CTFTypeId
.SEQUENCE
:
1301 element_decl
= self
.declaration
.element_declaration
1303 if ((element_decl
.type == CTFTypeId
.INTEGER
1304 and element_decl
.length
== 8)
1305 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1306 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1308 seq_len
= self
._get
_sequence
_len
()
1311 for i
in range(seq_len
):
1312 evDef
= self
._get
_sequence
_element
_at
(i
)
1313 value
.append(evDef
.value
)
1314 elif id == CTFTypeId
.FLOAT
:
1315 value
= self
._get
_float
()
1316 elif id == CTFTypeId
.VARIANT
:
1317 variant
= _Definition
.__new
__(_Definition
)
1318 variant
._d
= self
._get
_variant
()
1319 value
= variant
.value
1320 elif id == CTFTypeId
.STRUCT
:
1323 for i
in range(self
._get
_struct
_field
_count
()):
1324 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1325 value
[member
.name
] = member
.value
1329 "Error occurred while accessing field {} of type {}".format(
1331 CTFTypeId
.type_name(id)))
1337 """Return the scope of a field or None on error."""
1343 # Used to compare to -1ULL in error checks
1344 _MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
1346 class EnumerationMapping
:
1348 Enumeration mapping class. start and end values are inclusive.
1351 def __init__(self
, name
, start
, end
):
1357 def __init__(self
, name
):
1358 self
._c
= nbt
._bt
_ctf
_clock
_create
(name
)
1361 raise ValueError("Invalid clock name.")
1364 nbt
._bt
_ctf
_clock
_put
(self
._c
)
1369 Get the clock's name.
1372 name
= nbt
._bt
_ctf
_clock
_get
_name
(self
._c
)
1375 raise ValueError("Invalid clock instance.")
1380 def description(self
):
1382 Get the clock's description. None if unset.
1385 return nbt
._bt
_ctf
_clock
_get
_description
(self
._c
)
1388 def description(self
, desc
):
1390 Set the clock's description. The description appears in the clock's TSDL
1394 ret
= nbt
._bt
_ctf
_clock
_set
_description
(self
._c
, str(desc
))
1397 raise ValueError("Invalid clock description.")
1400 def frequency(self
):
1402 Get the clock's frequency (Hz).
1405 freq
= nbt
._bt
_ctf
_clock
_get
_frequency
(self
._c
)
1407 if freq
== CTFWriter
._MAX
_UINT
64:
1408 raise ValueError("Invalid clock instance")
1413 def frequency(self
, freq
):
1415 Set the clock's frequency (Hz).
1418 ret
= nbt
._bt
_ctf
_clock
_set
_frequency
(self
._c
, freq
)
1421 raise ValueError("Invalid frequency value.")
1424 def precision(self
):
1426 Get the clock's precision (in clock ticks).
1429 precision
= nbt
._bt
_ctf
_clock
_get
_precision
(self
._c
)
1431 if precision
== CTFWriter
._MAX
_UINT
64:
1432 raise ValueError("Invalid clock instance")
1437 def precision(self
, precision
):
1439 Set the clock's precision (in clock ticks).
1442 ret
= nbt
._bt
_ctf
_clock
_set
_precision
(self
._c
, precision
)
1445 def offset_seconds(self
):
1447 Get the clock's offset in seconds from POSIX.1 Epoch.
1450 offset_s
= nbt
._bt
_ctf
_clock
_get
_offset
_s
(self
._c
)
1452 if offset_s
== CTFWriter
._MAX
_UINT
64:
1453 raise ValueError("Invalid clock instance")
1457 @offset_seconds.setter
1458 def offset_seconds(self
, offset_s
):
1460 Set the clock's offset in seconds from POSIX.1 Epoch.
1463 ret
= nbt
._bt
_ctf
_clock
_set
_offset
_s
(self
._c
, offset_s
)
1466 raise ValueError("Invalid offset value.")
1471 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1474 offset
= nbt
._bt
_ctf
_clock
_get
_offset
(self
._c
)
1476 if offset
== CTFWriter
._MAX
_UINT
64:
1477 raise ValueError("Invalid clock instance")
1482 def offset(self
, offset
):
1484 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1487 ret
= nbt
._bt
_ctf
_clock
_set
_offset
(self
._c
, offset
)
1490 raise ValueError("Invalid offset value.")
1495 Get a clock's absolute attribute. A clock is absolute if the clock
1496 is a global reference across the trace's other clocks.
1499 is_absolute
= nbt
._bt
_ctf
_clock
_get
_is
_absolute
(self
._c
)
1501 if is_absolute
== -1:
1502 raise ValueError("Invalid clock instance")
1504 return False if is_absolute
== 0 else True
1507 def absolute(self
, is_absolute
):
1509 Set a clock's absolute attribute. A clock is absolute if the clock
1510 is a global reference across the trace's other clocks.
1513 ret
= nbt
._bt
_ctf
_clock
_set
_is
_absolute
(self
._c
, int(is_absolute
))
1516 raise ValueError("Could not set the clock's absolute attribute.")
1521 Get a clock's UUID (an object of type UUID).
1527 ret
, value
= nbt
._bt
_python
_ctf
_clock
_get
_uuid
_index
(self
._c
, i
)
1530 raise ValueError("Invalid clock instance")
1532 uuid_list
.append(value
)
1534 return UUID(bytes
=bytes(uuid_list
))
1537 def uuid(self
, uuid
):
1539 Set a clock's UUID (an object of type UUID).
1542 uuid_bytes
= uuid
.bytes
1544 if len(uuid_bytes
) != 16:
1545 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1547 for i
in range(len(uuid_bytes
)):
1548 ret
= nbt
._bt
_python
_ctf
_clock
_set
_uuid
_index
(self
._c
, i
,
1552 raise ValueError("Invalid clock instance")
1557 Get the current time in nanoseconds since the clock's origin (offset and
1558 offset_s attributes).
1561 time
= nbt
._bt
_ctf
_clock
_get
_time
(self
._c
)
1563 if time
== CTFWriter
._MAX
_UINT
64:
1564 raise ValueError("Invalid clock instance")
1569 def time(self
, time
):
1571 Set the current time in nanoseconds since the clock's origin (offset and
1572 offset_s attributes). The clock's value will be sampled as events are
1573 appended to a stream.
1576 ret
= nbt
._bt
_ctf
_clock
_set
_time
(self
._c
, time
)
1579 raise ValueError("Invalid time value.")
1581 class FieldDeclaration
:
1583 FieldDeclaration should not be instantiated directly. Instantiate
1584 one of the concrete FieldDeclaration classes.
1588 # These values are based on the bt_ctf_integer_base enum
1589 # declared in event-types.h.
1590 INTEGER_BASE_UNKNOWN
= -1
1591 INTEGER_BASE_BINARY
= 2
1592 INTEGER_BASE_OCTAL
= 8
1593 INTEGER_BASE_DECIMAL
= 10
1594 INTEGER_BASE_HEXADECIMAL
= 16
1597 if self
._ft
is None:
1598 raise ValueError("FieldDeclaration creation failed.")
1601 nbt
._bt
_ctf
_field
_type
_put
(self
._ft
)
1604 def _create_field_declaration_from_native_instance(
1605 native_field_declaration
):
1607 CTFTypeId
.INTEGER
: CTFWriter
.IntegerFieldDeclaration
,
1608 CTFTypeId
.FLOAT
: CTFWriter
.FloatFieldDeclaration
,
1609 CTFTypeId
.ENUM
: CTFWriter
.EnumerationFieldDeclaration
,
1610 CTFTypeId
.STRING
: CTFWriter
.StringFieldDeclaration
,
1611 CTFTypeId
.STRUCT
: CTFWriter
.StructureFieldDeclaration
,
1612 CTFTypeId
.VARIANT
: CTFWriter
.VariantFieldDeclaration
,
1613 CTFTypeId
.ARRAY
: CTFWriter
.ArrayFieldDeclaration
,
1614 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceFieldDeclaration
1617 field_type_id
= nbt
._bt
_ctf
_field
_type
_get
_type
_id
(native_field_declaration
)
1619 if field_type_id
== CTFTypeId
.UNKNOWN
:
1620 raise TypeError("Invalid field instance")
1622 declaration
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
1623 declaration
._ft
= native_field_declaration
1624 declaration
.__class
__ = type_dict
[field_type_id
]
1629 def alignment(self
):
1631 Get the field declaration's alignment. Returns -1 on error.
1634 return nbt
._bt
_ctf
_field
_type
_get
_alignment
(self
._ft
)
1637 def alignment(self
, alignment
):
1639 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1640 some types, such as structures and string, may impose other alignment
1644 ret
= nbt
._bt
_ctf
_field
_type
_set
_alignment
(self
._ft
, alignment
)
1647 raise ValueError("Invalid alignment value.")
1650 def byte_order(self
):
1652 Get the field declaration's byte order. One of the ByteOrder's constant.
1655 return nbt
._bt
_ctf
_field
_type
_get
_byte
_order
(self
._ft
)
1658 def byte_order(self
, byte_order
):
1660 Set the field declaration's byte order. Use constants defined in the ByteOrder
1664 ret
= nbt
._bt
_ctf
_field
_type
_set
_byte
_order
(self
._ft
, byte_order
)
1667 raise ValueError("Could not set byte order value.")
1669 class IntegerFieldDeclaration(FieldDeclaration
):
1670 def __init__(self
, size
):
1672 Create a new integer field declaration of the given size.
1674 self
._ft
= nbt
._bt
_ctf
_field
_type
_integer
_create
(size
)
1680 Get an integer's size.
1683 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_size
(self
._ft
)
1686 raise ValueError("Could not get Integer's size attribute.")
1693 Get an integer's signedness attribute.
1696 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_signed
(self
._ft
)
1699 raise ValueError("Could not get Integer's signed attribute.")
1706 def signed(self
, signed
):
1708 Set an integer's signedness attribute.
1711 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_signed
(self
._ft
, signed
)
1714 raise ValueError("Could not set Integer's signed attribute.")
1719 Get the integer's base used to pretty-print the resulting trace.
1720 Returns a constant from the FieldDeclaration.IntegerBase class.
1723 return nbt
._bt
_ctf
_field
_type
_integer
_get
_base
(self
._ft
)
1726 def base(self
, base
):
1728 Set the integer's base used to pretty-print the resulting trace.
1729 The base must be a constant of the FieldDeclarationIntegerBase class.
1732 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_base
(self
._ft
, base
)
1735 raise ValueError("Could not set Integer's base.")
1740 Get the integer's encoding (one of the constants of the
1741 CTFStringEncoding class).
1742 Returns a constant from the CTFStringEncoding class.
1745 return nbt
._bt
_ctf
_field
_type
_integer
_get
_encoding
(self
._ft
)
1748 def encoding(self
, encoding
):
1750 An integer encoding may be set to signal that the integer must be printed
1751 as a text character. Must be a constant from the CTFStringEncoding class.
1754 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_encoding
(self
._ft
, encoding
)
1757 raise ValueError("Could not set Integer's encoding.")
1759 class EnumerationFieldDeclaration(FieldDeclaration
):
1760 def __init__(self
, integer_type
):
1762 Create a new enumeration field declaration with the given underlying container type.
1764 isinst
= isinstance(integer_type
, CTFWriter
.IntegerFieldDeclaration
)
1766 if integer_type
is None or not isinst
:
1767 raise TypeError("Invalid integer container.")
1769 self
._ft
= nbt
._bt
_ctf
_field
_type
_enumeration
_create
(integer_type
._ft
)
1773 def container(self
):
1775 Get the enumeration's underlying container type.
1778 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_container
_type
(self
._ft
)
1781 raise TypeError("Invalid enumeration declaration")
1783 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1785 def add_mapping(self
, name
, range_start
, range_end
):
1787 Add a mapping to the enumeration. The range's values are inclusive.
1790 if range_start
< 0 or range_end
< 0:
1791 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
(self
._ft
,
1796 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
_unsigned
(self
._ft
,
1802 raise ValueError("Could not add mapping to enumeration declaration.")
1807 Generator returning instances of EnumerationMapping.
1810 signed
= self
.container
.signed
1812 count
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_count
(self
._ft
)
1814 for i
in range(count
):
1816 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, i
)
1818 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, i
)
1821 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1822 raise TypeError(msg
)
1824 name
, range_start
, range_end
= ret
1825 yield CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1827 def get_mapping_by_name(self
, name
):
1829 Get a mapping by name (EnumerationMapping).
1832 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_name
(self
._ft
, name
)
1837 if self
.container
.signed
:
1838 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1840 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1843 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1844 raise TypeError(msg
)
1846 name
, range_start
, range_end
= ret
1848 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1850 def get_mapping_by_value(self
, value
):
1852 Get a mapping by value (EnumerationMapping).
1856 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_value
(self
._ft
, value
)
1858 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_unsigned
_value
(self
._ft
, value
)
1863 if self
.container
.signed
:
1864 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1866 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1869 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1870 raise TypeError(msg
)
1872 name
, range_start
, range_end
= ret
1874 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1876 class FloatFieldDeclaration(FieldDeclaration
):
1884 Create a new floating point field declaration.
1887 self
._ft
= nbt
._bt
_ctf
_field
_type
_floating
_point
_create
()
1891 def exponent_digits(self
):
1893 Get the number of exponent digits used to store the floating point field.
1896 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_exponent
_digits
(self
._ft
)
1900 "Could not get Floating point exponent digit count")
1904 @exponent_digits.setter
1905 def exponent_digits(self
, exponent_digits
):
1907 Set the number of exponent digits to use to store the floating point field.
1908 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1909 are defined as constants of this class.
1912 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_exponent
_digits
(self
._ft
,
1916 raise ValueError("Could not set exponent digit count.")
1919 def mantissa_digits(self
):
1921 Get the number of mantissa digits used to store the floating point field.
1924 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_mantissa
_digits
(self
._ft
)
1927 raise TypeError("Could not get Floating point mantissa digit count")
1931 @mantissa_digits.setter
1932 def mantissa_digits(self
, mantissa_digits
):
1934 Set the number of mantissa digits to use to store the floating point field.
1935 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1936 are defined as constants of this class.
1939 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_mantissa
_digits
(self
._ft
,
1943 raise ValueError("Could not set mantissa digit count.")
1945 class FloatingPointFieldDeclaration(FloatFieldDeclaration
):
1948 class StructureFieldDeclaration(FieldDeclaration
):
1951 Create a new structure field declaration.
1954 self
._ft
= nbt
._bt
_ctf
_field
_type
_structure
_create
()
1957 def add_field(self
, field_type
, field_name
):
1959 Add a field of type "field_type" to the structure.
1962 ret
= nbt
._bt
_ctf
_field
_type
_structure
_add
_field
(self
._ft
,
1967 raise ValueError("Could not add field to structure.")
1972 Generator returning the structure's field as tuples of (field name, field declaration).
1975 count
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_count
(self
._ft
)
1978 raise TypeError("Could not get Structure field count")
1980 for i
in range(count
):
1981 field_name
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_name
(self
._ft
, i
)
1983 if field_name
is None:
1984 msg
= "Could not get Structure field name at index {}".format(i
)
1985 raise TypeError(msg
)
1987 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_type
(self
._ft
, i
)
1989 if field_type_native
is None:
1990 msg
= "Could not get Structure field type at index {}".format(i
)
1991 raise TypeError(msg
)
1993 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1994 yield (field_name
, field_type
)
1996 def get_field_by_name(self
, name
):
1998 Get a field declaration by name (FieldDeclaration).
2001 field_type_native
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_type
_by
_name
(self
._ft
, name
)
2003 if field_type_native
is None:
2004 msg
= "Could not find Structure field with name {}".format(name
)
2005 raise TypeError(msg
)
2007 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2009 class VariantFieldDeclaration(FieldDeclaration
):
2010 def __init__(self
, enum_tag
, tag_name
):
2012 Create a new variant field declaration.
2015 isinst
= isinstance(enum_tag
, CTFWriter
.EnumerationFieldDeclaration
)
2016 if enum_tag
is None or not isinst
:
2017 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
2019 self
._ft
= nbt
._bt
_ctf
_field
_type
_variant
_create
(enum_tag
._ft
,
2026 Get the variant's tag name.
2029 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_name
(self
._ft
)
2032 raise TypeError("Could not get Variant tag name")
2039 Get the variant's tag type.
2042 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_type
(self
._ft
)
2045 raise TypeError("Could not get Variant tag type")
2047 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2049 def add_field(self
, field_type
, field_name
):
2051 Add a field of type "field_type" to the variant.
2054 ret
= nbt
._bt
_ctf
_field
_type
_variant
_add
_field
(self
._ft
,
2059 raise ValueError("Could not add field to variant.")
2064 Generator returning the variant's field as tuples of (field name, field declaration).
2067 count
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_count
(self
._ft
)
2070 raise TypeError("Could not get Variant field count")
2072 for i
in range(count
):
2073 field_name
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_name
(self
._ft
, i
)
2075 if field_name
is None:
2076 msg
= "Could not get Variant field name at index {}".format(i
)
2077 raise TypeError(msg
)
2079 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_type
(self
._ft
, i
)
2081 if field_type_native
is None:
2082 msg
= "Could not get Variant field type at index {}".format(i
)
2083 raise TypeError(msg
)
2085 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2086 yield (field_name
, field_type
)
2088 def get_field_by_name(self
, name
):
2090 Get a field declaration by name (FieldDeclaration).
2093 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_by
_name
(self
._ft
,
2096 if field_type_native
is None:
2097 msg
= "Could not find Variant field with name {}".format(name
)
2098 raise TypeError(msg
)
2100 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2102 def get_field_from_tag(self
, tag
):
2104 Get a field declaration from tag (EnumerationField).
2107 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_from
_tag
(self
._ft
, tag
._f
)
2109 if field_type_native
is None:
2110 msg
= "Could not find Variant field with tag value {}".format(tag
.value
)
2111 raise TypeError(msg
)
2113 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2115 class ArrayFieldDeclaration(FieldDeclaration
):
2116 def __init__(self
, element_type
, length
):
2118 Create a new array field declaration.
2121 self
._ft
= nbt
._bt
_ctf
_field
_type
_array
_create
(element_type
._ft
,
2126 def element_type(self
):
2128 Get the array's element type.
2131 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_element
_type
(self
._ft
)
2134 raise TypeError("Could not get Array element type")
2136 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2141 Get the array's length.
2144 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_length
(self
._ft
)
2147 raise TypeError("Could not get Array length")
2151 class SequenceFieldDeclaration(FieldDeclaration
):
2152 def __init__(self
, element_type
, length_field_name
):
2154 Create a new sequence field declaration.
2157 self
._ft
= nbt
._bt
_ctf
_field
_type
_sequence
_create
(element_type
._ft
,
2158 str(length_field_name
))
2162 def element_type(self
):
2164 Get the sequence's element type.
2167 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_element
_type
(self
._ft
)
2170 raise TypeError("Could not get Sequence element type")
2172 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2175 def length_field_name(self
):
2177 Get the sequence's length field name.
2180 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_length
_field
_name
(self
._ft
)
2183 raise TypeError("Could not get Sequence length field name")
2187 class StringFieldDeclaration(FieldDeclaration
):
2190 Create a new string field declaration.
2193 self
._ft
= nbt
._bt
_ctf
_field
_type
_string
_create
()
2199 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
2202 return nbt
._bt
_ctf
_field
_type
_string
_get
_encoding
(self
._ft
)
2205 def encoding(self
, encoding
):
2207 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
2210 ret
= nbt
._bt
_ctf
_field
_type
_string
_set
_encoding
(self
._ft
, encoding
)
2212 raise ValueError("Could not set string encoding.")
2215 def create_field(field_type
):
2217 Create an instance of a field.
2219 isinst
= isinstance(field_type
, CTFWriter
.FieldDeclaration
)
2221 if field_type
is None or not isinst
:
2222 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
2224 if isinstance(field_type
, CTFWriter
.IntegerFieldDeclaration
):
2225 return CTFWriter
.IntegerField(field_type
)
2226 elif isinstance(field_type
, CTFWriter
.EnumerationFieldDeclaration
):
2227 return CTFWriter
.EnumerationField(field_type
)
2228 elif isinstance(field_type
, CTFWriter
.FloatFieldDeclaration
):
2229 return CTFWriter
.FloatingPointField(field_type
)
2230 elif isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2231 return CTFWriter
.StructureField(field_type
)
2232 elif isinstance(field_type
, CTFWriter
.VariantFieldDeclaration
):
2233 return CTFWriter
.VariantField(field_type
)
2234 elif isinstance(field_type
, CTFWriter
.ArrayFieldDeclaration
):
2235 return CTFWriter
.ArrayField(field_type
)
2236 elif isinstance(field_type
, CTFWriter
.SequenceFieldDeclaration
):
2237 return CTFWriter
.SequenceField(field_type
)
2238 elif isinstance(field_type
, CTFWriter
.StringFieldDeclaration
):
2239 return CTFWriter
.StringField(field_type
)
2243 Base class, do not instantiate.
2246 def __init__(self
, field_type
):
2247 if not isinstance(field_type
, CTFWriter
.FieldDeclaration
):
2248 raise TypeError("Invalid field_type argument.")
2250 self
._f
= nbt
._bt
_ctf
_field
_create
(field_type
._ft
)
2253 raise ValueError("Field creation failed.")
2256 nbt
._bt
_ctf
_field
_put
(self
._f
)
2259 def _create_field_from_native_instance(native_field_instance
):
2261 CTFTypeId
.INTEGER
: CTFWriter
.IntegerField
,
2262 CTFTypeId
.FLOAT
: CTFWriter
.FloatingPointField
,
2263 CTFTypeId
.ENUM
: CTFWriter
.EnumerationField
,
2264 CTFTypeId
.STRING
: CTFWriter
.StringField
,
2265 CTFTypeId
.STRUCT
: CTFWriter
.StructureField
,
2266 CTFTypeId
.VARIANT
: CTFWriter
.VariantField
,
2267 CTFTypeId
.ARRAY
: CTFWriter
.ArrayField
,
2268 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceField
2271 field_type
= nbt
._bt
_python
_get
_field
_type
(native_field_instance
)
2273 if field_type
== CTFTypeId
.UNKNOWN
:
2274 raise TypeError("Invalid field instance")
2276 field
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
2277 field
._f
= native_field_instance
2278 field
.__class
__ = type_dict
[field_type
]
2283 def declaration(self
):
2284 native_field_type
= nbt
._bt
_ctf
_field
_get
_type
(self
._f
)
2286 if native_field_type
is None:
2287 raise TypeError("Invalid field instance")
2288 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(
2291 class IntegerField(Field
):
2295 Get an integer field's value.
2298 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2301 raise TypeError("Invalid integer instance.")
2304 ret
, value
= nbt
._bt
_ctf
_field
_unsigned
_integer
_get
_value
(self
._f
)
2306 ret
, value
= nbt
._bt
_ctf
_field
_signed
_integer
_get
_value
(self
._f
)
2309 raise ValueError("Could not get integer field value.")
2314 def value(self
, value
):
2316 Set an integer field's value.
2319 if not isinstance(value
, int):
2320 raise TypeError("IntegerField's value must be an int")
2322 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2324 raise TypeError("Invalid integer instance.")
2327 ret
= nbt
._bt
_ctf
_field
_unsigned
_integer
_set
_value
(self
._f
, value
)
2329 ret
= nbt
._bt
_ctf
_field
_signed
_integer
_set
_value
(self
._f
, value
)
2332 raise ValueError("Could not set integer field value.")
2334 class EnumerationField(Field
):
2336 def container(self
):
2338 Return the enumeration's underlying container field (an integer field).
2341 container
= CTFWriter
.IntegerField
.__new
__(CTFWriter
.IntegerField
)
2342 container
._f
= nbt
._bt
_ctf
_field
_enumeration
_get
_container
(self
._f
)
2344 if container
._f
is None:
2345 raise TypeError("Invalid enumeration field type.")
2352 Get the enumeration field's mapping name.
2355 value
= nbt
._bt
_ctf
_field
_enumeration
_get
_mapping
_name
(self
._f
)
2358 raise ValueError("Could not get enumeration's mapping name.")
2363 def value(self
, value
):
2365 Set the enumeration field's value. Must be an integer as mapping names
2369 if not isinstance(value
, int):
2370 raise TypeError("EnumerationField value must be an int")
2372 self
.container
.value
= value
2374 class FloatingPointField(Field
):
2378 Get a floating point field's value.
2381 ret
, value
= nbt
._bt
_ctf
_field
_floating
_point
_get
_value
(self
._f
)
2384 raise ValueError("Could not get floating point field value.")
2389 def value(self
, value
):
2391 Set a floating point field's value.
2394 if not isinstance(value
, int) and not isinstance(value
, float):
2395 raise TypeError("Value must be either a float or an int")
2397 ret
= nbt
._bt
_ctf
_field
_floating
_point
_set
_value
(self
._f
, float(value
))
2400 raise ValueError("Could not set floating point field value.")
2402 # oops!! This class is provided to ensure backward-compatibility since
2403 # a stable release publicly exposed this abomination.
2404 class FloatFieldingPoint(FloatingPointField
):
2407 class StructureField(Field
):
2408 def field(self
, field_name
):
2410 Get the structure's field corresponding to the provided field name.
2413 native_instance
= nbt
._bt
_ctf
_field
_structure
_get
_field
(self
._f
,
2416 if native_instance
is None:
2417 raise ValueError("Invalid field_name provided.")
2419 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2421 class VariantField(Field
):
2422 def field(self
, tag
):
2424 Return the variant's selected field. The "tag" field is the selector enum field.
2427 native_instance
= nbt
._bt
_ctf
_field
_variant
_get
_field
(self
._f
, tag
._f
)
2429 if native_instance
is None:
2430 raise ValueError("Invalid tag provided.")
2432 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2434 class ArrayField(Field
):
2435 def field(self
, index
):
2437 Return the array's field at position "index".
2440 native_instance
= nbt
._bt
_ctf
_field
_array
_get
_field
(self
._f
, index
)
2442 if native_instance
is None:
2443 raise IndexError("Invalid index provided.")
2445 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2447 class SequenceField(Field
):
2451 Get the sequence's length field (IntegerField).
2454 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_length
(self
._f
)
2456 if native_instance
is None:
2459 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2462 def length(self
, length_field
):
2464 Set the sequence's length field (IntegerField).
2467 if not isinstance(length_field
, CTFWriter
.IntegerField
):
2468 raise TypeError("Invalid length field.")
2470 if length_field
.declaration
.signed
:
2471 raise TypeError("Sequence field length must be unsigned")
2473 ret
= nbt
._bt
_ctf
_field
_sequence
_set
_length
(self
._f
, length_field
._f
)
2476 raise ValueError("Could not set sequence length.")
2478 def field(self
, index
):
2480 Return the sequence's field at position "index".
2483 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_field
(self
._f
, index
)
2485 if native_instance
is None:
2486 raise ValueError("Could not get sequence element at index.")
2488 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2490 class StringField(Field
):
2494 Get a string field's value.
2497 return nbt
._bt
_ctf
_field
_string
_get
_value
(self
._f
)
2500 def value(self
, value
):
2502 Set a string field's value.
2505 ret
= nbt
._bt
_ctf
_field
_string
_set
_value
(self
._f
, str(value
))
2508 raise ValueError("Could not set string field value.")
2511 def __init__(self
, name
):
2513 Create a new event class of the given name.
2516 self
._ec
= nbt
._bt
_ctf
_event
_class
_create
(name
)
2518 if self
._ec
is None:
2519 raise ValueError("Event class creation failed.")
2522 nbt
._bt
_ctf
_event
_class
_put
(self
._ec
)
2524 def add_field(self
, field_type
, field_name
):
2526 Add a field of type "field_type" to the event class.
2529 ret
= nbt
._bt
_ctf
_event
_class
_add
_field
(self
._ec
, field_type
._ft
,
2533 raise ValueError("Could not add field to event class.")
2538 Get the event class' name.
2541 name
= nbt
._bt
_ctf
_event
_class
_get
_name
(self
._ec
)
2544 raise TypeError("Could not get EventClass name")
2551 Get the event class' id. Returns a negative value if unset.
2554 id = nbt
._bt
_ctf
_event
_class
_get
_id
(self
._ec
)
2557 raise TypeError("Could not get EventClass id")
2564 Set the event class' id. Throws a TypeError if the event class
2565 is already registered to a stream class.
2568 ret
= nbt
._bt
_ctf
_event
_class
_set
_id
(self
._ec
, id)
2571 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
2574 def stream_class(self
):
2576 Get the event class' stream class. Returns None if unset.
2578 stream_class_native
= nbt
._bt
_ctf
_event
_class
_get
_stream
_class
(self
._ec
)
2580 if stream_class_native
is None:
2583 stream_class
= CTFWriter
.StreamClass
.__new
__(CTFWriter
.StreamClass
)
2584 stream_class
._sc
= stream_class_native
2591 Generator returning the event class' fields as tuples of (field name, field declaration).
2594 count
= nbt
._bt
_ctf
_event
_class
_get
_field
_count
(self
._ec
)
2597 raise TypeError("Could not get EventClass' field count")
2599 for i
in range(count
):
2600 field_name
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_name
(self
._ec
, i
)
2602 if field_name
is None:
2603 msg
= "Could not get EventClass' field name at index {}".format(i
)
2604 raise TypeError(msg
)
2606 field_type_native
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_type
(self
._ec
, i
)
2608 if field_type_native
is None:
2609 msg
= "Could not get EventClass' field type at index {}".format(i
)
2610 raise TypeError(msg
)
2612 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2613 yield (field_name
, field_type
)
2615 def get_field_by_name(self
, name
):
2617 Get a field declaration by name (FieldDeclaration).
2620 field_type_native
= nbt
._bt
_ctf
_event
_class
_get
_field
_by
_name
(self
._ec
, name
)
2622 if field_type_native
is None:
2623 msg
= "Could not find EventClass field with name {}".format(name
)
2624 raise TypeError(msg
)
2626 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2629 def __init__(self
, event_class
):
2631 Create a new event of the given event class.
2634 if not isinstance(event_class
, CTFWriter
.EventClass
):
2635 raise TypeError("Invalid event_class argument.")
2637 self
._e
= nbt
._bt
_ctf
_event
_create
(event_class
._ec
)
2640 raise ValueError("Event creation failed.")
2643 nbt
._bt
_ctf
_event
_put
(self
._e
)
2646 def event_class(self
):
2648 Get the event's class.
2651 event_class_native
= nbt
._bt
_ctf
_event
_get
_class
(self
._e
)
2653 if event_class_native
is None:
2656 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2657 event_class
._ec
= event_class_native
2663 Get a clock from event. Returns None if the event's class
2664 is not registered to a stream class.
2667 clock_instance
= nbt
._bt
_ctf
_event
_get
_clock
(self
._e
)
2669 if clock_instance
is None:
2672 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2673 clock
._c
= clock_instance
2677 def payload(self
, field_name
):
2679 Get a field from event.
2682 native_instance
= nbt
._bt
_ctf
_event
_get
_payload
(self
._e
,
2685 if native_instance
is None:
2686 raise ValueError("Could not get event payload.")
2688 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2690 def set_payload(self
, field_name
, value_field
):
2692 Set a manually created field as an event's payload.
2695 if not isinstance(value
, CTFWriter
.Field
):
2696 raise TypeError("Invalid value type.")
2698 ret
= nbt
._bt
_ctf
_event
_set
_payload
(self
._e
, str(field_name
),
2702 raise ValueError("Could not set event field payload.")
2705 def __init__(self
, name
):
2707 Create a new stream class of the given name.
2710 self
._sc
= nbt
._bt
_ctf
_stream
_class
_create
(name
)
2712 if self
._sc
is None:
2713 raise ValueError("Stream class creation failed.")
2716 nbt
._bt
_ctf
_stream
_class
_put
(self
._sc
)
2721 Get a stream class' name.
2724 name
= nbt
._bt
_ctf
_stream
_class
_get
_name
(self
._sc
)
2727 raise TypeError("Could not get StreamClass name")
2734 Get a stream class' clock.
2737 clock_instance
= nbt
._bt
_ctf
_stream
_class
_get
_clock
(self
._sc
)
2739 if clock_instance
is None:
2742 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2743 clock
._c
= clock_instance
2748 def clock(self
, clock
):
2750 Assign a clock to a stream class.
2753 if not isinstance(clock
, CTFWriter
.Clock
):
2754 raise TypeError("Invalid clock type.")
2756 ret
= nbt
._bt
_ctf
_stream
_class
_set
_clock
(self
._sc
, clock
._c
)
2759 raise ValueError("Could not set stream class clock.")
2764 Get a stream class' id.
2767 ret
= nbt
._bt
_ctf
_stream
_class
_get
_id
(self
._sc
)
2770 raise TypeError("Could not get StreamClass id")
2777 Assign an id to a stream class.
2780 ret
= nbt
._bt
_ctf
_stream
_class
_set
_id
(self
._sc
, id)
2783 raise TypeError("Could not set stream class id.")
2786 def event_classes(self
):
2788 Generator returning the stream class' event classes.
2791 count
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
_count
(self
._sc
)
2794 raise TypeError("Could not get StreamClass' event class count")
2796 for i
in range(count
):
2797 event_class_native
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
(self
._sc
, i
)
2799 if event_class_native
is None:
2800 msg
= "Could not get StreamClass' event class at index {}".format(i
)
2801 raise TypeError(msg
)
2803 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2804 event_class
._ec
= event_class_native
2807 def add_event_class(self
, event_class
):
2809 Add an event class to a stream class. New events can be added even after a
2810 stream has been instantiated and events have been appended. However, a stream
2811 will not accept events of a class that has not been added to the stream
2815 if not isinstance(event_class
, CTFWriter
.EventClass
):
2816 raise TypeError("Invalid event_class type.")
2818 ret
= nbt
._bt
_ctf
_stream
_class
_add
_event
_class
(self
._sc
,
2822 raise ValueError("Could not add event class.")
2825 def packet_context_type(self
):
2827 Get the StreamClass' packet context type (StructureFieldDeclaration)
2830 field_type_native
= nbt
._bt
_ctf
_stream
_class
_get
_packet
_context
_type
(self
._sc
)
2832 if field_type_native
is None:
2833 raise ValueError("Invalid StreamClass")
2835 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2839 @packet_context_type.setter
2840 def packet_context_type(self
, field_type
):
2842 Set a StreamClass' packet context type. Must be of type
2843 StructureFieldDeclaration.
2846 if not isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2847 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2849 ret
= nbt
._bt
_ctf
_stream
_class
_set
_packet
_context
_type
(self
._sc
,
2853 raise ValueError("Failed to set packet context type.")
2857 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
2860 nbt
._bt
_ctf
_stream
_put
(self
._s
)
2863 def discarded_events(self
):
2865 Get a stream's discarded event count.
2868 ret
, count
= nbt
._bt
_ctf
_stream
_get
_discarded
_events
_count
(self
._s
)
2871 raise ValueError("Could not get the stream's discarded events count")
2875 def append_discarded_events(self
, event_count
):
2877 Increase the current packet's discarded event count.
2880 nbt
._bt
_ctf
_stream
_append
_discarded
_events
(self
._s
, event_count
)
2882 def append_event(self
, event
):
2884 Append "event" to the stream's current packet. The stream's associated clock
2885 will be sampled during this call. The event shall not be modified after
2886 being appended to a stream.
2889 ret
= nbt
._bt
_ctf
_stream
_append
_event
(self
._s
, event
._e
)
2892 raise ValueError("Could not append event to stream.")
2895 def packet_context(self
):
2897 Get a Stream's packet context field (a StructureField).
2900 native_field
= nbt
._bt
_ctf
_stream
_get
_packet
_context
(self
._s
)
2902 if native_field
is None:
2903 raise ValueError("Invalid Stream.")
2905 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_field
)
2907 @packet_context.setter
2908 def packet_context(self
, field
):
2910 Set a Stream's packet context field (must be a StructureField).
2913 if not isinstance(field
, CTFWriter
.StructureField
):
2914 raise TypeError("Argument field must be of type StructureField")
2916 ret
= nbt
._bt
_ctf
_stream
_set
_packet
_context
(self
._s
, field
._f
)
2919 raise ValueError("Invalid packet context field.")
2923 The stream's current packet's events will be flushed to disk. Events
2924 subsequently appended to the stream will be added to a new packet.
2927 ret
= nbt
._bt
_ctf
_stream
_flush
(self
._s
)
2930 raise ValueError("Could not flush stream.")
2933 def __init__(self
, path
):
2935 Create a new writer that will produce a trace in the given path.
2938 self
._w
= nbt
._bt
_ctf
_writer
_create
(path
)
2941 raise ValueError("Writer creation failed.")
2944 nbt
._bt
_ctf
_writer
_put
(self
._w
)
2946 def create_stream(self
, stream_class
):
2948 Create a new stream instance and register it to the writer.
2951 if not isinstance(stream_class
, CTFWriter
.StreamClass
):
2952 raise TypeError("Invalid stream_class type.")
2954 stream
= CTFWriter
.Stream
.__new
__(CTFWriter
.Stream
)
2955 stream
._s
= nbt
._bt
_ctf
_writer
_create
_stream
(self
._w
, stream_class
._sc
)
2959 def add_environment_field(self
, name
, value
):
2961 Add an environment field to the trace.
2964 ret
= nbt
._bt
_ctf
_writer
_add
_environment
_field
(self
._w
, str(name
),
2968 raise ValueError("Could not add environment field to trace.")
2970 def add_clock(self
, clock
):
2972 Add a clock to the trace. Clocks assigned to stream classes must be
2973 registered to the writer.
2976 ret
= nbt
._bt
_ctf
_writer
_add
_clock
(self
._w
, clock
._c
)
2979 raise ValueError("Could not add clock to Writer.")
2984 Get the trace's TSDL meta-data.
2987 return nbt
._bt
_ctf
_writer
_get
_metadata
_string
(self
._w
)
2989 def flush_metadata(self
):
2991 Flush the trace's metadata to the metadata file.
2994 nbt
._bt
_ctf
_writer
_flush
_metadata
(self
._w
)
2997 def byte_order(self
):
2999 Get the trace's byte order. Must be a constant from the ByteOrder
3003 raise NotImplementedError("Getter not implemented.")
3006 def byte_order(self
, byte_order
):
3008 Set the trace's byte order. Must be a constant from the ByteOrder
3009 class. Defaults to the host machine's endianness
3012 ret
= nbt
._bt
_ctf
_writer
_set
_byte
_order
(self
._w
, byte_order
)
3015 raise ValueError("Could not set trace's byte order.")