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
):
991 """Do not instantiate."""
994 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
999 Return the length of an array or a negative
1003 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
1006 def element_declaration(self
):
1008 Return element declaration.
1011 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
1013 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1016 class SequenceFieldDeclaration(FieldDeclaration
):
1017 """Do not instantiate."""
1020 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
1023 def element_declaration(self
):
1025 Return element declaration.
1028 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
1030 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
1033 class FloatFieldDeclaration(FieldDeclaration
):
1034 """Do not instantiate."""
1037 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
1040 class StructureFieldDeclaration(FieldDeclaration
):
1041 """Do not instantiate."""
1044 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
1047 class StringFieldDeclaration(FieldDeclaration
):
1048 """Do not instantiate."""
1051 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
1054 class VariantFieldDeclaration(FieldDeclaration
):
1055 """Do not instantiate."""
1058 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
1063 Return the last error code encountered while
1064 accessing a field and reset the error flag.
1065 Return 0 if no error, a negative value otherwise.
1068 return nbt
._bt
_ctf
_field
_get
_error
()
1071 def _create_field_declaration(declaration_ptr
, name
, scope
):
1073 Private field declaration factory.
1076 if declaration_ptr
is None:
1077 raise ValueError("declaration_ptr must be valid")
1078 if scope
not in _scopes
:
1079 raise ValueError("Invalid scope provided")
1081 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
1084 if type == CTFTypeId
.INTEGER
:
1085 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
1086 elif type == CTFTypeId
.ENUM
:
1087 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
1088 elif type == CTFTypeId
.ARRAY
:
1089 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
1090 elif type == CTFTypeId
.SEQUENCE
:
1091 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
1092 elif type == CTFTypeId
.FLOAT
:
1093 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
1094 elif type == CTFTypeId
.STRUCT
:
1095 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
1096 elif type == CTFTypeId
.STRING
:
1097 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
1098 elif type == CTFTypeId
.VARIANT
:
1099 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
1103 declaration
._fd
= declaration_ptr
1104 declaration
._s
= scope
1105 declaration
._name
= name
1111 def __init__(self
, definition_ptr
, scope
):
1112 self
._d
= definition_ptr
1115 if scope
not in _scopes
:
1116 ValueError("Invalid scope provided")
1120 """Return the name of a field or None on error."""
1122 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1126 """Return the type of a field or -1 if unknown."""
1128 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1131 def declaration(self
):
1132 """Return the associated Definition object."""
1134 return _create_field_declaration(
1135 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1137 def _get_enum_str(self
):
1139 Return the string matching the current enumeration.
1140 Return None on error.
1143 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1145 def _get_array_element_at(self
, index
):
1147 Return the array's element at position index.
1148 Return None on error
1151 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1153 if array_ptr
is None:
1156 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1158 if definition_ptr
is None:
1161 return _Definition(definition_ptr
, self
.scope
)
1163 def _get_sequence_len(self
):
1165 Return the len of a sequence or a negative
1169 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1171 return nbt
._bt
_sequence
_len
(seq
)
1173 def _get_sequence_element_at(self
, index
):
1175 Return the sequence's element at position index,
1176 otherwise return None
1179 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1182 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1184 if definition_ptr
is not None:
1185 return _Definition(definition_ptr
, self
.scope
)
1187 def _get_uint64(self
):
1189 Return the value associated with the field.
1190 If the field does not exist or is not of the type requested,
1191 the value returned is undefined. To check if an error occured,
1192 use the field_error() function after accessing a field.
1195 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1197 def _get_int64(self
):
1199 Return the value associated with the field.
1200 If the field does not exist or is not of the type requested,
1201 the value returned is undefined. To check if an error occured,
1202 use the field_error() function after accessing a field.
1205 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1207 def _get_char_array(self
):
1209 Return the value associated with the field.
1210 If the field does not exist or is not of the type requested,
1211 the value returned is undefined. To check if an error occurred,
1212 use the field_error() function after accessing a field.
1215 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1219 Return the value associated with the field.
1220 If the field does not exist or is not of the type requested,
1221 the value returned is undefined. To check if an error occurred,
1222 use the field_error() function after accessing a field.
1225 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1227 def _get_float(self
):
1229 Return the value associated with the field.
1230 If the field does not exist or is not of the type requested,
1231 the value returned is undefined. To check if an error occurred,
1232 use the field_error() function after accessing a field.
1235 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1237 def _get_variant(self
):
1239 Return the variant's selected field.
1240 If the field does not exist or is not of the type requested,
1241 the value returned is undefined. To check if an error occurred,
1242 use the field_error() function after accessing a field.
1245 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1247 def _get_struct_field_count(self
):
1249 Return the number of fields contained in the structure.
1250 If the field does not exist or is not of the type requested,
1251 the value returned is undefined.
1254 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1256 def _get_struct_field_at(self
, i
):
1258 Return the structure's field at position i.
1259 If the field does not exist or is not of the type requested,
1260 the value returned is undefined. To check if an error occurred,
1261 use the field_error() function after accessing a field.
1264 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1269 Return the value associated with the field according to its type.
1270 Return None on error.
1276 if id == CTFTypeId
.STRING
:
1277 value
= self
._get
_str
()
1278 elif id == CTFTypeId
.ARRAY
:
1279 element_decl
= self
.declaration
.element_declaration
1281 if ((element_decl
.type == CTFTypeId
.INTEGER
1282 and element_decl
.length
== 8)
1283 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1284 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1288 for i
in range(self
.declaration
.length
):
1289 element
= self
._get
_array
_element
_at
(i
)
1290 value
.append(element
.value
)
1291 elif id == CTFTypeId
.INTEGER
:
1292 if self
.declaration
.signedness
== 0:
1293 value
= self
._get
_uint
64()
1295 value
= self
._get
_int
64()
1296 elif id == CTFTypeId
.ENUM
:
1297 value
= self
._get
_enum
_str
()
1298 elif id == CTFTypeId
.SEQUENCE
:
1299 element_decl
= self
.declaration
.element_declaration
1301 if ((element_decl
.type == CTFTypeId
.INTEGER
1302 and element_decl
.length
== 8)
1303 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1304 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1306 seq_len
= self
._get
_sequence
_len
()
1309 for i
in range(seq_len
):
1310 evDef
= self
._get
_sequence
_element
_at
(i
)
1311 value
.append(evDef
.value
)
1312 elif id == CTFTypeId
.FLOAT
:
1313 value
= self
._get
_float
()
1314 elif id == CTFTypeId
.VARIANT
:
1315 variant
= _Definition
.__new
__(_Definition
)
1316 variant
._d
= self
._get
_variant
()
1317 value
= variant
.value
1318 elif id == CTFTypeId
.STRUCT
:
1321 for i
in range(self
._get
_struct
_field
_count
()):
1322 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1323 value
[member
.name
] = member
.value
1327 "Error occurred while accessing field {} of type {}".format(
1329 CTFTypeId
.type_name(id)))
1335 """Return the scope of a field or None on error."""
1341 # Used to compare to -1ULL in error checks
1342 _MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
1344 class EnumerationMapping
:
1346 Enumeration mapping class. start and end values are inclusive.
1349 def __init__(self
, name
, start
, end
):
1355 def __init__(self
, name
):
1356 self
._c
= nbt
._bt
_ctf
_clock
_create
(name
)
1359 raise ValueError("Invalid clock name.")
1362 nbt
._bt
_ctf
_clock
_put
(self
._c
)
1367 Get the clock's name.
1370 name
= nbt
._bt
_ctf
_clock
_get
_name
(self
._c
)
1373 raise ValueError("Invalid clock instance.")
1378 def description(self
):
1380 Get the clock's description. None if unset.
1383 return nbt
._bt
_ctf
_clock
_get
_description
(self
._c
)
1386 def description(self
, desc
):
1388 Set the clock's description. The description appears in the clock's TSDL
1392 ret
= nbt
._bt
_ctf
_clock
_set
_description
(self
._c
, str(desc
))
1395 raise ValueError("Invalid clock description.")
1398 def frequency(self
):
1400 Get the clock's frequency (Hz).
1403 freq
= nbt
._bt
_ctf
_clock
_get
_frequency
(self
._c
)
1405 if freq
== CTFWriter
._MAX
_UINT
64:
1406 raise ValueError("Invalid clock instance")
1411 def frequency(self
, freq
):
1413 Set the clock's frequency (Hz).
1416 ret
= nbt
._bt
_ctf
_clock
_set
_frequency
(self
._c
, freq
)
1419 raise ValueError("Invalid frequency value.")
1422 def precision(self
):
1424 Get the clock's precision (in clock ticks).
1427 precision
= nbt
._bt
_ctf
_clock
_get
_precision
(self
._c
)
1429 if precision
== CTFWriter
._MAX
_UINT
64:
1430 raise ValueError("Invalid clock instance")
1435 def precision(self
, precision
):
1437 Set the clock's precision (in clock ticks).
1440 ret
= nbt
._bt
_ctf
_clock
_set
_precision
(self
._c
, precision
)
1443 def offset_seconds(self
):
1445 Get the clock's offset in seconds from POSIX.1 Epoch.
1448 offset_s
= nbt
._bt
_ctf
_clock
_get
_offset
_s
(self
._c
)
1450 if offset_s
== CTFWriter
._MAX
_UINT
64:
1451 raise ValueError("Invalid clock instance")
1455 @offset_seconds.setter
1456 def offset_seconds(self
, offset_s
):
1458 Set the clock's offset in seconds from POSIX.1 Epoch.
1461 ret
= nbt
._bt
_ctf
_clock
_set
_offset
_s
(self
._c
, offset_s
)
1464 raise ValueError("Invalid offset value.")
1469 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1472 offset
= nbt
._bt
_ctf
_clock
_get
_offset
(self
._c
)
1474 if offset
== CTFWriter
._MAX
_UINT
64:
1475 raise ValueError("Invalid clock instance")
1480 def offset(self
, offset
):
1482 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1485 ret
= nbt
._bt
_ctf
_clock
_set
_offset
(self
._c
, offset
)
1488 raise ValueError("Invalid offset value.")
1493 Get a clock's absolute attribute. A clock is absolute if the clock
1494 is a global reference across the trace's other clocks.
1497 is_absolute
= nbt
._bt
_ctf
_clock
_get
_is
_absolute
(self
._c
)
1499 if is_absolute
== -1:
1500 raise ValueError("Invalid clock instance")
1502 return False if is_absolute
== 0 else True
1505 def absolute(self
, is_absolute
):
1507 Set a clock's absolute attribute. A clock is absolute if the clock
1508 is a global reference across the trace's other clocks.
1511 ret
= nbt
._bt
_ctf
_clock
_set
_is
_absolute
(self
._c
, int(is_absolute
))
1514 raise ValueError("Could not set the clock's absolute attribute.")
1519 Get a clock's UUID (an object of type UUID).
1525 ret
, value
= nbt
._bt
_python
_ctf
_clock
_get
_uuid
_index
(self
._c
, i
)
1528 raise ValueError("Invalid clock instance")
1530 uuid_list
.append(value
)
1532 return UUID(bytes
=bytes(uuid_list
))
1535 def uuid(self
, uuid
):
1537 Set a clock's UUID (an object of type UUID).
1540 uuid_bytes
= uuid
.bytes
1542 if len(uuid_bytes
) != 16:
1543 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1545 for i
in range(len(uuid_bytes
)):
1546 ret
= nbt
._bt
_python
_ctf
_clock
_set
_uuid
_index
(self
._c
, i
,
1550 raise ValueError("Invalid clock instance")
1555 Get the current time in nanoseconds since the clock's origin (offset and
1556 offset_s attributes).
1559 time
= nbt
._bt
_ctf
_clock
_get
_time
(self
._c
)
1561 if time
== CTFWriter
._MAX
_UINT
64:
1562 raise ValueError("Invalid clock instance")
1567 def time(self
, time
):
1569 Set the current time in nanoseconds since the clock's origin (offset and
1570 offset_s attributes). The clock's value will be sampled as events are
1571 appended to a stream.
1574 ret
= nbt
._bt
_ctf
_clock
_set
_time
(self
._c
, time
)
1577 raise ValueError("Invalid time value.")
1579 class FieldDeclaration
:
1581 FieldDeclaration should not be instantiated directly. Instantiate
1582 one of the concrete FieldDeclaration classes.
1586 # These values are based on the bt_ctf_integer_base enum
1587 # declared in event-types.h.
1588 INTEGER_BASE_UNKNOWN
= -1
1589 INTEGER_BASE_BINARY
= 2
1590 INTEGER_BASE_OCTAL
= 8
1591 INTEGER_BASE_DECIMAL
= 10
1592 INTEGER_BASE_HEXADECIMAL
= 16
1595 if self
._ft
is None:
1596 raise ValueError("FieldDeclaration creation failed.")
1599 nbt
._bt
_ctf
_field
_type
_put
(self
._ft
)
1602 def _create_field_declaration_from_native_instance(
1603 native_field_declaration
):
1605 CTFTypeId
.INTEGER
: CTFWriter
.IntegerFieldDeclaration
,
1606 CTFTypeId
.FLOAT
: CTFWriter
.FloatFieldDeclaration
,
1607 CTFTypeId
.ENUM
: CTFWriter
.EnumerationFieldDeclaration
,
1608 CTFTypeId
.STRING
: CTFWriter
.StringFieldDeclaration
,
1609 CTFTypeId
.STRUCT
: CTFWriter
.StructureFieldDeclaration
,
1610 CTFTypeId
.VARIANT
: CTFWriter
.VariantFieldDeclaration
,
1611 CTFTypeId
.ARRAY
: CTFWriter
.ArrayFieldDeclaration
,
1612 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceFieldDeclaration
1615 field_type_id
= nbt
._bt
_ctf
_field
_type
_get
_type
_id
(native_field_declaration
)
1617 if field_type_id
== CTFTypeId
.UNKNOWN
:
1618 raise TypeError("Invalid field instance")
1620 declaration
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
1621 declaration
._ft
= native_field_declaration
1622 declaration
.__class
__ = type_dict
[field_type_id
]
1627 def alignment(self
):
1629 Get the field declaration's alignment. Returns -1 on error.
1632 return nbt
._bt
_ctf
_field
_type
_get
_alignment
(self
._ft
)
1635 def alignment(self
, alignment
):
1637 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1638 some types, such as structures and string, may impose other alignment
1642 ret
= nbt
._bt
_ctf
_field
_type
_set
_alignment
(self
._ft
, alignment
)
1645 raise ValueError("Invalid alignment value.")
1648 def byte_order(self
):
1650 Get the field declaration's byte order. One of the ByteOrder's constant.
1653 return nbt
._bt
_ctf
_field
_type
_get
_byte
_order
(self
._ft
)
1656 def byte_order(self
, byte_order
):
1658 Set the field declaration's byte order. Use constants defined in the ByteOrder
1662 ret
= nbt
._bt
_ctf
_field
_type
_set
_byte
_order
(self
._ft
, byte_order
)
1665 raise ValueError("Could not set byte order value.")
1667 class IntegerFieldDeclaration(FieldDeclaration
):
1668 def __init__(self
, size
):
1670 Create a new integer field declaration of the given size.
1672 self
._ft
= nbt
._bt
_ctf
_field
_type
_integer
_create
(size
)
1678 Get an integer's size.
1681 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_size
(self
._ft
)
1684 raise ValueError("Could not get Integer's size attribute.")
1691 Get an integer's signedness attribute.
1694 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_signed
(self
._ft
)
1697 raise ValueError("Could not get Integer's signed attribute.")
1704 def signed(self
, signed
):
1706 Set an integer's signedness attribute.
1709 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_signed
(self
._ft
, signed
)
1712 raise ValueError("Could not set Integer's signed attribute.")
1717 Get the integer's base used to pretty-print the resulting trace.
1718 Returns a constant from the FieldDeclaration.IntegerBase class.
1721 return nbt
._bt
_ctf
_field
_type
_integer
_get
_base
(self
._ft
)
1724 def base(self
, base
):
1726 Set the integer's base used to pretty-print the resulting trace.
1727 The base must be a constant of the FieldDeclarationIntegerBase class.
1730 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_base
(self
._ft
, base
)
1733 raise ValueError("Could not set Integer's base.")
1738 Get the integer's encoding (one of the constants of the
1739 CTFStringEncoding class).
1740 Returns a constant from the CTFStringEncoding class.
1743 return nbt
._bt
_ctf
_field
_type
_integer
_get
_encoding
(self
._ft
)
1746 def encoding(self
, encoding
):
1748 An integer encoding may be set to signal that the integer must be printed
1749 as a text character. Must be a constant from the CTFStringEncoding class.
1752 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_encoding
(self
._ft
, encoding
)
1755 raise ValueError("Could not set Integer's encoding.")
1757 class EnumerationFieldDeclaration(FieldDeclaration
):
1758 def __init__(self
, integer_type
):
1760 Create a new enumeration field declaration with the given underlying container type.
1762 isinst
= isinstance(integer_type
, CTFWriter
.IntegerFieldDeclaration
)
1764 if integer_type
is None or not isinst
:
1765 raise TypeError("Invalid integer container.")
1767 self
._ft
= nbt
._bt
_ctf
_field
_type
_enumeration
_create
(integer_type
._ft
)
1771 def container(self
):
1773 Get the enumeration's underlying container type.
1776 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_container
_type
(self
._ft
)
1779 raise TypeError("Invalid enumeration declaration")
1781 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1783 def add_mapping(self
, name
, range_start
, range_end
):
1785 Add a mapping to the enumeration. The range's values are inclusive.
1788 if range_start
< 0 or range_end
< 0:
1789 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
(self
._ft
,
1794 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
_unsigned
(self
._ft
,
1800 raise ValueError("Could not add mapping to enumeration declaration.")
1805 Generator returning instances of EnumerationMapping.
1808 signed
= self
.container
.signed
1810 count
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_count
(self
._ft
)
1812 for i
in range(count
):
1814 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, i
)
1816 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, i
)
1819 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1820 raise TypeError(msg
)
1822 name
, range_start
, range_end
= ret
1823 yield CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1825 def get_mapping_by_name(self
, name
):
1827 Get a mapping by name (EnumerationMapping).
1830 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_name
(self
._ft
, name
)
1835 if self
.container
.signed
:
1836 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1838 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1841 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1842 raise TypeError(msg
)
1844 name
, range_start
, range_end
= ret
1846 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1848 def get_mapping_by_value(self
, value
):
1850 Get a mapping by value (EnumerationMapping).
1854 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_value
(self
._ft
, value
)
1856 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_unsigned
_value
(self
._ft
, value
)
1861 if self
.container
.signed
:
1862 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1864 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1867 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1868 raise TypeError(msg
)
1870 name
, range_start
, range_end
= ret
1872 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1874 class FloatFieldDeclaration(FieldDeclaration
):
1882 Create a new floating point field declaration.
1885 self
._ft
= nbt
._bt
_ctf
_field
_type
_floating
_point
_create
()
1889 def exponent_digits(self
):
1891 Get the number of exponent digits used to store the floating point field.
1894 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_exponent
_digits
(self
._ft
)
1898 "Could not get Floating point exponent digit count")
1902 @exponent_digits.setter
1903 def exponent_digits(self
, exponent_digits
):
1905 Set the number of exponent digits to use to store the floating point field.
1906 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1907 are defined as constants of this class.
1910 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_exponent
_digits
(self
._ft
,
1914 raise ValueError("Could not set exponent digit count.")
1917 def mantissa_digits(self
):
1919 Get the number of mantissa digits used to store the floating point field.
1922 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_mantissa
_digits
(self
._ft
)
1925 raise TypeError("Could not get Floating point mantissa digit count")
1929 @mantissa_digits.setter
1930 def mantissa_digits(self
, mantissa_digits
):
1932 Set the number of mantissa digits to use to store the floating point field.
1933 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1934 are defined as constants of this class.
1937 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_mantissa
_digits
(self
._ft
,
1941 raise ValueError("Could not set mantissa digit count.")
1943 class FloatingPointFieldDeclaration(FloatFieldDeclaration
):
1946 class StructureFieldDeclaration(FieldDeclaration
):
1949 Create a new structure field declaration.
1952 self
._ft
= nbt
._bt
_ctf
_field
_type
_structure
_create
()
1955 def add_field(self
, field_type
, field_name
):
1957 Add a field of type "field_type" to the structure.
1960 ret
= nbt
._bt
_ctf
_field
_type
_structure
_add
_field
(self
._ft
,
1965 raise ValueError("Could not add field to structure.")
1970 Generator returning the structure's field as tuples of (field name, field declaration).
1973 count
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_count
(self
._ft
)
1976 raise TypeError("Could not get Structure field count")
1978 for i
in range(count
):
1979 field_name
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_name
(self
._ft
, i
)
1981 if field_name
is None:
1982 msg
= "Could not get Structure field name at index {}".format(i
)
1983 raise TypeError(msg
)
1985 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_type
(self
._ft
, i
)
1987 if field_type_native
is None:
1988 msg
= "Could not get Structure field type at index {}".format(i
)
1989 raise TypeError(msg
)
1991 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1992 yield (field_name
, field_type
)
1994 def get_field_by_name(self
, name
):
1996 Get a field declaration by name (FieldDeclaration).
1999 field_type_native
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_type
_by
_name
(self
._ft
, name
)
2001 if field_type_native
is None:
2002 msg
= "Could not find Structure field with name {}".format(name
)
2003 raise TypeError(msg
)
2005 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2007 class VariantFieldDeclaration(FieldDeclaration
):
2008 def __init__(self
, enum_tag
, tag_name
):
2010 Create a new variant field declaration.
2013 isinst
= isinstance(enum_tag
, CTFWriter
.EnumerationFieldDeclaration
)
2014 if enum_tag
is None or not isinst
:
2015 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
2017 self
._ft
= nbt
._bt
_ctf
_field
_type
_variant
_create
(enum_tag
._ft
,
2024 Get the variant's tag name.
2027 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_name
(self
._ft
)
2030 raise TypeError("Could not get Variant tag name")
2037 Get the variant's tag type.
2040 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_type
(self
._ft
)
2043 raise TypeError("Could not get Variant tag type")
2045 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2047 def add_field(self
, field_type
, field_name
):
2049 Add a field of type "field_type" to the variant.
2052 ret
= nbt
._bt
_ctf
_field
_type
_variant
_add
_field
(self
._ft
,
2057 raise ValueError("Could not add field to variant.")
2062 Generator returning the variant's field as tuples of (field name, field declaration).
2065 count
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_count
(self
._ft
)
2068 raise TypeError("Could not get Variant field count")
2070 for i
in range(count
):
2071 field_name
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_name
(self
._ft
, i
)
2073 if field_name
is None:
2074 msg
= "Could not get Variant field name at index {}".format(i
)
2075 raise TypeError(msg
)
2077 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_type
(self
._ft
, i
)
2079 if field_type_native
is None:
2080 msg
= "Could not get Variant field type at index {}".format(i
)
2081 raise TypeError(msg
)
2083 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2084 yield (field_name
, field_type
)
2086 def get_field_by_name(self
, name
):
2088 Get a field declaration by name (FieldDeclaration).
2091 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_by
_name
(self
._ft
,
2094 if field_type_native
is None:
2095 msg
= "Could not find Variant field with name {}".format(name
)
2096 raise TypeError(msg
)
2098 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2100 def get_field_from_tag(self
, tag
):
2102 Get a field declaration from tag (EnumerationField).
2105 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_from
_tag
(self
._ft
, tag
._f
)
2107 if field_type_native
is None:
2108 msg
= "Could not find Variant field with tag value {}".format(tag
.value
)
2109 raise TypeError(msg
)
2111 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2113 class ArrayFieldDeclaration(FieldDeclaration
):
2114 def __init__(self
, element_type
, length
):
2116 Create a new array field declaration.
2119 self
._ft
= nbt
._bt
_ctf
_field
_type
_array
_create
(element_type
._ft
,
2124 def element_type(self
):
2126 Get the array's element type.
2129 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_element
_type
(self
._ft
)
2132 raise TypeError("Could not get Array element type")
2134 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2139 Get the array's length.
2142 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_length
(self
._ft
)
2145 raise TypeError("Could not get Array length")
2149 class SequenceFieldDeclaration(FieldDeclaration
):
2150 def __init__(self
, element_type
, length_field_name
):
2152 Create a new sequence field declaration.
2155 self
._ft
= nbt
._bt
_ctf
_field
_type
_sequence
_create
(element_type
._ft
,
2156 str(length_field_name
))
2160 def element_type(self
):
2162 Get the sequence's element type.
2165 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_element
_type
(self
._ft
)
2168 raise TypeError("Could not get Sequence element type")
2170 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
2173 def length_field_name(self
):
2175 Get the sequence's length field name.
2178 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_length
_field
_name
(self
._ft
)
2181 raise TypeError("Could not get Sequence length field name")
2185 class StringFieldDeclaration(FieldDeclaration
):
2188 Create a new string field declaration.
2191 self
._ft
= nbt
._bt
_ctf
_field
_type
_string
_create
()
2197 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
2200 return nbt
._bt
_ctf
_field
_type
_string
_get
_encoding
(self
._ft
)
2203 def encoding(self
, encoding
):
2205 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
2208 ret
= nbt
._bt
_ctf
_field
_type
_string
_set
_encoding
(self
._ft
, encoding
)
2210 raise ValueError("Could not set string encoding.")
2213 def create_field(field_type
):
2215 Create an instance of a field.
2217 isinst
= isinstance(field_type
, CTFWriter
.FieldDeclaration
)
2219 if field_type
is None or not isinst
:
2220 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
2222 if isinstance(field_type
, CTFWriter
.IntegerFieldDeclaration
):
2223 return CTFWriter
.IntegerField(field_type
)
2224 elif isinstance(field_type
, CTFWriter
.EnumerationFieldDeclaration
):
2225 return CTFWriter
.EnumerationField(field_type
)
2226 elif isinstance(field_type
, CTFWriter
.FloatFieldDeclaration
):
2227 return CTFWriter
.FloatingPointField(field_type
)
2228 elif isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2229 return CTFWriter
.StructureField(field_type
)
2230 elif isinstance(field_type
, CTFWriter
.VariantFieldDeclaration
):
2231 return CTFWriter
.VariantField(field_type
)
2232 elif isinstance(field_type
, CTFWriter
.ArrayFieldDeclaration
):
2233 return CTFWriter
.ArrayField(field_type
)
2234 elif isinstance(field_type
, CTFWriter
.SequenceFieldDeclaration
):
2235 return CTFWriter
.SequenceField(field_type
)
2236 elif isinstance(field_type
, CTFWriter
.StringFieldDeclaration
):
2237 return CTFWriter
.StringField(field_type
)
2241 Base class, do not instantiate.
2244 def __init__(self
, field_type
):
2245 if not isinstance(field_type
, CTFWriter
.FieldDeclaration
):
2246 raise TypeError("Invalid field_type argument.")
2248 self
._f
= nbt
._bt
_ctf
_field
_create
(field_type
._ft
)
2251 raise ValueError("Field creation failed.")
2254 nbt
._bt
_ctf
_field
_put
(self
._f
)
2257 def _create_field_from_native_instance(native_field_instance
):
2259 CTFTypeId
.INTEGER
: CTFWriter
.IntegerField
,
2260 CTFTypeId
.FLOAT
: CTFWriter
.FloatingPointField
,
2261 CTFTypeId
.ENUM
: CTFWriter
.EnumerationField
,
2262 CTFTypeId
.STRING
: CTFWriter
.StringField
,
2263 CTFTypeId
.STRUCT
: CTFWriter
.StructureField
,
2264 CTFTypeId
.VARIANT
: CTFWriter
.VariantField
,
2265 CTFTypeId
.ARRAY
: CTFWriter
.ArrayField
,
2266 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceField
2269 field_type
= nbt
._bt
_python
_get
_field
_type
(native_field_instance
)
2271 if field_type
== CTFTypeId
.UNKNOWN
:
2272 raise TypeError("Invalid field instance")
2274 field
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
2275 field
._f
= native_field_instance
2276 field
.__class
__ = type_dict
[field_type
]
2281 def declaration(self
):
2282 native_field_type
= nbt
._bt
_ctf
_field
_get
_type
(self
._f
)
2284 if native_field_type
is None:
2285 raise TypeError("Invalid field instance")
2286 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(
2289 class IntegerField(Field
):
2293 Get an integer field's value.
2296 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2299 raise TypeError("Invalid integer instance.")
2302 ret
, value
= nbt
._bt
_ctf
_field
_unsigned
_integer
_get
_value
(self
._f
)
2304 ret
, value
= nbt
._bt
_ctf
_field
_signed
_integer
_get
_value
(self
._f
)
2307 raise ValueError("Could not get integer field value.")
2312 def value(self
, value
):
2314 Set an integer field's value.
2317 if not isinstance(value
, int):
2318 raise TypeError("IntegerField's value must be an int")
2320 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2322 raise TypeError("Invalid integer instance.")
2325 ret
= nbt
._bt
_ctf
_field
_unsigned
_integer
_set
_value
(self
._f
, value
)
2327 ret
= nbt
._bt
_ctf
_field
_signed
_integer
_set
_value
(self
._f
, value
)
2330 raise ValueError("Could not set integer field value.")
2332 class EnumerationField(Field
):
2334 def container(self
):
2336 Return the enumeration's underlying container field (an integer field).
2339 container
= CTFWriter
.IntegerField
.__new
__(CTFWriter
.IntegerField
)
2340 container
._f
= nbt
._bt
_ctf
_field
_enumeration
_get
_container
(self
._f
)
2342 if container
._f
is None:
2343 raise TypeError("Invalid enumeration field type.")
2350 Get the enumeration field's mapping name.
2353 value
= nbt
._bt
_ctf
_field
_enumeration
_get
_mapping
_name
(self
._f
)
2356 raise ValueError("Could not get enumeration's mapping name.")
2361 def value(self
, value
):
2363 Set the enumeration field's value. Must be an integer as mapping names
2367 if not isinstance(value
, int):
2368 raise TypeError("EnumerationField value must be an int")
2370 self
.container
.value
= value
2372 class FloatingPointField(Field
):
2376 Get a floating point field's value.
2379 ret
, value
= nbt
._bt
_ctf
_field
_floating
_point
_get
_value
(self
._f
)
2382 raise ValueError("Could not get floating point field value.")
2387 def value(self
, value
):
2389 Set a floating point field's value.
2392 if not isinstance(value
, int) and not isinstance(value
, float):
2393 raise TypeError("Value must be either a float or an int")
2395 ret
= nbt
._bt
_ctf
_field
_floating
_point
_set
_value
(self
._f
, float(value
))
2398 raise ValueError("Could not set floating point field value.")
2400 # oops!! This class is provided to ensure backward-compatibility since
2401 # a stable release publicly exposed this abomination.
2402 class FloatFieldingPoint(FloatingPointField
):
2405 class StructureField(Field
):
2406 def field(self
, field_name
):
2408 Get the structure's field corresponding to the provided field name.
2411 native_instance
= nbt
._bt
_ctf
_field
_structure
_get
_field
(self
._f
,
2414 if native_instance
is None:
2415 raise ValueError("Invalid field_name provided.")
2417 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2419 class VariantField(Field
):
2420 def field(self
, tag
):
2422 Return the variant's selected field. The "tag" field is the selector enum field.
2425 native_instance
= nbt
._bt
_ctf
_field
_variant
_get
_field
(self
._f
, tag
._f
)
2427 if native_instance
is None:
2428 raise ValueError("Invalid tag provided.")
2430 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2432 class ArrayField(Field
):
2433 def field(self
, index
):
2435 Return the array's field at position "index".
2438 native_instance
= nbt
._bt
_ctf
_field
_array
_get
_field
(self
._f
, index
)
2440 if native_instance
is None:
2441 raise IndexError("Invalid index provided.")
2443 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2445 class SequenceField(Field
):
2449 Get the sequence's length field (IntegerField).
2452 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_length
(self
._f
)
2454 if native_instance
is None:
2457 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2460 def length(self
, length_field
):
2462 Set the sequence's length field (IntegerField).
2465 if not isinstance(length_field
, CTFWriter
.IntegerField
):
2466 raise TypeError("Invalid length field.")
2468 if length_field
.declaration
.signed
:
2469 raise TypeError("Sequence field length must be unsigned")
2471 ret
= nbt
._bt
_ctf
_field
_sequence
_set
_length
(self
._f
, length_field
._f
)
2474 raise ValueError("Could not set sequence length.")
2476 def field(self
, index
):
2478 Return the sequence's field at position "index".
2481 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_field
(self
._f
, index
)
2483 if native_instance
is None:
2484 raise ValueError("Could not get sequence element at index.")
2486 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2488 class StringField(Field
):
2492 Get a string field's value.
2495 return nbt
._bt
_ctf
_field
_string
_get
_value
(self
._f
)
2498 def value(self
, value
):
2500 Set a string field's value.
2503 ret
= nbt
._bt
_ctf
_field
_string
_set
_value
(self
._f
, str(value
))
2506 raise ValueError("Could not set string field value.")
2509 def __init__(self
, name
):
2511 Create a new event class of the given name.
2514 self
._ec
= nbt
._bt
_ctf
_event
_class
_create
(name
)
2516 if self
._ec
is None:
2517 raise ValueError("Event class creation failed.")
2520 nbt
._bt
_ctf
_event
_class
_put
(self
._ec
)
2522 def add_field(self
, field_type
, field_name
):
2524 Add a field of type "field_type" to the event class.
2527 ret
= nbt
._bt
_ctf
_event
_class
_add
_field
(self
._ec
, field_type
._ft
,
2531 raise ValueError("Could not add field to event class.")
2536 Get the event class' name.
2539 name
= nbt
._bt
_ctf
_event
_class
_get
_name
(self
._ec
)
2542 raise TypeError("Could not get EventClass name")
2549 Get the event class' id. Returns a negative value if unset.
2552 id = nbt
._bt
_ctf
_event
_class
_get
_id
(self
._ec
)
2555 raise TypeError("Could not get EventClass id")
2562 Set the event class' id. Throws a TypeError if the event class
2563 is already registered to a stream class.
2566 ret
= nbt
._bt
_ctf
_event
_class
_set
_id
(self
._ec
, id)
2569 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
2572 def stream_class(self
):
2574 Get the event class' stream class. Returns None if unset.
2576 stream_class_native
= nbt
._bt
_ctf
_event
_class
_get
_stream
_class
(self
._ec
)
2578 if stream_class_native
is None:
2581 stream_class
= CTFWriter
.StreamClass
.__new
__(CTFWriter
.StreamClass
)
2582 stream_class
._sc
= stream_class_native
2589 Generator returning the event class' fields as tuples of (field name, field declaration).
2592 count
= nbt
._bt
_ctf
_event
_class
_get
_field
_count
(self
._ec
)
2595 raise TypeError("Could not get EventClass' field count")
2597 for i
in range(count
):
2598 field_name
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_name
(self
._ec
, i
)
2600 if field_name
is None:
2601 msg
= "Could not get EventClass' field name at index {}".format(i
)
2602 raise TypeError(msg
)
2604 field_type_native
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_type
(self
._ec
, i
)
2606 if field_type_native
is None:
2607 msg
= "Could not get EventClass' field type at index {}".format(i
)
2608 raise TypeError(msg
)
2610 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2611 yield (field_name
, field_type
)
2613 def get_field_by_name(self
, name
):
2615 Get a field declaration by name (FieldDeclaration).
2618 field_type_native
= nbt
._bt
_ctf
_event
_class
_get
_field
_by
_name
(self
._ec
, name
)
2620 if field_type_native
is None:
2621 msg
= "Could not find EventClass field with name {}".format(name
)
2622 raise TypeError(msg
)
2624 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2627 def __init__(self
, event_class
):
2629 Create a new event of the given event class.
2632 if not isinstance(event_class
, CTFWriter
.EventClass
):
2633 raise TypeError("Invalid event_class argument.")
2635 self
._e
= nbt
._bt
_ctf
_event
_create
(event_class
._ec
)
2638 raise ValueError("Event creation failed.")
2641 nbt
._bt
_ctf
_event
_put
(self
._e
)
2644 def event_class(self
):
2646 Get the event's class.
2649 event_class_native
= nbt
._bt
_ctf
_event
_get
_class
(self
._e
)
2651 if event_class_native
is None:
2654 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2655 event_class
._ec
= event_class_native
2661 Get a clock from event. Returns None if the event's class
2662 is not registered to a stream class.
2665 clock_instance
= nbt
._bt
_ctf
_event
_get
_clock
(self
._e
)
2667 if clock_instance
is None:
2670 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2671 clock
._c
= clock_instance
2675 def payload(self
, field_name
):
2677 Get a field from event.
2680 native_instance
= nbt
._bt
_ctf
_event
_get
_payload
(self
._e
,
2683 if native_instance
is None:
2684 raise ValueError("Could not get event payload.")
2686 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2688 def set_payload(self
, field_name
, value_field
):
2690 Set a manually created field as an event's payload.
2693 if not isinstance(value
, CTFWriter
.Field
):
2694 raise TypeError("Invalid value type.")
2696 ret
= nbt
._bt
_ctf
_event
_set
_payload
(self
._e
, str(field_name
),
2700 raise ValueError("Could not set event field payload.")
2703 def __init__(self
, name
):
2705 Create a new stream class of the given name.
2708 self
._sc
= nbt
._bt
_ctf
_stream
_class
_create
(name
)
2710 if self
._sc
is None:
2711 raise ValueError("Stream class creation failed.")
2714 nbt
._bt
_ctf
_stream
_class
_put
(self
._sc
)
2719 Get a stream class' name.
2722 name
= nbt
._bt
_ctf
_stream
_class
_get
_name
(self
._sc
)
2725 raise TypeError("Could not get StreamClass name")
2732 Get a stream class' clock.
2735 clock_instance
= nbt
._bt
_ctf
_stream
_class
_get
_clock
(self
._sc
)
2737 if clock_instance
is None:
2740 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2741 clock
._c
= clock_instance
2746 def clock(self
, clock
):
2748 Assign a clock to a stream class.
2751 if not isinstance(clock
, CTFWriter
.Clock
):
2752 raise TypeError("Invalid clock type.")
2754 ret
= nbt
._bt
_ctf
_stream
_class
_set
_clock
(self
._sc
, clock
._c
)
2757 raise ValueError("Could not set stream class clock.")
2762 Get a stream class' id.
2765 ret
= nbt
._bt
_ctf
_stream
_class
_get
_id
(self
._sc
)
2768 raise TypeError("Could not get StreamClass id")
2775 Assign an id to a stream class.
2778 ret
= nbt
._bt
_ctf
_stream
_class
_set
_id
(self
._sc
, id)
2781 raise TypeError("Could not set stream class id.")
2784 def event_classes(self
):
2786 Generator returning the stream class' event classes.
2789 count
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
_count
(self
._sc
)
2792 raise TypeError("Could not get StreamClass' event class count")
2794 for i
in range(count
):
2795 event_class_native
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
(self
._sc
, i
)
2797 if event_class_native
is None:
2798 msg
= "Could not get StreamClass' event class at index {}".format(i
)
2799 raise TypeError(msg
)
2801 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2802 event_class
._ec
= event_class_native
2805 def add_event_class(self
, event_class
):
2807 Add an event class to a stream class. New events can be added even after a
2808 stream has been instantiated and events have been appended. However, a stream
2809 will not accept events of a class that has not been added to the stream
2813 if not isinstance(event_class
, CTFWriter
.EventClass
):
2814 raise TypeError("Invalid event_class type.")
2816 ret
= nbt
._bt
_ctf
_stream
_class
_add
_event
_class
(self
._sc
,
2820 raise ValueError("Could not add event class.")
2823 def packet_context_type(self
):
2825 Get the StreamClass' packet context type (StructureFieldDeclaration)
2828 field_type_native
= nbt
._bt
_ctf
_stream
_class
_get
_packet
_context
_type
(self
._sc
)
2830 if field_type_native
is None:
2831 raise ValueError("Invalid StreamClass")
2833 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2837 @packet_context_type.setter
2838 def packet_context_type(self
, field_type
):
2840 Set a StreamClass' packet context type. Must be of type
2841 StructureFieldDeclaration.
2844 if not isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2845 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2847 ret
= nbt
._bt
_ctf
_stream
_class
_set
_packet
_context
_type
(self
._sc
,
2851 raise ValueError("Failed to set packet context type.")
2855 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
2858 nbt
._bt
_ctf
_stream
_put
(self
._s
)
2861 def discarded_events(self
):
2863 Get a stream's discarded event count.
2866 ret
, count
= nbt
._bt
_ctf
_stream
_get
_discarded
_events
_count
(self
._s
)
2869 raise ValueError("Could not get the stream's discarded events count")
2873 def append_discarded_events(self
, event_count
):
2875 Increase the current packet's discarded event count.
2878 nbt
._bt
_ctf
_stream
_append
_discarded
_events
(self
._s
, event_count
)
2880 def append_event(self
, event
):
2882 Append "event" to the stream's current packet. The stream's associated clock
2883 will be sampled during this call. The event shall not be modified after
2884 being appended to a stream.
2887 ret
= nbt
._bt
_ctf
_stream
_append
_event
(self
._s
, event
._e
)
2890 raise ValueError("Could not append event to stream.")
2893 def packet_context(self
):
2895 Get a Stream's packet context field (a StructureField).
2898 native_field
= nbt
._bt
_ctf
_stream
_get
_packet
_context
(self
._s
)
2900 if native_field
is None:
2901 raise ValueError("Invalid Stream.")
2903 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_field
)
2905 @packet_context.setter
2906 def packet_context(self
, field
):
2908 Set a Stream's packet context field (must be a StructureField).
2911 if not isinstance(field
, CTFWriter
.StructureField
):
2912 raise TypeError("Argument field must be of type StructureField")
2914 ret
= nbt
._bt
_ctf
_stream
_set
_packet
_context
(self
._s
, field
._f
)
2917 raise ValueError("Invalid packet context field.")
2921 The stream's current packet's events will be flushed to disk. Events
2922 subsequently appended to the stream will be added to a new packet.
2925 ret
= nbt
._bt
_ctf
_stream
_flush
(self
._s
)
2928 raise ValueError("Could not flush stream.")
2931 def __init__(self
, path
):
2933 Create a new writer that will produce a trace in the given path.
2936 self
._w
= nbt
._bt
_ctf
_writer
_create
(path
)
2939 raise ValueError("Writer creation failed.")
2942 nbt
._bt
_ctf
_writer
_put
(self
._w
)
2944 def create_stream(self
, stream_class
):
2946 Create a new stream instance and register it to the writer.
2949 if not isinstance(stream_class
, CTFWriter
.StreamClass
):
2950 raise TypeError("Invalid stream_class type.")
2952 stream
= CTFWriter
.Stream
.__new
__(CTFWriter
.Stream
)
2953 stream
._s
= nbt
._bt
_ctf
_writer
_create
_stream
(self
._w
, stream_class
._sc
)
2957 def add_environment_field(self
, name
, value
):
2959 Add an environment field to the trace.
2962 ret
= nbt
._bt
_ctf
_writer
_add
_environment
_field
(self
._w
, str(name
),
2966 raise ValueError("Could not add environment field to trace.")
2968 def add_clock(self
, clock
):
2970 Add a clock to the trace. Clocks assigned to stream classes must be
2971 registered to the writer.
2974 ret
= nbt
._bt
_ctf
_writer
_add
_clock
(self
._w
, clock
._c
)
2977 raise ValueError("Could not add clock to Writer.")
2982 Get the trace's TSDL meta-data.
2985 return nbt
._bt
_ctf
_writer
_get
_metadata
_string
(self
._w
)
2987 def flush_metadata(self
):
2989 Flush the trace's metadata to the metadata file.
2992 nbt
._bt
_ctf
_writer
_flush
_metadata
(self
._w
)
2995 def byte_order(self
):
2997 Get the trace's byte order. Must be a constant from the ByteOrder
3001 raise NotImplementedError("Getter not implemented.")
3004 def byte_order(self
, byte_order
):
3006 Set the trace's byte order. Must be a constant from the ByteOrder
3007 class. Defaults to the host machine's endianness
3010 ret
= nbt
._bt
_ctf
_writer
_set
_byte
_order
(self
._w
, byte_order
)
3013 raise ValueError("Could not set trace's byte order.")