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
):
924 Integer field declaration.
928 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
931 def signedness(self
):
933 0 if this integer is unsigned, 1 if signed, or -1 on error.
936 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
941 Integer's base (``int``), or a negative value on error.
944 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
947 def byte_order(self
):
949 Integer's byte order (one of :class:`ByteOrder` constants).
952 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
955 return ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
957 return ByteOrder
.BYTE_ORDER_BIG_ENDIAN
959 return ByteOrder
.BYTE_ORDER_UNKNOWN
964 Integer's length in bits, or a negative value on error.
967 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
972 Integer's encoding (one of :class:`CTFStringEncoding`
976 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
979 class EnumerationFieldDeclaration(FieldDeclaration
):
981 Enumeration field declaration.
985 As of this version, this class is missing some properties.
989 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
992 class ArrayFieldDeclaration(FieldDeclaration
):
994 Static array field declaration.
998 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
1003 Static array's fixed length (number of contained elements), or
1004 a negative value on error.
1007 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
1010 def element_declaration(self
):
1012 Underlying element's field declaration.
1015 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
1017 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1020 class SequenceFieldDeclaration(FieldDeclaration
):
1022 Sequence (dynamic array) field declaration.
1026 As of this version, this class is missing some properties.
1030 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
1033 def element_declaration(self
):
1035 Underlying element's field declaration.
1038 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
1040 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1043 class FloatFieldDeclaration(FieldDeclaration
):
1045 Floating point number field declaration.
1049 As of this version, this class is missing some properties.
1053 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
1056 class StructureFieldDeclaration(FieldDeclaration
):
1058 Structure (ordered map of field names to field declarations) field
1063 As of this version, this class is missing some properties.
1067 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
1070 class StringFieldDeclaration(FieldDeclaration
):
1072 String (NULL-terminated array of bytes) field declaration.
1076 As of this version, this class is missing some properties.
1080 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
1083 class VariantFieldDeclaration(FieldDeclaration
):
1085 Variant (dynamic selection between different types) field declaration.
1089 As of this version, this class is missing some properties.
1093 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
1098 Return the last error code encountered while
1099 accessing a field and reset the error flag.
1100 Return 0 if no error, a negative value otherwise.
1103 return nbt
._bt
_ctf
_field
_get
_error
()
1106 def _create_field_declaration(declaration_ptr
, name
, scope
):
1108 Private field declaration factory.
1111 if declaration_ptr
is None:
1112 raise ValueError("declaration_ptr must be valid")
1113 if scope
not in _scopes
:
1114 raise ValueError("Invalid scope provided")
1116 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
1119 if type == CTFTypeId
.INTEGER
:
1120 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
1121 elif type == CTFTypeId
.ENUM
:
1122 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
1123 elif type == CTFTypeId
.ARRAY
:
1124 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
1125 elif type == CTFTypeId
.SEQUENCE
:
1126 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
1127 elif type == CTFTypeId
.FLOAT
:
1128 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
1129 elif type == CTFTypeId
.STRUCT
:
1130 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
1131 elif type == CTFTypeId
.STRING
:
1132 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
1133 elif type == CTFTypeId
.VARIANT
:
1134 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
1138 declaration
._fd
= declaration_ptr
1139 declaration
._s
= scope
1140 declaration
._name
= name
1146 def __init__(self
, definition_ptr
, scope
):
1147 self
._d
= definition_ptr
1150 if scope
not in _scopes
:
1151 ValueError("Invalid scope provided")
1155 """Return the name of a field or None on error."""
1157 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1161 """Return the type of a field or -1 if unknown."""
1163 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1166 def declaration(self
):
1167 """Return the associated Definition object."""
1169 return _create_field_declaration(
1170 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1172 def _get_enum_str(self
):
1174 Return the string matching the current enumeration.
1175 Return None on error.
1178 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1180 def _get_array_element_at(self
, index
):
1182 Return the array's element at position index.
1183 Return None on error
1186 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1188 if array_ptr
is None:
1191 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1193 if definition_ptr
is None:
1196 return _Definition(definition_ptr
, self
.scope
)
1198 def _get_sequence_len(self
):
1200 Return the len of a sequence or a negative
1204 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1206 return nbt
._bt
_sequence
_len
(seq
)
1208 def _get_sequence_element_at(self
, index
):
1210 Return the sequence's element at position index,
1211 otherwise return None
1214 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1217 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1219 if definition_ptr
is not None:
1220 return _Definition(definition_ptr
, self
.scope
)
1222 def _get_uint64(self
):
1224 Return the value associated with the field.
1225 If the field does not exist or is not of the type requested,
1226 the value returned is undefined. To check if an error occured,
1227 use the field_error() function after accessing a field.
1230 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1232 def _get_int64(self
):
1234 Return the value associated with the field.
1235 If the field does not exist or is not of the type requested,
1236 the value returned is undefined. To check if an error occured,
1237 use the field_error() function after accessing a field.
1240 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1242 def _get_char_array(self
):
1244 Return the value associated with the field.
1245 If the field does not exist or is not of the type requested,
1246 the value returned is undefined. To check if an error occurred,
1247 use the field_error() function after accessing a field.
1250 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1254 Return the value associated with the field.
1255 If the field does not exist or is not of the type requested,
1256 the value returned is undefined. To check if an error occurred,
1257 use the field_error() function after accessing a field.
1260 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1262 def _get_float(self
):
1264 Return the value associated with the field.
1265 If the field does not exist or is not of the type requested,
1266 the value returned is undefined. To check if an error occurred,
1267 use the field_error() function after accessing a field.
1270 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1272 def _get_variant(self
):
1274 Return the variant's selected field.
1275 If the field does not exist or is not of the type requested,
1276 the value returned is undefined. To check if an error occurred,
1277 use the field_error() function after accessing a field.
1280 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1282 def _get_struct_field_count(self
):
1284 Return the number of fields contained in the structure.
1285 If the field does not exist or is not of the type requested,
1286 the value returned is undefined.
1289 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1291 def _get_struct_field_at(self
, i
):
1293 Return the structure's field at position i.
1294 If the field does not exist or is not of the type requested,
1295 the value returned is undefined. To check if an error occurred,
1296 use the field_error() function after accessing a field.
1299 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1304 Return the value associated with the field according to its type.
1305 Return None on error.
1311 if id == CTFTypeId
.STRING
:
1312 value
= self
._get
_str
()
1313 elif id == CTFTypeId
.ARRAY
:
1314 element_decl
= self
.declaration
.element_declaration
1316 if ((element_decl
.type == CTFTypeId
.INTEGER
1317 and element_decl
.length
== 8)
1318 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1319 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1323 for i
in range(self
.declaration
.length
):
1324 element
= self
._get
_array
_element
_at
(i
)
1325 value
.append(element
.value
)
1326 elif id == CTFTypeId
.INTEGER
:
1327 if self
.declaration
.signedness
== 0:
1328 value
= self
._get
_uint
64()
1330 value
= self
._get
_int
64()
1331 elif id == CTFTypeId
.ENUM
:
1332 value
= self
._get
_enum
_str
()
1333 elif id == CTFTypeId
.SEQUENCE
:
1334 element_decl
= self
.declaration
.element_declaration
1336 if ((element_decl
.type == CTFTypeId
.INTEGER
1337 and element_decl
.length
== 8)
1338 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1339 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1341 seq_len
= self
._get
_sequence
_len
()
1344 for i
in range(seq_len
):
1345 evDef
= self
._get
_sequence
_element
_at
(i
)
1346 value
.append(evDef
.value
)
1347 elif id == CTFTypeId
.FLOAT
:
1348 value
= self
._get
_float
()
1349 elif id == CTFTypeId
.VARIANT
:
1350 variant
= _Definition
.__new
__(_Definition
)
1351 variant
._d
= self
._get
_variant
()
1352 value
= variant
.value
1353 elif id == CTFTypeId
.STRUCT
:
1356 for i
in range(self
._get
_struct
_field
_count
()):
1357 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1358 value
[member
.name
] = member
.value
1362 "Error occurred while accessing field {} of type {}".format(
1364 CTFTypeId
.type_name(id)))
1370 """Return the scope of a field or None on error."""
1376 # Used to compare to -1ULL in error checks
1377 _MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
1379 class EnumerationMapping
:
1381 Enumeration mapping class. start and end values are inclusive.
1384 def __init__(self
, name
, start
, end
):
1390 def __init__(self
, name
):
1391 self
._c
= nbt
._bt
_ctf
_clock
_create
(name
)
1394 raise ValueError("Invalid clock name.")
1397 nbt
._bt
_ctf
_clock
_put
(self
._c
)
1402 Get the clock's name.
1405 name
= nbt
._bt
_ctf
_clock
_get
_name
(self
._c
)
1408 raise ValueError("Invalid clock instance.")
1413 def description(self
):
1415 Get the clock's description. None if unset.
1418 return nbt
._bt
_ctf
_clock
_get
_description
(self
._c
)
1421 def description(self
, desc
):
1423 Set the clock's description. The description appears in the clock's TSDL
1427 ret
= nbt
._bt
_ctf
_clock
_set
_description
(self
._c
, str(desc
))
1430 raise ValueError("Invalid clock description.")
1433 def frequency(self
):
1435 Get the clock's frequency (Hz).
1438 freq
= nbt
._bt
_ctf
_clock
_get
_frequency
(self
._c
)
1440 if freq
== CTFWriter
._MAX
_UINT
64:
1441 raise ValueError("Invalid clock instance")
1446 def frequency(self
, freq
):
1448 Set the clock's frequency (Hz).
1451 ret
= nbt
._bt
_ctf
_clock
_set
_frequency
(self
._c
, freq
)
1454 raise ValueError("Invalid frequency value.")
1457 def precision(self
):
1459 Get the clock's precision (in clock ticks).
1462 precision
= nbt
._bt
_ctf
_clock
_get
_precision
(self
._c
)
1464 if precision
== CTFWriter
._MAX
_UINT
64:
1465 raise ValueError("Invalid clock instance")
1470 def precision(self
, precision
):
1472 Set the clock's precision (in clock ticks).
1475 ret
= nbt
._bt
_ctf
_clock
_set
_precision
(self
._c
, precision
)
1478 def offset_seconds(self
):
1480 Get the clock's offset in seconds from POSIX.1 Epoch.
1483 offset_s
= nbt
._bt
_ctf
_clock
_get
_offset
_s
(self
._c
)
1485 if offset_s
== CTFWriter
._MAX
_UINT
64:
1486 raise ValueError("Invalid clock instance")
1490 @offset_seconds.setter
1491 def offset_seconds(self
, offset_s
):
1493 Set the clock's offset in seconds from POSIX.1 Epoch.
1496 ret
= nbt
._bt
_ctf
_clock
_set
_offset
_s
(self
._c
, offset_s
)
1499 raise ValueError("Invalid offset value.")
1504 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1507 offset
= nbt
._bt
_ctf
_clock
_get
_offset
(self
._c
)
1509 if offset
== CTFWriter
._MAX
_UINT
64:
1510 raise ValueError("Invalid clock instance")
1515 def offset(self
, offset
):
1517 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1520 ret
= nbt
._bt
_ctf
_clock
_set
_offset
(self
._c
, offset
)
1523 raise ValueError("Invalid offset value.")
1528 Get a clock's absolute attribute. A clock is absolute if the clock
1529 is a global reference across the trace's other clocks.
1532 is_absolute
= nbt
._bt
_ctf
_clock
_get
_is
_absolute
(self
._c
)
1534 if is_absolute
== -1:
1535 raise ValueError("Invalid clock instance")
1537 return False if is_absolute
== 0 else True
1540 def absolute(self
, is_absolute
):
1542 Set a clock's absolute attribute. A clock is absolute if the clock
1543 is a global reference across the trace's other clocks.
1546 ret
= nbt
._bt
_ctf
_clock
_set
_is
_absolute
(self
._c
, int(is_absolute
))
1549 raise ValueError("Could not set the clock's absolute attribute.")
1554 Get a clock's UUID (an object of type UUID).
1560 ret
, value
= nbt
._bt
_python
_ctf
_clock
_get
_uuid
_index
(self
._c
, i
)
1563 raise ValueError("Invalid clock instance")
1565 uuid_list
.append(value
)
1567 return UUID(bytes
=bytes(uuid_list
))
1570 def uuid(self
, uuid
):
1572 Set a clock's UUID (an object of type UUID).
1575 uuid_bytes
= uuid
.bytes
1577 if len(uuid_bytes
) != 16:
1578 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1580 for i
in range(len(uuid_bytes
)):
1581 ret
= nbt
._bt
_python
_ctf
_clock
_set
_uuid
_index
(self
._c
, i
,
1585 raise ValueError("Invalid clock instance")
1590 Get the current time in nanoseconds since the clock's origin (offset and
1591 offset_s attributes).
1594 time
= nbt
._bt
_ctf
_clock
_get
_time
(self
._c
)
1596 if time
== CTFWriter
._MAX
_UINT
64:
1597 raise ValueError("Invalid clock instance")
1602 def time(self
, time
):
1604 Set the current time in nanoseconds since the clock's origin (offset and
1605 offset_s attributes). The clock's value will be sampled as events are
1606 appended to a stream.
1609 ret
= nbt
._bt
_ctf
_clock
_set
_time
(self
._c
, time
)
1612 raise ValueError("Invalid time value.")
1614 class FieldDeclaration
:
1616 FieldDeclaration should not be instantiated directly. Instantiate
1617 one of the concrete FieldDeclaration classes.
1621 # These values are based on the bt_ctf_integer_base enum
1622 # declared in event-types.h.
1623 INTEGER_BASE_UNKNOWN
= -1
1624 INTEGER_BASE_BINARY
= 2
1625 INTEGER_BASE_OCTAL
= 8
1626 INTEGER_BASE_DECIMAL
= 10
1627 INTEGER_BASE_HEXADECIMAL
= 16
1630 if self
._ft
is None:
1631 raise ValueError("FieldDeclaration creation failed.")
1634 nbt
._bt
_ctf
_field
_type
_put
(self
._ft
)
1637 def _create_field_declaration_from_native_instance(
1638 native_field_declaration
):
1640 CTFTypeId
.INTEGER
: CTFWriter
.IntegerFieldDeclaration
,
1641 CTFTypeId
.FLOAT
: CTFWriter
.FloatFieldDeclaration
,
1642 CTFTypeId
.ENUM
: CTFWriter
.EnumerationFieldDeclaration
,
1643 CTFTypeId
.STRING
: CTFWriter
.StringFieldDeclaration
,
1644 CTFTypeId
.STRUCT
: CTFWriter
.StructureFieldDeclaration
,
1645 CTFTypeId
.VARIANT
: CTFWriter
.VariantFieldDeclaration
,
1646 CTFTypeId
.ARRAY
: CTFWriter
.ArrayFieldDeclaration
,
1647 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceFieldDeclaration
1650 field_type_id
= nbt
._bt
_ctf
_field
_type
_get
_type
_id
(native_field_declaration
)
1652 if field_type_id
== CTFTypeId
.UNKNOWN
:
1653 raise TypeError("Invalid field instance")
1655 declaration
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
1656 declaration
._ft
= native_field_declaration
1657 declaration
.__class
__ = type_dict
[field_type_id
]
1662 def alignment(self
):
1664 Get the field declaration's alignment. Returns -1 on error.
1667 return nbt
._bt
_ctf
_field
_type
_get
_alignment
(self
._ft
)
1670 def alignment(self
, alignment
):
1672 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1673 some types, such as structures and string, may impose other alignment
1677 ret
= nbt
._bt
_ctf
_field
_type
_set
_alignment
(self
._ft
, alignment
)
1680 raise ValueError("Invalid alignment value.")
1683 def byte_order(self
):
1685 Get the field declaration's byte order. One of the ByteOrder's constant.
1688 return nbt
._bt
_ctf
_field
_type
_get
_byte
_order
(self
._ft
)
1691 def byte_order(self
, byte_order
):
1693 Set the field declaration's byte order. Use constants defined in the ByteOrder
1697 ret
= nbt
._bt
_ctf
_field
_type
_set
_byte
_order
(self
._ft
, byte_order
)
1700 raise ValueError("Could not set byte order value.")
1702 class IntegerFieldDeclaration(FieldDeclaration
):
1703 def __init__(self
, size
):
1705 Create a new integer field declaration of the given size.
1707 self
._ft
= nbt
._bt
_ctf
_field
_type
_integer
_create
(size
)
1713 Get an integer's size.
1716 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_size
(self
._ft
)
1719 raise ValueError("Could not get Integer's size attribute.")
1726 Get an integer's signedness attribute.
1729 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_signed
(self
._ft
)
1732 raise ValueError("Could not get Integer's signed attribute.")
1739 def signed(self
, signed
):
1741 Set an integer's signedness attribute.
1744 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_signed
(self
._ft
, signed
)
1747 raise ValueError("Could not set Integer's signed attribute.")
1752 Get the integer's base used to pretty-print the resulting trace.
1753 Returns a constant from the FieldDeclaration.IntegerBase class.
1756 return nbt
._bt
_ctf
_field
_type
_integer
_get
_base
(self
._ft
)
1759 def base(self
, base
):
1761 Set the integer's base used to pretty-print the resulting trace.
1762 The base must be a constant of the FieldDeclarationIntegerBase class.
1765 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_base
(self
._ft
, base
)
1768 raise ValueError("Could not set Integer's base.")
1773 Get the integer's encoding (one of the constants of the
1774 CTFStringEncoding class).
1775 Returns a constant from the CTFStringEncoding class.
1778 return nbt
._bt
_ctf
_field
_type
_integer
_get
_encoding
(self
._ft
)
1781 def encoding(self
, encoding
):
1783 An integer encoding may be set to signal that the integer must be printed
1784 as a text character. Must be a constant from the CTFStringEncoding class.
1787 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_encoding
(self
._ft
, encoding
)
1790 raise ValueError("Could not set Integer's encoding.")
1792 class EnumerationFieldDeclaration(FieldDeclaration
):
1793 def __init__(self
, integer_type
):
1795 Create a new enumeration field declaration with the given underlying container type.
1797 isinst
= isinstance(integer_type
, CTFWriter
.IntegerFieldDeclaration
)
1799 if integer_type
is None or not isinst
:
1800 raise TypeError("Invalid integer container.")
1802 self
._ft
= nbt
._bt
_ctf
_field
_type
_enumeration
_create
(integer_type
._ft
)
1806 def container(self
):
1808 Get the enumeration's underlying container type.
1811 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_container
_type
(self
._ft
)
1814 raise TypeError("Invalid enumeration declaration")
1816 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1818 def add_mapping(self
, name
, range_start
, range_end
):
1820 Add a mapping to the enumeration. The range's values are inclusive.
1823 if range_start
< 0 or range_end
< 0:
1824 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
(self
._ft
,
1829 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
_unsigned
(self
._ft
,
1835 raise ValueError("Could not add mapping to enumeration declaration.")
1840 Generator returning instances of EnumerationMapping.
1843 signed
= self
.container
.signed
1845 count
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_count
(self
._ft
)
1847 for i
in range(count
):
1849 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, i
)
1851 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, i
)
1854 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1855 raise TypeError(msg
)
1857 name
, range_start
, range_end
= ret
1858 yield CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1860 def get_mapping_by_name(self
, name
):
1862 Get a mapping by name (EnumerationMapping).
1865 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_name
(self
._ft
, name
)
1870 if self
.container
.signed
:
1871 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1873 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1876 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1877 raise TypeError(msg
)
1879 name
, range_start
, range_end
= ret
1881 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1883 def get_mapping_by_value(self
, value
):
1885 Get a mapping by value (EnumerationMapping).
1889 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_value
(self
._ft
, value
)
1891 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_unsigned
_value
(self
._ft
, value
)
1896 if self
.container
.signed
:
1897 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1899 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1902 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1903 raise TypeError(msg
)
1905 name
, range_start
, range_end
= ret
1907 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1909 class FloatFieldDeclaration(FieldDeclaration
):
1917 Create a new floating point field declaration.
1920 self
._ft
= nbt
._bt
_ctf
_field
_type
_floating
_point
_create
()
1924 def exponent_digits(self
):
1926 Get the number of exponent digits used to store the floating point field.
1929 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_exponent
_digits
(self
._ft
)
1933 "Could not get Floating point exponent digit count")
1937 @exponent_digits.setter
1938 def exponent_digits(self
, exponent_digits
):
1940 Set the number of exponent digits to use to store the floating point field.
1941 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1942 are defined as constants of this class.
1945 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_exponent
_digits
(self
._ft
,
1949 raise ValueError("Could not set exponent digit count.")
1952 def mantissa_digits(self
):
1954 Get the number of mantissa digits used to store the floating point field.
1957 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_mantissa
_digits
(self
._ft
)
1960 raise TypeError("Could not get Floating point mantissa digit count")
1964 @mantissa_digits.setter
1965 def mantissa_digits(self
, mantissa_digits
):
1967 Set the number of mantissa digits to use to store the floating point field.
1968 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1969 are defined as constants of this class.
1972 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_mantissa
_digits
(self
._ft
,
1976 raise ValueError("Could not set mantissa digit count.")
1978 class FloatingPointFieldDeclaration(FloatFieldDeclaration
):
1981 class StructureFieldDeclaration(FieldDeclaration
):
1984 Create a new structure field declaration.
1987 self
._ft
= nbt
._bt
_ctf
_field
_type
_structure
_create
()
1990 def add_field(self
, field_type
, field_name
):
1992 Add a field of type "field_type" to the structure.
1995 ret
= nbt
._bt
_ctf
_field
_type
_structure
_add
_field
(self
._ft
,
2000 raise ValueError("Could not add field to structure.")
2005 Generator returning the structure's field as tuples of (field name, field declaration).
2008 count
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_count
(self
._ft
)
2011 raise TypeError("Could not get Structure field count")
2013 for i
in range(count
):
2014 field_name
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_name
(self
._ft
, i
)
2016 if field_name
is None:
2017 msg
= "Could not get Structure field name at index {}".format(i
)
2018 raise TypeError(msg
)
2020 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_type
(self
._ft
, i
)
2022 if field_type_native
is None:
2023 msg
= "Could not get Structure field type at index {}".format(i
)
2024 raise TypeError(msg
)
2026 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2027 yield (field_name
, field_type
)
2029 def get_field_by_name(self
, name
):
2031 Get a field declaration by name (FieldDeclaration).
2034 field_type_native
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_type
_by
_name
(self
._ft
, name
)
2036 if field_type_native
is None:
2037 msg
= "Could not find Structure field with name {}".format(name
)
2038 raise TypeError(msg
)
2040 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2042 class VariantFieldDeclaration(FieldDeclaration
):
2043 def __init__(self
, enum_tag
, tag_name
):
2045 Create a new variant field declaration.
2048 isinst
= isinstance(enum_tag
, CTFWriter
.EnumerationFieldDeclaration
)
2049 if enum_tag
is None or not isinst
:
2050 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
2052 self
._ft
= nbt
._bt
_ctf
_field
_type
_variant
_create
(enum_tag
._ft
,
2059 Get the variant's tag name.
2062 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_name
(self
._ft
)
2065 raise TypeError("Could not get Variant tag name")
2072 Get the variant's tag type.
2075 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_type
(self
._ft
)
2078 raise TypeError("Could not get Variant tag type")
2080 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2082 def add_field(self
, field_type
, field_name
):
2084 Add a field of type "field_type" to the variant.
2087 ret
= nbt
._bt
_ctf
_field
_type
_variant
_add
_field
(self
._ft
,
2092 raise ValueError("Could not add field to variant.")
2097 Generator returning the variant's field as tuples of (field name, field declaration).
2100 count
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_count
(self
._ft
)
2103 raise TypeError("Could not get Variant field count")
2105 for i
in range(count
):
2106 field_name
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_name
(self
._ft
, i
)
2108 if field_name
is None:
2109 msg
= "Could not get Variant field name at index {}".format(i
)
2110 raise TypeError(msg
)
2112 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_type
(self
._ft
, i
)
2114 if field_type_native
is None:
2115 msg
= "Could not get Variant field type at index {}".format(i
)
2116 raise TypeError(msg
)
2118 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2119 yield (field_name
, field_type
)
2121 def get_field_by_name(self
, name
):
2123 Get a field declaration by name (FieldDeclaration).
2126 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_by
_name
(self
._ft
,
2129 if field_type_native
is None:
2130 msg
= "Could not find Variant field with name {}".format(name
)
2131 raise TypeError(msg
)
2133 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2135 def get_field_from_tag(self
, tag
):
2137 Get a field declaration from tag (EnumerationField).
2140 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_from
_tag
(self
._ft
, tag
._f
)
2142 if field_type_native
is None:
2143 msg
= "Could not find Variant field with tag value {}".format(tag
.value
)
2144 raise TypeError(msg
)
2146 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2148 class ArrayFieldDeclaration(FieldDeclaration
):
2149 def __init__(self
, element_type
, length
):
2151 Create a new array field declaration.
2154 self
._ft
= nbt
._bt
_ctf
_field
_type
_array
_create
(element_type
._ft
,
2159 def element_type(self
):
2161 Get the array's element type.
2164 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_element
_type
(self
._ft
)
2167 raise TypeError("Could not get Array element type")
2169 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2174 Get the array's length.
2177 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_length
(self
._ft
)
2180 raise TypeError("Could not get Array length")
2184 class SequenceFieldDeclaration(FieldDeclaration
):
2185 def __init__(self
, element_type
, length_field_name
):
2187 Create a new sequence field declaration.
2190 self
._ft
= nbt
._bt
_ctf
_field
_type
_sequence
_create
(element_type
._ft
,
2191 str(length_field_name
))
2195 def element_type(self
):
2197 Get the sequence's element type.
2200 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_element
_type
(self
._ft
)
2203 raise TypeError("Could not get Sequence element type")
2205 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2208 def length_field_name(self
):
2210 Get the sequence's length field name.
2213 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_length
_field
_name
(self
._ft
)
2216 raise TypeError("Could not get Sequence length field name")
2220 class StringFieldDeclaration(FieldDeclaration
):
2223 Create a new string field declaration.
2226 self
._ft
= nbt
._bt
_ctf
_field
_type
_string
_create
()
2232 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
2235 return nbt
._bt
_ctf
_field
_type
_string
_get
_encoding
(self
._ft
)
2238 def encoding(self
, encoding
):
2240 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
2243 ret
= nbt
._bt
_ctf
_field
_type
_string
_set
_encoding
(self
._ft
, encoding
)
2245 raise ValueError("Could not set string encoding.")
2248 def create_field(field_type
):
2250 Create an instance of a field.
2252 isinst
= isinstance(field_type
, CTFWriter
.FieldDeclaration
)
2254 if field_type
is None or not isinst
:
2255 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
2257 if isinstance(field_type
, CTFWriter
.IntegerFieldDeclaration
):
2258 return CTFWriter
.IntegerField(field_type
)
2259 elif isinstance(field_type
, CTFWriter
.EnumerationFieldDeclaration
):
2260 return CTFWriter
.EnumerationField(field_type
)
2261 elif isinstance(field_type
, CTFWriter
.FloatFieldDeclaration
):
2262 return CTFWriter
.FloatingPointField(field_type
)
2263 elif isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2264 return CTFWriter
.StructureField(field_type
)
2265 elif isinstance(field_type
, CTFWriter
.VariantFieldDeclaration
):
2266 return CTFWriter
.VariantField(field_type
)
2267 elif isinstance(field_type
, CTFWriter
.ArrayFieldDeclaration
):
2268 return CTFWriter
.ArrayField(field_type
)
2269 elif isinstance(field_type
, CTFWriter
.SequenceFieldDeclaration
):
2270 return CTFWriter
.SequenceField(field_type
)
2271 elif isinstance(field_type
, CTFWriter
.StringFieldDeclaration
):
2272 return CTFWriter
.StringField(field_type
)
2276 Base class, do not instantiate.
2279 def __init__(self
, field_type
):
2280 if not isinstance(field_type
, CTFWriter
.FieldDeclaration
):
2281 raise TypeError("Invalid field_type argument.")
2283 self
._f
= nbt
._bt
_ctf
_field
_create
(field_type
._ft
)
2286 raise ValueError("Field creation failed.")
2289 nbt
._bt
_ctf
_field
_put
(self
._f
)
2292 def _create_field_from_native_instance(native_field_instance
):
2294 CTFTypeId
.INTEGER
: CTFWriter
.IntegerField
,
2295 CTFTypeId
.FLOAT
: CTFWriter
.FloatingPointField
,
2296 CTFTypeId
.ENUM
: CTFWriter
.EnumerationField
,
2297 CTFTypeId
.STRING
: CTFWriter
.StringField
,
2298 CTFTypeId
.STRUCT
: CTFWriter
.StructureField
,
2299 CTFTypeId
.VARIANT
: CTFWriter
.VariantField
,
2300 CTFTypeId
.ARRAY
: CTFWriter
.ArrayField
,
2301 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceField
2304 field_type
= nbt
._bt
_python
_get
_field
_type
(native_field_instance
)
2306 if field_type
== CTFTypeId
.UNKNOWN
:
2307 raise TypeError("Invalid field instance")
2309 field
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
2310 field
._f
= native_field_instance
2311 field
.__class
__ = type_dict
[field_type
]
2316 def declaration(self
):
2317 native_field_type
= nbt
._bt
_ctf
_field
_get
_type
(self
._f
)
2319 if native_field_type
is None:
2320 raise TypeError("Invalid field instance")
2321 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(
2324 class IntegerField(Field
):
2328 Get an integer field's value.
2331 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2334 raise TypeError("Invalid integer instance.")
2337 ret
, value
= nbt
._bt
_ctf
_field
_unsigned
_integer
_get
_value
(self
._f
)
2339 ret
, value
= nbt
._bt
_ctf
_field
_signed
_integer
_get
_value
(self
._f
)
2342 raise ValueError("Could not get integer field value.")
2347 def value(self
, value
):
2349 Set an integer field's value.
2352 if not isinstance(value
, int):
2353 raise TypeError("IntegerField's value must be an int")
2355 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2357 raise TypeError("Invalid integer instance.")
2360 ret
= nbt
._bt
_ctf
_field
_unsigned
_integer
_set
_value
(self
._f
, value
)
2362 ret
= nbt
._bt
_ctf
_field
_signed
_integer
_set
_value
(self
._f
, value
)
2365 raise ValueError("Could not set integer field value.")
2367 class EnumerationField(Field
):
2369 def container(self
):
2371 Return the enumeration's underlying container field (an integer field).
2374 container
= CTFWriter
.IntegerField
.__new
__(CTFWriter
.IntegerField
)
2375 container
._f
= nbt
._bt
_ctf
_field
_enumeration
_get
_container
(self
._f
)
2377 if container
._f
is None:
2378 raise TypeError("Invalid enumeration field type.")
2385 Get the enumeration field's mapping name.
2388 value
= nbt
._bt
_ctf
_field
_enumeration
_get
_mapping
_name
(self
._f
)
2391 raise ValueError("Could not get enumeration's mapping name.")
2396 def value(self
, value
):
2398 Set the enumeration field's value. Must be an integer as mapping names
2402 if not isinstance(value
, int):
2403 raise TypeError("EnumerationField value must be an int")
2405 self
.container
.value
= value
2407 class FloatingPointField(Field
):
2411 Get a floating point field's value.
2414 ret
, value
= nbt
._bt
_ctf
_field
_floating
_point
_get
_value
(self
._f
)
2417 raise ValueError("Could not get floating point field value.")
2422 def value(self
, value
):
2424 Set a floating point field's value.
2427 if not isinstance(value
, int) and not isinstance(value
, float):
2428 raise TypeError("Value must be either a float or an int")
2430 ret
= nbt
._bt
_ctf
_field
_floating
_point
_set
_value
(self
._f
, float(value
))
2433 raise ValueError("Could not set floating point field value.")
2435 # oops!! This class is provided to ensure backward-compatibility since
2436 # a stable release publicly exposed this abomination.
2437 class FloatFieldingPoint(FloatingPointField
):
2440 class StructureField(Field
):
2441 def field(self
, field_name
):
2443 Get the structure's field corresponding to the provided field name.
2446 native_instance
= nbt
._bt
_ctf
_field
_structure
_get
_field
(self
._f
,
2449 if native_instance
is None:
2450 raise ValueError("Invalid field_name provided.")
2452 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2454 class VariantField(Field
):
2455 def field(self
, tag
):
2457 Return the variant's selected field. The "tag" field is the selector enum field.
2460 native_instance
= nbt
._bt
_ctf
_field
_variant
_get
_field
(self
._f
, tag
._f
)
2462 if native_instance
is None:
2463 raise ValueError("Invalid tag provided.")
2465 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2467 class ArrayField(Field
):
2468 def field(self
, index
):
2470 Return the array's field at position "index".
2473 native_instance
= nbt
._bt
_ctf
_field
_array
_get
_field
(self
._f
, index
)
2475 if native_instance
is None:
2476 raise IndexError("Invalid index provided.")
2478 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2480 class SequenceField(Field
):
2484 Get the sequence's length field (IntegerField).
2487 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_length
(self
._f
)
2489 if native_instance
is None:
2492 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2495 def length(self
, length_field
):
2497 Set the sequence's length field (IntegerField).
2500 if not isinstance(length_field
, CTFWriter
.IntegerField
):
2501 raise TypeError("Invalid length field.")
2503 if length_field
.declaration
.signed
:
2504 raise TypeError("Sequence field length must be unsigned")
2506 ret
= nbt
._bt
_ctf
_field
_sequence
_set
_length
(self
._f
, length_field
._f
)
2509 raise ValueError("Could not set sequence length.")
2511 def field(self
, index
):
2513 Return the sequence's field at position "index".
2516 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_field
(self
._f
, index
)
2518 if native_instance
is None:
2519 raise ValueError("Could not get sequence element at index.")
2521 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2523 class StringField(Field
):
2527 Get a string field's value.
2530 return nbt
._bt
_ctf
_field
_string
_get
_value
(self
._f
)
2533 def value(self
, value
):
2535 Set a string field's value.
2538 ret
= nbt
._bt
_ctf
_field
_string
_set
_value
(self
._f
, str(value
))
2541 raise ValueError("Could not set string field value.")
2544 def __init__(self
, name
):
2546 Create a new event class of the given name.
2549 self
._ec
= nbt
._bt
_ctf
_event
_class
_create
(name
)
2551 if self
._ec
is None:
2552 raise ValueError("Event class creation failed.")
2555 nbt
._bt
_ctf
_event
_class
_put
(self
._ec
)
2557 def add_field(self
, field_type
, field_name
):
2559 Add a field of type "field_type" to the event class.
2562 ret
= nbt
._bt
_ctf
_event
_class
_add
_field
(self
._ec
, field_type
._ft
,
2566 raise ValueError("Could not add field to event class.")
2571 Get the event class' name.
2574 name
= nbt
._bt
_ctf
_event
_class
_get
_name
(self
._ec
)
2577 raise TypeError("Could not get EventClass name")
2584 Get the event class' id. Returns a negative value if unset.
2587 id = nbt
._bt
_ctf
_event
_class
_get
_id
(self
._ec
)
2590 raise TypeError("Could not get EventClass id")
2597 Set the event class' id. Throws a TypeError if the event class
2598 is already registered to a stream class.
2601 ret
= nbt
._bt
_ctf
_event
_class
_set
_id
(self
._ec
, id)
2604 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
2607 def stream_class(self
):
2609 Get the event class' stream class. Returns None if unset.
2611 stream_class_native
= nbt
._bt
_ctf
_event
_class
_get
_stream
_class
(self
._ec
)
2613 if stream_class_native
is None:
2616 stream_class
= CTFWriter
.StreamClass
.__new
__(CTFWriter
.StreamClass
)
2617 stream_class
._sc
= stream_class_native
2624 Generator returning the event class' fields as tuples of (field name, field declaration).
2627 count
= nbt
._bt
_ctf
_event
_class
_get
_field
_count
(self
._ec
)
2630 raise TypeError("Could not get EventClass' field count")
2632 for i
in range(count
):
2633 field_name
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_name
(self
._ec
, i
)
2635 if field_name
is None:
2636 msg
= "Could not get EventClass' field name at index {}".format(i
)
2637 raise TypeError(msg
)
2639 field_type_native
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_type
(self
._ec
, i
)
2641 if field_type_native
is None:
2642 msg
= "Could not get EventClass' field type at index {}".format(i
)
2643 raise TypeError(msg
)
2645 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2646 yield (field_name
, field_type
)
2648 def get_field_by_name(self
, name
):
2650 Get a field declaration by name (FieldDeclaration).
2653 field_type_native
= nbt
._bt
_ctf
_event
_class
_get
_field
_by
_name
(self
._ec
, name
)
2655 if field_type_native
is None:
2656 msg
= "Could not find EventClass field with name {}".format(name
)
2657 raise TypeError(msg
)
2659 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2662 def __init__(self
, event_class
):
2664 Create a new event of the given event class.
2667 if not isinstance(event_class
, CTFWriter
.EventClass
):
2668 raise TypeError("Invalid event_class argument.")
2670 self
._e
= nbt
._bt
_ctf
_event
_create
(event_class
._ec
)
2673 raise ValueError("Event creation failed.")
2676 nbt
._bt
_ctf
_event
_put
(self
._e
)
2679 def event_class(self
):
2681 Get the event's class.
2684 event_class_native
= nbt
._bt
_ctf
_event
_get
_class
(self
._e
)
2686 if event_class_native
is None:
2689 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2690 event_class
._ec
= event_class_native
2696 Get a clock from event. Returns None if the event's class
2697 is not registered to a stream class.
2700 clock_instance
= nbt
._bt
_ctf
_event
_get
_clock
(self
._e
)
2702 if clock_instance
is None:
2705 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2706 clock
._c
= clock_instance
2710 def payload(self
, field_name
):
2712 Get a field from event.
2715 native_instance
= nbt
._bt
_ctf
_event
_get
_payload
(self
._e
,
2718 if native_instance
is None:
2719 raise ValueError("Could not get event payload.")
2721 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2723 def set_payload(self
, field_name
, value_field
):
2725 Set a manually created field as an event's payload.
2728 if not isinstance(value
, CTFWriter
.Field
):
2729 raise TypeError("Invalid value type.")
2731 ret
= nbt
._bt
_ctf
_event
_set
_payload
(self
._e
, str(field_name
),
2735 raise ValueError("Could not set event field payload.")
2738 def __init__(self
, name
):
2740 Create a new stream class of the given name.
2743 self
._sc
= nbt
._bt
_ctf
_stream
_class
_create
(name
)
2745 if self
._sc
is None:
2746 raise ValueError("Stream class creation failed.")
2749 nbt
._bt
_ctf
_stream
_class
_put
(self
._sc
)
2754 Get a stream class' name.
2757 name
= nbt
._bt
_ctf
_stream
_class
_get
_name
(self
._sc
)
2760 raise TypeError("Could not get StreamClass name")
2767 Get a stream class' clock.
2770 clock_instance
= nbt
._bt
_ctf
_stream
_class
_get
_clock
(self
._sc
)
2772 if clock_instance
is None:
2775 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2776 clock
._c
= clock_instance
2781 def clock(self
, clock
):
2783 Assign a clock to a stream class.
2786 if not isinstance(clock
, CTFWriter
.Clock
):
2787 raise TypeError("Invalid clock type.")
2789 ret
= nbt
._bt
_ctf
_stream
_class
_set
_clock
(self
._sc
, clock
._c
)
2792 raise ValueError("Could not set stream class clock.")
2797 Get a stream class' id.
2800 ret
= nbt
._bt
_ctf
_stream
_class
_get
_id
(self
._sc
)
2803 raise TypeError("Could not get StreamClass id")
2810 Assign an id to a stream class.
2813 ret
= nbt
._bt
_ctf
_stream
_class
_set
_id
(self
._sc
, id)
2816 raise TypeError("Could not set stream class id.")
2819 def event_classes(self
):
2821 Generator returning the stream class' event classes.
2824 count
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
_count
(self
._sc
)
2827 raise TypeError("Could not get StreamClass' event class count")
2829 for i
in range(count
):
2830 event_class_native
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
(self
._sc
, i
)
2832 if event_class_native
is None:
2833 msg
= "Could not get StreamClass' event class at index {}".format(i
)
2834 raise TypeError(msg
)
2836 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2837 event_class
._ec
= event_class_native
2840 def add_event_class(self
, event_class
):
2842 Add an event class to a stream class. New events can be added even after a
2843 stream has been instantiated and events have been appended. However, a stream
2844 will not accept events of a class that has not been added to the stream
2848 if not isinstance(event_class
, CTFWriter
.EventClass
):
2849 raise TypeError("Invalid event_class type.")
2851 ret
= nbt
._bt
_ctf
_stream
_class
_add
_event
_class
(self
._sc
,
2855 raise ValueError("Could not add event class.")
2858 def packet_context_type(self
):
2860 Get the StreamClass' packet context type (StructureFieldDeclaration)
2863 field_type_native
= nbt
._bt
_ctf
_stream
_class
_get
_packet
_context
_type
(self
._sc
)
2865 if field_type_native
is None:
2866 raise ValueError("Invalid StreamClass")
2868 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2872 @packet_context_type.setter
2873 def packet_context_type(self
, field_type
):
2875 Set a StreamClass' packet context type. Must be of type
2876 StructureFieldDeclaration.
2879 if not isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2880 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2882 ret
= nbt
._bt
_ctf
_stream
_class
_set
_packet
_context
_type
(self
._sc
,
2886 raise ValueError("Failed to set packet context type.")
2890 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
2893 nbt
._bt
_ctf
_stream
_put
(self
._s
)
2896 def discarded_events(self
):
2898 Get a stream's discarded event count.
2901 ret
, count
= nbt
._bt
_ctf
_stream
_get
_discarded
_events
_count
(self
._s
)
2904 raise ValueError("Could not get the stream's discarded events count")
2908 def append_discarded_events(self
, event_count
):
2910 Increase the current packet's discarded event count.
2913 nbt
._bt
_ctf
_stream
_append
_discarded
_events
(self
._s
, event_count
)
2915 def append_event(self
, event
):
2917 Append "event" to the stream's current packet. The stream's associated clock
2918 will be sampled during this call. The event shall not be modified after
2919 being appended to a stream.
2922 ret
= nbt
._bt
_ctf
_stream
_append
_event
(self
._s
, event
._e
)
2925 raise ValueError("Could not append event to stream.")
2928 def packet_context(self
):
2930 Get a Stream's packet context field (a StructureField).
2933 native_field
= nbt
._bt
_ctf
_stream
_get
_packet
_context
(self
._s
)
2935 if native_field
is None:
2936 raise ValueError("Invalid Stream.")
2938 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_field
)
2940 @packet_context.setter
2941 def packet_context(self
, field
):
2943 Set a Stream's packet context field (must be a StructureField).
2946 if not isinstance(field
, CTFWriter
.StructureField
):
2947 raise TypeError("Argument field must be of type StructureField")
2949 ret
= nbt
._bt
_ctf
_stream
_set
_packet
_context
(self
._s
, field
._f
)
2952 raise ValueError("Invalid packet context field.")
2956 The stream's current packet's events will be flushed to disk. Events
2957 subsequently appended to the stream will be added to a new packet.
2960 ret
= nbt
._bt
_ctf
_stream
_flush
(self
._s
)
2963 raise ValueError("Could not flush stream.")
2966 def __init__(self
, path
):
2968 Create a new writer that will produce a trace in the given path.
2971 self
._w
= nbt
._bt
_ctf
_writer
_create
(path
)
2974 raise ValueError("Writer creation failed.")
2977 nbt
._bt
_ctf
_writer
_put
(self
._w
)
2979 def create_stream(self
, stream_class
):
2981 Create a new stream instance and register it to the writer.
2984 if not isinstance(stream_class
, CTFWriter
.StreamClass
):
2985 raise TypeError("Invalid stream_class type.")
2987 stream
= CTFWriter
.Stream
.__new
__(CTFWriter
.Stream
)
2988 stream
._s
= nbt
._bt
_ctf
_writer
_create
_stream
(self
._w
, stream_class
._sc
)
2992 def add_environment_field(self
, name
, value
):
2994 Add an environment field to the trace.
2997 ret
= nbt
._bt
_ctf
_writer
_add
_environment
_field
(self
._w
, str(name
),
3001 raise ValueError("Could not add environment field to trace.")
3003 def add_clock(self
, clock
):
3005 Add a clock to the trace. Clocks assigned to stream classes must be
3006 registered to the writer.
3009 ret
= nbt
._bt
_ctf
_writer
_add
_clock
(self
._w
, clock
._c
)
3012 raise ValueError("Could not add clock to Writer.")
3017 Get the trace's TSDL meta-data.
3020 return nbt
._bt
_ctf
_writer
_get
_metadata
_string
(self
._w
)
3022 def flush_metadata(self
):
3024 Flush the trace's metadata to the metadata file.
3027 nbt
._bt
_ctf
_writer
_flush
_metadata
(self
._w
)
3030 def byte_order(self
):
3032 Get the trace's byte order. Must be a constant from the ByteOrder
3036 raise NotImplementedError("Getter not implemented.")
3039 def byte_order(self
, byte_order
):
3041 Set the trace's byte order. Must be a constant from the ByteOrder
3042 class. Defaults to the host machine's endianness
3045 ret
= nbt
._bt
_ctf
_writer
_set
_byte
_order
(self
._w
, byte_order
)
3048 raise ValueError("Could not set trace's byte order.")