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 def print_format_list(babeltrace_file
):
249 Print a list of available formats to file.
251 babeltrace_file must be a File instance opened in write mode.
255 if babeltrace_file
._file
is not None:
256 nbt
._bt
_print
_format
_list
(babeltrace_file
._file
)
257 except AttributeError:
258 raise TypeError("in print_format_list, argument 1 must be a File instance")
261 # Based on enum bt_clock_type in clock-type.h
269 The TraceHandle allows the user to manipulate a trace file directly.
270 It is a unique identifier representing a trace file.
275 raise NotImplementedError("TraceHandle cannot be instantiated")
278 return "Babeltrace TraceHandle: trace_id('{0}')".format(self
._id
)
282 """Return the TraceHandle id."""
288 """Return the path of a TraceHandle."""
290 return nbt
._bt
_trace
_handle
_get
_path
(self
._trace
_collection
._tc
,
294 def timestamp_begin(self
):
295 """Return the creation time of the buffers of a trace."""
297 return nbt
._bt
_trace
_handle
_get
_timestamp
_begin
(self
._trace
_collection
._tc
,
299 _ClockType
.CLOCK_REAL
)
302 def timestamp_end(self
):
303 """Return the destruction timestamp of the buffers of a trace."""
305 return nbt
._bt
_trace
_handle
_get
_timestamp
_end
(self
._trace
_collection
._tc
,
307 _ClockType
.CLOCK_REAL
)
312 Generator returning all events (EventDeclaration) in a trace.
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
:
336 # Based on the enum in ctf-writer/writer.h
338 BYTE_ORDER_NATIVE
= 0
339 BYTE_ORDER_LITTLE_ENDIAN
= 1
340 BYTE_ORDER_BIG_ENDIAN
= 2
341 BYTE_ORDER_NETWORK
= 3
342 BYTE_ORDER_UNKNOWN
= 4 # Python-specific entry
345 # enum equivalent, accessible constants
346 # These are taken directly from ctf/events.h
347 # All changes to enums must also be made here
362 name
= "UNKNOWN_TYPE"
364 attr
for attr
in dir(CTFTypeId
) if not callable(
367 attr
)) and not attr
.startswith("__")]
369 for attr
in constants
:
370 if getattr(CTFTypeId
, attr
) == id:
378 TRACE_PACKET_HEADER
= 0
379 STREAM_PACKET_CONTEXT
= 1
380 STREAM_EVENT_HEADER
= 2
381 STREAM_EVENT_CONTEXT
= 3
385 def scope_name(scope
):
386 name
= "UNKNOWN_SCOPE"
388 attr
for attr
in dir(CTFScope
) if not callable(
391 attr
)) and not attr
.startswith("__")]
393 for attr
in constants
:
394 if getattr(CTFScope
, attr
) == scope
:
401 # Priority of the scopes when searching for event fields
403 CTFScope
.EVENT_FIELDS
,
404 CTFScope
.EVENT_CONTEXT
,
405 CTFScope
.STREAM_EVENT_CONTEXT
,
406 CTFScope
.STREAM_EVENT_HEADER
,
407 CTFScope
.STREAM_PACKET_CONTEXT
,
408 CTFScope
.TRACE_PACKET_HEADER
412 class Event(collections
.Mapping
):
414 This class represents an event from the trace.
415 It is obtained using the TraceCollection generator functions.
420 raise NotImplementedError("Event cannot be instantiated")
424 """Return the name of the event or None on error."""
426 return nbt
._bt
_ctf
_event
_name
(self
._e
)
431 Return the timestamp of the event as written in
432 the packet (in cycles) or -1ULL on error.
435 return nbt
._bt
_ctf
_get
_cycles
(self
._e
)
440 Return the timestamp of the event offset with the
441 system clock source or -1ULL on error.
444 return nbt
._bt
_ctf
_get
_timestamp
(self
._e
)
449 Return a datetime object based on the event's
450 timestamp. Note that the datetime class' precision
451 is limited to microseconds.
454 return datetime
.fromtimestamp(self
.timestamp
/ 1E9
)
456 def field_with_scope(self
, field_name
, scope
):
458 Get field_name's value in scope.
459 None is returned if no field matches field_name.
462 if scope
not in _scopes
:
463 raise ValueError("Invalid scope provided")
465 field
= self
._field
_with
_scope
(field_name
, scope
)
467 if field
is not None:
470 def field_list_with_scope(self
, scope
):
471 """Return a list of field names in scope."""
473 if scope
not in _scopes
:
474 raise ValueError("Invalid scope provided")
478 for field
in self
._field
_list
_with
_scope
(scope
):
479 field_names
.append(field
.name
)
486 Get the TraceHandle associated with this event
490 ret
= nbt
._bt
_ctf
_event
_get
_handle
_id
(self
._e
)
495 th
= TraceHandle
.__new
__(TraceHandle
)
497 th
._trace
_collection
= self
.get_trace_collection()
502 def trace_collection(self
):
504 Get the TraceCollection associated with this event.
505 Return None on error.
508 trace_collection
= TraceCollection()
509 trace_collection
._tc
= nbt
._bt
_ctf
_event
_get
_context
(self
._e
)
511 if trace_collection
._tc
is not None:
512 return trace_collection
514 def __getitem__(self
, field_name
):
516 Get field_name's value. If the field_name exists in multiple
517 scopes, the first field found is returned. The scopes are searched
518 in the following order:
521 3) STREAM_EVENT_CONTEXT
522 4) STREAM_EVENT_HEADER
523 5) STREAM_PACKET_CONTEXT
524 6) TRACE_PACKET_HEADER
525 None is returned if no field matches field_name.
527 Use field_with_scope() to explicitly access fields in a given
531 field
= self
._field
(field_name
)
533 if field
is not None:
536 raise KeyError(field_name
)
539 for key
in self
.keys():
545 for scope
in _scopes
:
546 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
547 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
549 if isinstance(ret
, list):
554 def __contains__(self
, field_name
):
555 return self
._field
(field_name
) is not None
558 """Return a list of field names."""
562 for scope
in _scopes
:
563 for name
in self
.field_list_with_scope(scope
):
564 field_names
.add(name
)
566 return list(field_names
)
568 def get(self
, field_name
, default
=None):
569 field
= self
._field
(field_name
)
577 for field
in self
.keys():
578 yield (field
, self
[field
])
580 def _field_with_scope(self
, field_name
, scope
):
581 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
583 if scope_ptr
is None:
586 definition_ptr
= nbt
._bt
_ctf
_get
_field
(self
._e
, scope_ptr
, field_name
)
588 if definition_ptr
is None:
591 field
= _Definition(definition_ptr
, scope
)
595 def _field(self
, field_name
):
598 for scope
in _scopes
:
599 field
= self
._field
_with
_scope
(field_name
, scope
)
601 if field
is not None:
606 def _field_list_with_scope(self
, scope
):
608 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
610 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
611 # provide the "count" return value
614 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
616 if isinstance(ret
, list):
617 list_ptr
, count
= ret
619 for i
in range(count
):
620 definition_ptr
= nbt
._bt
_python
_field
_one
_from
_list
(list_ptr
, i
)
622 if definition_ptr
is not None:
623 definition
= _Definition(definition_ptr
, scope
)
624 fields
.append(definition
)
629 class FieldError(Exception):
630 def __init__(self
, value
):
634 return repr(self
.value
)
637 class EventDeclaration
:
638 """Event declaration class. Do not instantiate."""
640 MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
643 raise NotImplementedError("EventDeclaration cannot be instantiated")
647 """Return the name of the event or None on error"""
649 return nbt
._bt
_ctf
_get
_decl
_event
_name
(self
._ed
)
653 """Return the event-ID of the event or -1 on error"""
655 id = nbt
._bt
_ctf
_get
_decl
_event
_id
(self
._ed
)
657 if id == self
.MAX_UINT64
:
665 Generator returning all FieldDeclarations of an event, going through
666 each scope in the following order:
669 3) STREAM_EVENT_CONTEXT
670 4) STREAM_EVENT_HEADER
671 5) STREAM_PACKET_CONTEXT
672 6) TRACE_PACKET_HEADER
675 for scope
in _scopes
:
676 for declaration
in self
.fields_scope(scope
):
679 def fields_scope(self
, scope
):
681 Generator returning FieldDeclarations of the current event in scope.
683 ret
= nbt
._by
_python
_field
_decl
_listcaller
(self
._ed
, scope
)
685 if not isinstance(ret
, list):
688 list_ptr
, count
= ret
690 for i
in range(count
):
691 field_decl_ptr
= nbt
._bt
_python
_field
_decl
_one
_from
_list
(list_ptr
, i
)
693 if field_decl_ptr
is not None:
694 decl_ptr
= nbt
._bt
_ctf
_get
_decl
_from
_field
_decl
(field_decl_ptr
)
695 name
= nbt
._bt
_ctf
_get
_decl
_field
_name
(field_decl_ptr
)
696 field_declaration
= _create_field_declaration(decl_ptr
, name
,
698 yield field_declaration
701 class FieldDeclaration
:
702 """Field declaration class. Do not instantiate."""
705 raise NotImplementedError("FieldDeclaration cannot be instantiated")
708 return "({0}) {1} {2}".format(CTFScope
.scope_name(self
.scope
),
709 CTFTypeId
.type_name(self
.type),
714 """Return the name of a FieldDeclaration or None on error."""
721 Return the FieldDeclaration's type. One of the entries in class
725 return nbt
._bt
_ctf
_field
_type
(self
._fd
)
730 Return the FieldDeclaration's scope.
736 class IntegerFieldDeclaration(FieldDeclaration
):
737 """Do not instantiate."""
740 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
743 def signedness(self
):
745 Return the signedness of an integer:
746 0 if unsigned; 1 if signed; -1 on error.
749 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
753 """Return the base of an int or a negative value on error."""
755 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
758 def byte_order(self
):
760 Return the byte order. One of class ByteOrder's entries.
763 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
766 return ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
768 return ByteOrder
.BYTE_ORDER_BIG_ENDIAN
770 return ByteOrder
.BYTE_ORDER_UNKNOWN
775 Return the size, in bits, of an int or a negative
779 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
784 Return the encoding. One of class CTFStringEncoding's entries.
785 Return a negative value on error.
788 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
791 class EnumerationFieldDeclaration(FieldDeclaration
):
792 """Do not instantiate."""
795 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
798 class ArrayFieldDeclaration(FieldDeclaration
):
799 """Do not instantiate."""
802 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
807 Return the length of an array or a negative
811 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
814 def element_declaration(self
):
816 Return element declaration.
819 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
821 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
824 class SequenceFieldDeclaration(FieldDeclaration
):
825 """Do not instantiate."""
828 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
831 def element_declaration(self
):
833 Return element declaration.
836 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
838 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
841 class FloatFieldDeclaration(FieldDeclaration
):
842 """Do not instantiate."""
845 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
848 class StructureFieldDeclaration(FieldDeclaration
):
849 """Do not instantiate."""
852 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
855 class StringFieldDeclaration(FieldDeclaration
):
856 """Do not instantiate."""
859 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
862 class VariantFieldDeclaration(FieldDeclaration
):
863 """Do not instantiate."""
866 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
871 Return the last error code encountered while
872 accessing a field and reset the error flag.
873 Return 0 if no error, a negative value otherwise.
876 return nbt
._bt
_ctf
_field
_get
_error
()
879 def _create_field_declaration(declaration_ptr
, name
, scope
):
881 Private field declaration factory.
884 if declaration_ptr
is None:
885 raise ValueError("declaration_ptr must be valid")
886 if scope
not in _scopes
:
887 raise ValueError("Invalid scope provided")
889 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
892 if type == CTFTypeId
.INTEGER
:
893 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
894 elif type == CTFTypeId
.ENUM
:
895 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
896 elif type == CTFTypeId
.ARRAY
:
897 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
898 elif type == CTFTypeId
.SEQUENCE
:
899 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
900 elif type == CTFTypeId
.FLOAT
:
901 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
902 elif type == CTFTypeId
.STRUCT
:
903 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
904 elif type == CTFTypeId
.STRING
:
905 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
906 elif type == CTFTypeId
.VARIANT
:
907 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
911 declaration
._fd
= declaration_ptr
912 declaration
._s
= scope
913 declaration
._name
= name
919 def __init__(self
, definition_ptr
, scope
):
920 self
._d
= definition_ptr
923 if scope
not in _scopes
:
924 ValueError("Invalid scope provided")
928 """Return the name of a field or None on error."""
930 return nbt
._bt
_ctf
_field
_name
(self
._d
)
934 """Return the type of a field or -1 if unknown."""
936 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
939 def declaration(self
):
940 """Return the associated Definition object."""
942 return _create_field_declaration(
943 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
945 def _get_enum_str(self
):
947 Return the string matching the current enumeration.
948 Return None on error.
951 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
953 def _get_array_element_at(self
, index
):
955 Return the array's element at position index.
959 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
961 if array_ptr
is None:
964 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
966 if definition_ptr
is None:
969 return _Definition(definition_ptr
, self
.scope
)
971 def _get_sequence_len(self
):
973 Return the len of a sequence or a negative
977 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
979 return nbt
._bt
_sequence
_len
(seq
)
981 def _get_sequence_element_at(self
, index
):
983 Return the sequence's element at position index,
984 otherwise return None
987 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
990 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
992 if definition_ptr
is not None:
993 return _Definition(definition_ptr
, self
.scope
)
995 def _get_uint64(self
):
997 Return the value associated with the field.
998 If the field does not exist or is not of the type requested,
999 the value returned is undefined. To check if an error occured,
1000 use the field_error() function after accessing a field.
1003 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1005 def _get_int64(self
):
1007 Return the value associated with the field.
1008 If the field does not exist or is not of the type requested,
1009 the value returned is undefined. To check if an error occured,
1010 use the field_error() function after accessing a field.
1013 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1015 def _get_char_array(self
):
1017 Return the value associated with the field.
1018 If the field does not exist or is not of the type requested,
1019 the value returned is undefined. To check if an error occurred,
1020 use the field_error() function after accessing a field.
1023 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1027 Return the value associated with the field.
1028 If the field does not exist or is not of the type requested,
1029 the value returned is undefined. To check if an error occurred,
1030 use the field_error() function after accessing a field.
1033 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1035 def _get_float(self
):
1037 Return the value associated with the field.
1038 If the field does not exist or is not of the type requested,
1039 the value returned is undefined. To check if an error occurred,
1040 use the field_error() function after accessing a field.
1043 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1045 def _get_variant(self
):
1047 Return the variant's selected field.
1048 If the field does not exist or is not of the type requested,
1049 the value returned is undefined. To check if an error occurred,
1050 use the field_error() function after accessing a field.
1053 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1055 def _get_struct_field_count(self
):
1057 Return the number of fields contained in the structure.
1058 If the field does not exist or is not of the type requested,
1059 the value returned is undefined.
1062 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1064 def _get_struct_field_at(self
, i
):
1066 Return the structure's field at position i.
1067 If the field does not exist or is not of the type requested,
1068 the value returned is undefined. To check if an error occurred,
1069 use the field_error() function after accessing a field.
1072 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1077 Return the value associated with the field according to its type.
1078 Return None on error.
1084 if id == CTFTypeId
.STRING
:
1085 value
= self
._get
_str
()
1086 elif id == CTFTypeId
.ARRAY
:
1087 element_decl
= self
.declaration
.element_declaration
1089 if ((element_decl
.type == CTFTypeId
.INTEGER
1090 and element_decl
.length
== 8)
1091 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1092 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1096 for i
in range(self
.declaration
.length
):
1097 element
= self
._get
_array
_element
_at
(i
)
1098 value
.append(element
.value
)
1099 elif id == CTFTypeId
.INTEGER
:
1100 if self
.declaration
.signedness
== 0:
1101 value
= self
._get
_uint
64()
1103 value
= self
._get
_int
64()
1104 elif id == CTFTypeId
.ENUM
:
1105 value
= self
._get
_enum
_str
()
1106 elif id == CTFTypeId
.SEQUENCE
:
1107 element_decl
= self
.declaration
.element_declaration
1109 if ((element_decl
.type == CTFTypeId
.INTEGER
1110 and element_decl
.length
== 8)
1111 and (element_decl
.encoding
== CTFStringEncoding
.ASCII
or element_decl
.encoding
== CTFStringEncoding
.UTF8
)):
1112 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1114 seq_len
= self
._get
_sequence
_len
()
1117 for i
in range(seq_len
):
1118 evDef
= self
._get
_sequence
_element
_at
(i
)
1119 value
.append(evDef
.value
)
1120 elif id == CTFTypeId
.FLOAT
:
1121 value
= self
._get
_float
()
1122 elif id == CTFTypeId
.VARIANT
:
1123 variant
= _Definition
.__new
__(_Definition
)
1124 variant
._d
= self
._get
_variant
()
1125 value
= variant
.value
1126 elif id == CTFTypeId
.STRUCT
:
1129 for i
in range(self
._get
_struct
_field
_count
()):
1130 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1131 value
[member
.name
] = member
.value
1135 "Error occurred while accessing field {} of type {}".format(
1137 CTFTypeId
.type_name(id)))
1143 """Return the scope of a field or None on error."""
1149 # Used to compare to -1ULL in error checks
1150 _MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
1152 class EnumerationMapping
:
1154 Enumeration mapping class. start and end values are inclusive.
1157 def __init__(self
, name
, start
, end
):
1163 def __init__(self
, name
):
1164 self
._c
= nbt
._bt
_ctf
_clock
_create
(name
)
1167 raise ValueError("Invalid clock name.")
1170 nbt
._bt
_ctf
_clock
_put
(self
._c
)
1175 Get the clock's name.
1178 name
= nbt
._bt
_ctf
_clock
_get
_name
(self
._c
)
1181 raise ValueError("Invalid clock instance.")
1186 def description(self
):
1188 Get the clock's description. None if unset.
1191 return nbt
._bt
_ctf
_clock
_get
_description
(self
._c
)
1194 def description(self
, desc
):
1196 Set the clock's description. The description appears in the clock's TSDL
1200 ret
= nbt
._bt
_ctf
_clock
_set
_description
(self
._c
, str(desc
))
1203 raise ValueError("Invalid clock description.")
1206 def frequency(self
):
1208 Get the clock's frequency (Hz).
1211 freq
= nbt
._bt
_ctf
_clock
_get
_frequency
(self
._c
)
1213 if freq
== CTFWriter
._MAX
_UINT
64:
1214 raise ValueError("Invalid clock instance")
1219 def frequency(self
, freq
):
1221 Set the clock's frequency (Hz).
1224 ret
= nbt
._bt
_ctf
_clock
_set
_frequency
(self
._c
, freq
)
1227 raise ValueError("Invalid frequency value.")
1230 def precision(self
):
1232 Get the clock's precision (in clock ticks).
1235 precision
= nbt
._bt
_ctf
_clock
_get
_precision
(self
._c
)
1237 if precision
== CTFWriter
._MAX
_UINT
64:
1238 raise ValueError("Invalid clock instance")
1243 def precision(self
, precision
):
1245 Set the clock's precision (in clock ticks).
1248 ret
= nbt
._bt
_ctf
_clock
_set
_precision
(self
._c
, precision
)
1251 def offset_seconds(self
):
1253 Get the clock's offset in seconds from POSIX.1 Epoch.
1256 offset_s
= nbt
._bt
_ctf
_clock
_get
_offset
_s
(self
._c
)
1258 if offset_s
== CTFWriter
._MAX
_UINT
64:
1259 raise ValueError("Invalid clock instance")
1263 @offset_seconds.setter
1264 def offset_seconds(self
, offset_s
):
1266 Set the clock's offset in seconds from POSIX.1 Epoch.
1269 ret
= nbt
._bt
_ctf
_clock
_set
_offset
_s
(self
._c
, offset_s
)
1272 raise ValueError("Invalid offset value.")
1277 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1280 offset
= nbt
._bt
_ctf
_clock
_get
_offset
(self
._c
)
1282 if offset
== CTFWriter
._MAX
_UINT
64:
1283 raise ValueError("Invalid clock instance")
1288 def offset(self
, offset
):
1290 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1293 ret
= nbt
._bt
_ctf
_clock
_set
_offset
(self
._c
, offset
)
1296 raise ValueError("Invalid offset value.")
1301 Get a clock's absolute attribute. A clock is absolute if the clock
1302 is a global reference across the trace's other clocks.
1305 is_absolute
= nbt
._bt
_ctf
_clock
_get
_is
_absolute
(self
._c
)
1307 if is_absolute
== -1:
1308 raise ValueError("Invalid clock instance")
1310 return False if is_absolute
== 0 else True
1313 def absolute(self
, is_absolute
):
1315 Set a clock's absolute attribute. A clock is absolute if the clock
1316 is a global reference across the trace's other clocks.
1319 ret
= nbt
._bt
_ctf
_clock
_set
_is
_absolute
(self
._c
, int(is_absolute
))
1322 raise ValueError("Could not set the clock's absolute attribute.")
1327 Get a clock's UUID (an object of type UUID).
1333 ret
, value
= nbt
._bt
_python
_ctf
_clock
_get
_uuid
_index
(self
._c
, i
)
1336 raise ValueError("Invalid clock instance")
1338 uuid_list
.append(value
)
1340 return UUID(bytes
=bytes(uuid_list
))
1343 def uuid(self
, uuid
):
1345 Set a clock's UUID (an object of type UUID).
1348 uuid_bytes
= uuid
.bytes
1350 if len(uuid_bytes
) != 16:
1351 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1353 for i
in range(len(uuid_bytes
)):
1354 ret
= nbt
._bt
_python
_ctf
_clock
_set
_uuid
_index
(self
._c
, i
,
1358 raise ValueError("Invalid clock instance")
1363 Get the current time in nanoseconds since the clock's origin (offset and
1364 offset_s attributes).
1367 time
= nbt
._bt
_ctf
_clock
_get
_time
(self
._c
)
1369 if time
== CTFWriter
._MAX
_UINT
64:
1370 raise ValueError("Invalid clock instance")
1375 def time(self
, time
):
1377 Set the current time in nanoseconds since the clock's origin (offset and
1378 offset_s attributes). The clock's value will be sampled as events are
1379 appended to a stream.
1382 ret
= nbt
._bt
_ctf
_clock
_set
_time
(self
._c
, time
)
1385 raise ValueError("Invalid time value.")
1387 class FieldDeclaration
:
1389 FieldDeclaration should not be instantiated directly. Instantiate
1390 one of the concrete FieldDeclaration classes.
1394 # These values are based on the bt_ctf_integer_base enum
1395 # declared in event-types.h.
1396 INTEGER_BASE_UNKNOWN
= -1
1397 INTEGER_BASE_BINARY
= 2
1398 INTEGER_BASE_OCTAL
= 8
1399 INTEGER_BASE_DECIMAL
= 10
1400 INTEGER_BASE_HEXADECIMAL
= 16
1403 if self
._ft
is None:
1404 raise ValueError("FieldDeclaration creation failed.")
1407 nbt
._bt
_ctf
_field
_type
_put
(self
._ft
)
1410 def _create_field_declaration_from_native_instance(
1411 native_field_declaration
):
1413 CTFTypeId
.INTEGER
: CTFWriter
.IntegerFieldDeclaration
,
1414 CTFTypeId
.FLOAT
: CTFWriter
.FloatFieldDeclaration
,
1415 CTFTypeId
.ENUM
: CTFWriter
.EnumerationFieldDeclaration
,
1416 CTFTypeId
.STRING
: CTFWriter
.StringFieldDeclaration
,
1417 CTFTypeId
.STRUCT
: CTFWriter
.StructureFieldDeclaration
,
1418 CTFTypeId
.VARIANT
: CTFWriter
.VariantFieldDeclaration
,
1419 CTFTypeId
.ARRAY
: CTFWriter
.ArrayFieldDeclaration
,
1420 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceFieldDeclaration
1423 field_type_id
= nbt
._bt
_ctf
_field
_type
_get
_type
_id
(native_field_declaration
)
1425 if field_type_id
== CTFTypeId
.UNKNOWN
:
1426 raise TypeError("Invalid field instance")
1428 declaration
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
1429 declaration
._ft
= native_field_declaration
1430 declaration
.__class
__ = type_dict
[field_type_id
]
1435 def alignment(self
):
1437 Get the field declaration's alignment. Returns -1 on error.
1440 return nbt
._bt
_ctf
_field
_type
_get
_alignment
(self
._ft
)
1443 def alignment(self
, alignment
):
1445 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1446 some types, such as structures and string, may impose other alignment
1450 ret
= nbt
._bt
_ctf
_field
_type
_set
_alignment
(self
._ft
, alignment
)
1453 raise ValueError("Invalid alignment value.")
1456 def byte_order(self
):
1458 Get the field declaration's byte order. One of the ByteOrder's constant.
1461 return nbt
._bt
_ctf
_field
_type
_get
_byte
_order
(self
._ft
)
1464 def byte_order(self
, byte_order
):
1466 Set the field declaration's byte order. Use constants defined in the ByteOrder
1470 ret
= nbt
._bt
_ctf
_field
_type
_set
_byte
_order
(self
._ft
, byte_order
)
1473 raise ValueError("Could not set byte order value.")
1475 class IntegerFieldDeclaration(FieldDeclaration
):
1476 def __init__(self
, size
):
1478 Create a new integer field declaration of the given size.
1480 self
._ft
= nbt
._bt
_ctf
_field
_type
_integer
_create
(size
)
1486 Get an integer's size.
1489 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_size
(self
._ft
)
1492 raise ValueError("Could not get Integer's size attribute.")
1499 Get an integer's signedness attribute.
1502 ret
= nbt
._bt
_ctf
_field
_type
_integer
_get
_signed
(self
._ft
)
1505 raise ValueError("Could not get Integer's signed attribute.")
1512 def signed(self
, signed
):
1514 Set an integer's signedness attribute.
1517 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_signed
(self
._ft
, signed
)
1520 raise ValueError("Could not set Integer's signed attribute.")
1525 Get the integer's base used to pretty-print the resulting trace.
1526 Returns a constant from the FieldDeclaration.IntegerBase class.
1529 return nbt
._bt
_ctf
_field
_type
_integer
_get
_base
(self
._ft
)
1532 def base(self
, base
):
1534 Set the integer's base used to pretty-print the resulting trace.
1535 The base must be a constant of the FieldDeclarationIntegerBase class.
1538 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_base
(self
._ft
, base
)
1541 raise ValueError("Could not set Integer's base.")
1546 Get the integer's encoding (one of the constants of the
1547 CTFStringEncoding class).
1548 Returns a constant from the CTFStringEncoding class.
1551 return nbt
._bt
_ctf
_field
_type
_integer
_get
_encoding
(self
._ft
)
1554 def encoding(self
, encoding
):
1556 An integer encoding may be set to signal that the integer must be printed
1557 as a text character. Must be a constant from the CTFStringEncoding class.
1560 ret
= nbt
._bt
_ctf
_field
_type
_integer
_set
_encoding
(self
._ft
, encoding
)
1563 raise ValueError("Could not set Integer's encoding.")
1565 class EnumerationFieldDeclaration(FieldDeclaration
):
1566 def __init__(self
, integer_type
):
1568 Create a new enumeration field declaration with the given underlying container type.
1570 isinst
= isinstance(integer_type
, CTFWriter
.IntegerFieldDeclaration
)
1572 if integer_type
is None or not isinst
:
1573 raise TypeError("Invalid integer container.")
1575 self
._ft
= nbt
._bt
_ctf
_field
_type
_enumeration
_create
(integer_type
._ft
)
1579 def container(self
):
1581 Get the enumeration's underlying container type.
1584 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_container
_type
(self
._ft
)
1587 raise TypeError("Invalid enumeration declaration")
1589 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1591 def add_mapping(self
, name
, range_start
, range_end
):
1593 Add a mapping to the enumeration. The range's values are inclusive.
1596 if range_start
< 0 or range_end
< 0:
1597 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
(self
._ft
,
1602 ret
= nbt
._bt
_ctf
_field
_type
_enumeration
_add
_mapping
_unsigned
(self
._ft
,
1608 raise ValueError("Could not add mapping to enumeration declaration.")
1613 Generator returning instances of EnumerationMapping.
1616 signed
= self
.container
.signed
1618 count
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_count
(self
._ft
)
1620 for i
in range(count
):
1622 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, i
)
1624 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, i
)
1627 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1628 raise TypeError(msg
)
1630 name
, range_start
, range_end
= ret
1631 yield CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1633 def get_mapping_by_name(self
, name
):
1635 Get a mapping by name (EnumerationMapping).
1638 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_name
(self
._ft
, name
)
1643 if self
.container
.signed
:
1644 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1646 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1649 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1650 raise TypeError(msg
)
1652 name
, range_start
, range_end
= ret
1654 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1656 def get_mapping_by_value(self
, value
):
1658 Get a mapping by value (EnumerationMapping).
1662 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_value
(self
._ft
, value
)
1664 index
= nbt
._bt
_ctf
_field
_type
_enumeration
_get
_mapping
_index
_by
_unsigned
_value
(self
._ft
, value
)
1669 if self
.container
.signed
:
1670 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
(self
._ft
, index
)
1672 ret
= nbt
._bt
_python
_ctf
_field
_type
_enumeration
_get
_mapping
_unsigned
(self
._ft
, index
)
1675 msg
= "Could not get Enumeration mapping at index {}".format(i
)
1676 raise TypeError(msg
)
1678 name
, range_start
, range_end
= ret
1680 return CTFWriter
.EnumerationMapping(name
, range_start
, range_end
)
1682 class FloatFieldDeclaration(FieldDeclaration
):
1690 Create a new floating point field declaration.
1693 self
._ft
= nbt
._bt
_ctf
_field
_type
_floating
_point
_create
()
1697 def exponent_digits(self
):
1699 Get the number of exponent digits used to store the floating point field.
1702 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_exponent
_digits
(self
._ft
)
1706 "Could not get Floating point exponent digit count")
1710 @exponent_digits.setter
1711 def exponent_digits(self
, exponent_digits
):
1713 Set the number of exponent digits to use to store the floating point field.
1714 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1715 are defined as constants of this class.
1718 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_exponent
_digits
(self
._ft
,
1722 raise ValueError("Could not set exponent digit count.")
1725 def mantissa_digits(self
):
1727 Get the number of mantissa digits used to store the floating point field.
1730 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_get
_mantissa
_digits
(self
._ft
)
1733 raise TypeError("Could not get Floating point mantissa digit count")
1737 @mantissa_digits.setter
1738 def mantissa_digits(self
, mantissa_digits
):
1740 Set the number of mantissa digits to use to store the floating point field.
1741 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1742 are defined as constants of this class.
1745 ret
= nbt
._bt
_ctf
_field
_type
_floating
_point
_set
_mantissa
_digits
(self
._ft
,
1749 raise ValueError("Could not set mantissa digit count.")
1751 class FloatingPointFieldDeclaration(FloatFieldDeclaration
):
1754 class StructureFieldDeclaration(FieldDeclaration
):
1757 Create a new structure field declaration.
1760 self
._ft
= nbt
._bt
_ctf
_field
_type
_structure
_create
()
1763 def add_field(self
, field_type
, field_name
):
1765 Add a field of type "field_type" to the structure.
1768 ret
= nbt
._bt
_ctf
_field
_type
_structure
_add
_field
(self
._ft
,
1773 raise ValueError("Could not add field to structure.")
1778 Generator returning the structure's field as tuples of (field name, field declaration).
1781 count
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_count
(self
._ft
)
1784 raise TypeError("Could not get Structure field count")
1786 for i
in range(count
):
1787 field_name
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_name
(self
._ft
, i
)
1789 if field_name
is None:
1790 msg
= "Could not get Structure field name at index {}".format(i
)
1791 raise TypeError(msg
)
1793 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_structure
_get
_field
_type
(self
._ft
, i
)
1795 if field_type_native
is None:
1796 msg
= "Could not get Structure field type at index {}".format(i
)
1797 raise TypeError(msg
)
1799 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1800 yield (field_name
, field_type
)
1802 def get_field_by_name(self
, name
):
1804 Get a field declaration by name (FieldDeclaration).
1807 field_type_native
= nbt
._bt
_ctf
_field
_type
_structure
_get
_field
_type
_by
_name
(self
._ft
, name
)
1809 if field_type_native
is None:
1810 msg
= "Could not find Structure field with name {}".format(name
)
1811 raise TypeError(msg
)
1813 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1815 class VariantFieldDeclaration(FieldDeclaration
):
1816 def __init__(self
, enum_tag
, tag_name
):
1818 Create a new variant field declaration.
1821 isinst
= isinstance(enum_tag
, CTFWriter
.EnumerationFieldDeclaration
)
1822 if enum_tag
is None or not isinst
:
1823 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
1825 self
._ft
= nbt
._bt
_ctf
_field
_type
_variant
_create
(enum_tag
._ft
,
1832 Get the variant's tag name.
1835 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_name
(self
._ft
)
1838 raise TypeError("Could not get Variant tag name")
1845 Get the variant's tag type.
1848 ret
= nbt
._bt
_ctf
_field
_type
_variant
_get
_tag
_type
(self
._ft
)
1851 raise TypeError("Could not get Variant tag type")
1853 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1855 def add_field(self
, field_type
, field_name
):
1857 Add a field of type "field_type" to the variant.
1860 ret
= nbt
._bt
_ctf
_field
_type
_variant
_add
_field
(self
._ft
,
1865 raise ValueError("Could not add field to variant.")
1870 Generator returning the variant's field as tuples of (field name, field declaration).
1873 count
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_count
(self
._ft
)
1876 raise TypeError("Could not get Variant field count")
1878 for i
in range(count
):
1879 field_name
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_name
(self
._ft
, i
)
1881 if field_name
is None:
1882 msg
= "Could not get Variant field name at index {}".format(i
)
1883 raise TypeError(msg
)
1885 field_type_native
= nbt
._bt
_python
_ctf
_field
_type
_variant
_get
_field
_type
(self
._ft
, i
)
1887 if field_type_native
is None:
1888 msg
= "Could not get Variant field type at index {}".format(i
)
1889 raise TypeError(msg
)
1891 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1892 yield (field_name
, field_type
)
1894 def get_field_by_name(self
, name
):
1896 Get a field declaration by name (FieldDeclaration).
1899 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_by
_name
(self
._ft
,
1902 if field_type_native
is None:
1903 msg
= "Could not find Variant field with name {}".format(name
)
1904 raise TypeError(msg
)
1906 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1908 def get_field_from_tag(self
, tag
):
1910 Get a field declaration from tag (EnumerationField).
1913 field_type_native
= nbt
._bt
_ctf
_field
_type
_variant
_get
_field
_type
_from
_tag
(self
._ft
, tag
._f
)
1915 if field_type_native
is None:
1916 msg
= "Could not find Variant field with tag value {}".format(tag
.value
)
1917 raise TypeError(msg
)
1919 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
1921 class ArrayFieldDeclaration(FieldDeclaration
):
1922 def __init__(self
, element_type
, length
):
1924 Create a new array field declaration.
1927 self
._ft
= nbt
._bt
_ctf
_field
_type
_array
_create
(element_type
._ft
,
1932 def element_type(self
):
1934 Get the array's element type.
1937 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_element
_type
(self
._ft
)
1940 raise TypeError("Could not get Array element type")
1942 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1947 Get the array's length.
1950 ret
= nbt
._bt
_ctf
_field
_type
_array
_get
_length
(self
._ft
)
1953 raise TypeError("Could not get Array length")
1957 class SequenceFieldDeclaration(FieldDeclaration
):
1958 def __init__(self
, element_type
, length_field_name
):
1960 Create a new sequence field declaration.
1963 self
._ft
= nbt
._bt
_ctf
_field
_type
_sequence
_create
(element_type
._ft
,
1964 str(length_field_name
))
1968 def element_type(self
):
1970 Get the sequence's element type.
1973 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_element
_type
(self
._ft
)
1976 raise TypeError("Could not get Sequence element type")
1978 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(ret
)
1981 def length_field_name(self
):
1983 Get the sequence's length field name.
1986 ret
= nbt
._bt
_ctf
_field
_type
_sequence
_get
_length
_field
_name
(self
._ft
)
1989 raise TypeError("Could not get Sequence length field name")
1993 class StringFieldDeclaration(FieldDeclaration
):
1996 Create a new string field declaration.
1999 self
._ft
= nbt
._bt
_ctf
_field
_type
_string
_create
()
2005 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
2008 return nbt
._bt
_ctf
_field
_type
_string
_get
_encoding
(self
._ft
)
2011 def encoding(self
, encoding
):
2013 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
2016 ret
= nbt
._bt
_ctf
_field
_type
_string
_set
_encoding
(self
._ft
, encoding
)
2018 raise ValueError("Could not set string encoding.")
2021 def create_field(field_type
):
2023 Create an instance of a field.
2025 isinst
= isinstance(field_type
, CTFWriter
.FieldDeclaration
)
2027 if field_type
is None or not isinst
:
2028 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
2030 if isinstance(field_type
, CTFWriter
.IntegerFieldDeclaration
):
2031 return CTFWriter
.IntegerField(field_type
)
2032 elif isinstance(field_type
, CTFWriter
.EnumerationFieldDeclaration
):
2033 return CTFWriter
.EnumerationField(field_type
)
2034 elif isinstance(field_type
, CTFWriter
.FloatFieldDeclaration
):
2035 return CTFWriter
.FloatingPointField(field_type
)
2036 elif isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2037 return CTFWriter
.StructureField(field_type
)
2038 elif isinstance(field_type
, CTFWriter
.VariantFieldDeclaration
):
2039 return CTFWriter
.VariantField(field_type
)
2040 elif isinstance(field_type
, CTFWriter
.ArrayFieldDeclaration
):
2041 return CTFWriter
.ArrayField(field_type
)
2042 elif isinstance(field_type
, CTFWriter
.SequenceFieldDeclaration
):
2043 return CTFWriter
.SequenceField(field_type
)
2044 elif isinstance(field_type
, CTFWriter
.StringFieldDeclaration
):
2045 return CTFWriter
.StringField(field_type
)
2049 Base class, do not instantiate.
2052 def __init__(self
, field_type
):
2053 if not isinstance(field_type
, CTFWriter
.FieldDeclaration
):
2054 raise TypeError("Invalid field_type argument.")
2056 self
._f
= nbt
._bt
_ctf
_field
_create
(field_type
._ft
)
2059 raise ValueError("Field creation failed.")
2062 nbt
._bt
_ctf
_field
_put
(self
._f
)
2065 def _create_field_from_native_instance(native_field_instance
):
2067 CTFTypeId
.INTEGER
: CTFWriter
.IntegerField
,
2068 CTFTypeId
.FLOAT
: CTFWriter
.FloatingPointField
,
2069 CTFTypeId
.ENUM
: CTFWriter
.EnumerationField
,
2070 CTFTypeId
.STRING
: CTFWriter
.StringField
,
2071 CTFTypeId
.STRUCT
: CTFWriter
.StructureField
,
2072 CTFTypeId
.VARIANT
: CTFWriter
.VariantField
,
2073 CTFTypeId
.ARRAY
: CTFWriter
.ArrayField
,
2074 CTFTypeId
.SEQUENCE
: CTFWriter
.SequenceField
2077 field_type
= nbt
._bt
_python
_get
_field
_type
(native_field_instance
)
2079 if field_type
== CTFTypeId
.UNKNOWN
:
2080 raise TypeError("Invalid field instance")
2082 field
= CTFWriter
.Field
.__new
__(CTFWriter
.Field
)
2083 field
._f
= native_field_instance
2084 field
.__class
__ = type_dict
[field_type
]
2089 def declaration(self
):
2090 native_field_type
= nbt
._bt
_ctf
_field
_get
_type
(self
._f
)
2092 if native_field_type
is None:
2093 raise TypeError("Invalid field instance")
2094 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(
2097 class IntegerField(Field
):
2101 Get an integer field's value.
2104 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2107 raise TypeError("Invalid integer instance.")
2110 ret
, value
= nbt
._bt
_ctf
_field
_unsigned
_integer
_get
_value
(self
._f
)
2112 ret
, value
= nbt
._bt
_ctf
_field
_signed
_integer
_get
_value
(self
._f
)
2115 raise ValueError("Could not get integer field value.")
2120 def value(self
, value
):
2122 Set an integer field's value.
2125 if not isinstance(value
, int):
2126 raise TypeError("IntegerField's value must be an int")
2128 signedness
= nbt
._bt
_python
_field
_integer
_get
_signedness
(self
._f
)
2130 raise TypeError("Invalid integer instance.")
2133 ret
= nbt
._bt
_ctf
_field
_unsigned
_integer
_set
_value
(self
._f
, value
)
2135 ret
= nbt
._bt
_ctf
_field
_signed
_integer
_set
_value
(self
._f
, value
)
2138 raise ValueError("Could not set integer field value.")
2140 class EnumerationField(Field
):
2142 def container(self
):
2144 Return the enumeration's underlying container field (an integer field).
2147 container
= CTFWriter
.IntegerField
.__new
__(CTFWriter
.IntegerField
)
2148 container
._f
= nbt
._bt
_ctf
_field
_enumeration
_get
_container
(self
._f
)
2150 if container
._f
is None:
2151 raise TypeError("Invalid enumeration field type.")
2158 Get the enumeration field's mapping name.
2161 value
= nbt
._bt
_ctf
_field
_enumeration
_get
_mapping
_name
(self
._f
)
2164 raise ValueError("Could not get enumeration's mapping name.")
2169 def value(self
, value
):
2171 Set the enumeration field's value. Must be an integer as mapping names
2175 if not isinstance(value
, int):
2176 raise TypeError("EnumerationField value must be an int")
2178 self
.container
.value
= value
2180 class FloatingPointField(Field
):
2184 Get a floating point field's value.
2187 ret
, value
= nbt
._bt
_ctf
_field
_floating
_point
_get
_value
(self
._f
)
2190 raise ValueError("Could not get floating point field value.")
2195 def value(self
, value
):
2197 Set a floating point field's value.
2200 if not isinstance(value
, int) and not isinstance(value
, float):
2201 raise TypeError("Value must be either a float or an int")
2203 ret
= nbt
._bt
_ctf
_field
_floating
_point
_set
_value
(self
._f
, float(value
))
2206 raise ValueError("Could not set floating point field value.")
2208 # oops!! This class is provided to ensure backward-compatibility since
2209 # a stable release publicly exposed this abomination.
2210 class FloatFieldingPoint(FloatingPointField
):
2213 class StructureField(Field
):
2214 def field(self
, field_name
):
2216 Get the structure's field corresponding to the provided field name.
2219 native_instance
= nbt
._bt
_ctf
_field
_structure
_get
_field
(self
._f
,
2222 if native_instance
is None:
2223 raise ValueError("Invalid field_name provided.")
2225 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2227 class VariantField(Field
):
2228 def field(self
, tag
):
2230 Return the variant's selected field. The "tag" field is the selector enum field.
2233 native_instance
= nbt
._bt
_ctf
_field
_variant
_get
_field
(self
._f
, tag
._f
)
2235 if native_instance
is None:
2236 raise ValueError("Invalid tag provided.")
2238 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2240 class ArrayField(Field
):
2241 def field(self
, index
):
2243 Return the array's field at position "index".
2246 native_instance
= nbt
._bt
_ctf
_field
_array
_get
_field
(self
._f
, index
)
2248 if native_instance
is None:
2249 raise IndexError("Invalid index provided.")
2251 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2253 class SequenceField(Field
):
2257 Get the sequence's length field (IntegerField).
2260 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_length
(self
._f
)
2262 if native_instance
is None:
2265 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2268 def length(self
, length_field
):
2270 Set the sequence's length field (IntegerField).
2273 if not isinstance(length_field
, CTFWriter
.IntegerField
):
2274 raise TypeError("Invalid length field.")
2276 if length_field
.declaration
.signed
:
2277 raise TypeError("Sequence field length must be unsigned")
2279 ret
= nbt
._bt
_ctf
_field
_sequence
_set
_length
(self
._f
, length_field
._f
)
2282 raise ValueError("Could not set sequence length.")
2284 def field(self
, index
):
2286 Return the sequence's field at position "index".
2289 native_instance
= nbt
._bt
_ctf
_field
_sequence
_get
_field
(self
._f
, index
)
2291 if native_instance
is None:
2292 raise ValueError("Could not get sequence element at index.")
2294 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2296 class StringField(Field
):
2300 Get a string field's value.
2303 return nbt
._bt
_ctf
_field
_string
_get
_value
(self
._f
)
2306 def value(self
, value
):
2308 Set a string field's value.
2311 ret
= nbt
._bt
_ctf
_field
_string
_set
_value
(self
._f
, str(value
))
2314 raise ValueError("Could not set string field value.")
2317 def __init__(self
, name
):
2319 Create a new event class of the given name.
2322 self
._ec
= nbt
._bt
_ctf
_event
_class
_create
(name
)
2324 if self
._ec
is None:
2325 raise ValueError("Event class creation failed.")
2328 nbt
._bt
_ctf
_event
_class
_put
(self
._ec
)
2330 def add_field(self
, field_type
, field_name
):
2332 Add a field of type "field_type" to the event class.
2335 ret
= nbt
._bt
_ctf
_event
_class
_add
_field
(self
._ec
, field_type
._ft
,
2339 raise ValueError("Could not add field to event class.")
2344 Get the event class' name.
2347 name
= nbt
._bt
_ctf
_event
_class
_get
_name
(self
._ec
)
2350 raise TypeError("Could not get EventClass name")
2357 Get the event class' id. Returns a negative value if unset.
2360 id = nbt
._bt
_ctf
_event
_class
_get
_id
(self
._ec
)
2363 raise TypeError("Could not get EventClass id")
2370 Set the event class' id. Throws a TypeError if the event class
2371 is already registered to a stream class.
2374 ret
= nbt
._bt
_ctf
_event
_class
_set
_id
(self
._ec
, id)
2377 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
2380 def stream_class(self
):
2382 Get the event class' stream class. Returns None if unset.
2384 stream_class_native
= nbt
._bt
_ctf
_event
_class
_get
_stream
_class
(self
._ec
)
2386 if stream_class_native
is None:
2389 stream_class
= CTFWriter
.StreamClass
.__new
__(CTFWriter
.StreamClass
)
2390 stream_class
._sc
= stream_class_native
2397 Generator returning the event class' fields as tuples of (field name, field declaration).
2400 count
= nbt
._bt
_ctf
_event
_class
_get
_field
_count
(self
._ec
)
2403 raise TypeError("Could not get EventClass' field count")
2405 for i
in range(count
):
2406 field_name
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_name
(self
._ec
, i
)
2408 if field_name
is None:
2409 msg
= "Could not get EventClass' field name at index {}".format(i
)
2410 raise TypeError(msg
)
2412 field_type_native
= nbt
._bt
_python
_ctf
_event
_class
_get
_field
_type
(self
._ec
, i
)
2414 if field_type_native
is None:
2415 msg
= "Could not get EventClass' field type at index {}".format(i
)
2416 raise TypeError(msg
)
2418 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2419 yield (field_name
, field_type
)
2421 def get_field_by_name(self
, name
):
2423 Get a field declaration by name (FieldDeclaration).
2426 field_type_native
= nbt
._bt
_ctf
_event
_class
_get
_field
_by
_name
(self
._ec
, name
)
2428 if field_type_native
is None:
2429 msg
= "Could not find EventClass field with name {}".format(name
)
2430 raise TypeError(msg
)
2432 return CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2435 def __init__(self
, event_class
):
2437 Create a new event of the given event class.
2440 if not isinstance(event_class
, CTFWriter
.EventClass
):
2441 raise TypeError("Invalid event_class argument.")
2443 self
._e
= nbt
._bt
_ctf
_event
_create
(event_class
._ec
)
2446 raise ValueError("Event creation failed.")
2449 nbt
._bt
_ctf
_event
_put
(self
._e
)
2452 def event_class(self
):
2454 Get the event's class.
2457 event_class_native
= nbt
._bt
_ctf
_event
_get
_class
(self
._e
)
2459 if event_class_native
is None:
2462 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2463 event_class
._ec
= event_class_native
2469 Get a clock from event. Returns None if the event's class
2470 is not registered to a stream class.
2473 clock_instance
= nbt
._bt
_ctf
_event
_get
_clock
(self
._e
)
2475 if clock_instance
is None:
2478 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2479 clock
._c
= clock_instance
2483 def payload(self
, field_name
):
2485 Get a field from event.
2488 native_instance
= nbt
._bt
_ctf
_event
_get
_payload
(self
._e
,
2491 if native_instance
is None:
2492 raise ValueError("Could not get event payload.")
2494 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_instance
)
2496 def set_payload(self
, field_name
, value_field
):
2498 Set a manually created field as an event's payload.
2501 if not isinstance(value
, CTFWriter
.Field
):
2502 raise TypeError("Invalid value type.")
2504 ret
= nbt
._bt
_ctf
_event
_set
_payload
(self
._e
, str(field_name
),
2508 raise ValueError("Could not set event field payload.")
2511 def __init__(self
, name
):
2513 Create a new stream class of the given name.
2516 self
._sc
= nbt
._bt
_ctf
_stream
_class
_create
(name
)
2518 if self
._sc
is None:
2519 raise ValueError("Stream class creation failed.")
2522 nbt
._bt
_ctf
_stream
_class
_put
(self
._sc
)
2527 Get a stream class' name.
2530 name
= nbt
._bt
_ctf
_stream
_class
_get
_name
(self
._sc
)
2533 raise TypeError("Could not get StreamClass name")
2540 Get a stream class' clock.
2543 clock_instance
= nbt
._bt
_ctf
_stream
_class
_get
_clock
(self
._sc
)
2545 if clock_instance
is None:
2548 clock
= CTFWriter
.Clock
.__new
__(CTFWriter
.Clock
)
2549 clock
._c
= clock_instance
2554 def clock(self
, clock
):
2556 Assign a clock to a stream class.
2559 if not isinstance(clock
, CTFWriter
.Clock
):
2560 raise TypeError("Invalid clock type.")
2562 ret
= nbt
._bt
_ctf
_stream
_class
_set
_clock
(self
._sc
, clock
._c
)
2565 raise ValueError("Could not set stream class clock.")
2570 Get a stream class' id.
2573 ret
= nbt
._bt
_ctf
_stream
_class
_get
_id
(self
._sc
)
2576 raise TypeError("Could not get StreamClass id")
2583 Assign an id to a stream class.
2586 ret
= nbt
._bt
_ctf
_stream
_class
_set
_id
(self
._sc
, id)
2589 raise TypeError("Could not set stream class id.")
2592 def event_classes(self
):
2594 Generator returning the stream class' event classes.
2597 count
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
_count
(self
._sc
)
2600 raise TypeError("Could not get StreamClass' event class count")
2602 for i
in range(count
):
2603 event_class_native
= nbt
._bt
_ctf
_stream
_class
_get
_event
_class
(self
._sc
, i
)
2605 if event_class_native
is None:
2606 msg
= "Could not get StreamClass' event class at index {}".format(i
)
2607 raise TypeError(msg
)
2609 event_class
= CTFWriter
.EventClass
.__new
__(CTFWriter
.EventClass
)
2610 event_class
._ec
= event_class_native
2613 def add_event_class(self
, event_class
):
2615 Add an event class to a stream class. New events can be added even after a
2616 stream has been instantiated and events have been appended. However, a stream
2617 will not accept events of a class that has not been added to the stream
2621 if not isinstance(event_class
, CTFWriter
.EventClass
):
2622 raise TypeError("Invalid event_class type.")
2624 ret
= nbt
._bt
_ctf
_stream
_class
_add
_event
_class
(self
._sc
,
2628 raise ValueError("Could not add event class.")
2631 def packet_context_type(self
):
2633 Get the StreamClass' packet context type (StructureFieldDeclaration)
2636 field_type_native
= nbt
._bt
_ctf
_stream
_class
_get
_packet
_context
_type
(self
._sc
)
2638 if field_type_native
is None:
2639 raise ValueError("Invalid StreamClass")
2641 field_type
= CTFWriter
.FieldDeclaration
._create
_field
_declaration
_from
_native
_instance
(field_type_native
)
2645 @packet_context_type.setter
2646 def packet_context_type(self
, field_type
):
2648 Set a StreamClass' packet context type. Must be of type
2649 StructureFieldDeclaration.
2652 if not isinstance(field_type
, CTFWriter
.StructureFieldDeclaration
):
2653 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2655 ret
= nbt
._bt
_ctf
_stream
_class
_set
_packet
_context
_type
(self
._sc
,
2659 raise ValueError("Failed to set packet context type.")
2663 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
2666 nbt
._bt
_ctf
_stream
_put
(self
._s
)
2669 def discarded_events(self
):
2671 Get a stream's discarded event count.
2674 ret
, count
= nbt
._bt
_ctf
_stream
_get
_discarded
_events
_count
(self
._s
)
2677 raise ValueError("Could not get the stream's discarded events count")
2681 def append_discarded_events(self
, event_count
):
2683 Increase the current packet's discarded event count.
2686 nbt
._bt
_ctf
_stream
_append
_discarded
_events
(self
._s
, event_count
)
2688 def append_event(self
, event
):
2690 Append "event" to the stream's current packet. The stream's associated clock
2691 will be sampled during this call. The event shall not be modified after
2692 being appended to a stream.
2695 ret
= nbt
._bt
_ctf
_stream
_append
_event
(self
._s
, event
._e
)
2698 raise ValueError("Could not append event to stream.")
2701 def packet_context(self
):
2703 Get a Stream's packet context field (a StructureField).
2706 native_field
= nbt
._bt
_ctf
_stream
_get
_packet
_context
(self
._s
)
2708 if native_field
is None:
2709 raise ValueError("Invalid Stream.")
2711 return CTFWriter
.Field
._create
_field
_from
_native
_instance
(native_field
)
2713 @packet_context.setter
2714 def packet_context(self
, field
):
2716 Set a Stream's packet context field (must be a StructureField).
2719 if not isinstance(field
, CTFWriter
.StructureField
):
2720 raise TypeError("Argument field must be of type StructureField")
2722 ret
= nbt
._bt
_ctf
_stream
_set
_packet
_context
(self
._s
, field
._f
)
2725 raise ValueError("Invalid packet context field.")
2729 The stream's current packet's events will be flushed to disk. Events
2730 subsequently appended to the stream will be added to a new packet.
2733 ret
= nbt
._bt
_ctf
_stream
_flush
(self
._s
)
2736 raise ValueError("Could not flush stream.")
2739 def __init__(self
, path
):
2741 Create a new writer that will produce a trace in the given path.
2744 self
._w
= nbt
._bt
_ctf
_writer
_create
(path
)
2747 raise ValueError("Writer creation failed.")
2750 nbt
._bt
_ctf
_writer
_put
(self
._w
)
2752 def create_stream(self
, stream_class
):
2754 Create a new stream instance and register it to the writer.
2757 if not isinstance(stream_class
, CTFWriter
.StreamClass
):
2758 raise TypeError("Invalid stream_class type.")
2760 stream
= CTFWriter
.Stream
.__new
__(CTFWriter
.Stream
)
2761 stream
._s
= nbt
._bt
_ctf
_writer
_create
_stream
(self
._w
, stream_class
._sc
)
2765 def add_environment_field(self
, name
, value
):
2767 Add an environment field to the trace.
2770 ret
= nbt
._bt
_ctf
_writer
_add
_environment
_field
(self
._w
, str(name
),
2774 raise ValueError("Could not add environment field to trace.")
2776 def add_clock(self
, clock
):
2778 Add a clock to the trace. Clocks assigned to stream classes must be
2779 registered to the writer.
2782 ret
= nbt
._bt
_ctf
_writer
_add
_clock
(self
._w
, clock
._c
)
2785 raise ValueError("Could not add clock to Writer.")
2790 Get the trace's TSDL meta-data.
2793 return nbt
._bt
_ctf
_writer
_get
_metadata
_string
(self
._w
)
2795 def flush_metadata(self
):
2797 Flush the trace's metadata to the metadata file.
2800 nbt
._bt
_ctf
_writer
_flush
_metadata
(self
._w
)
2803 def byte_order(self
):
2805 Get the trace's byte order. Must be a constant from the ByteOrder
2809 raise NotImplementedError("Getter not implemented.")
2812 def byte_order(self
, byte_order
):
2814 Set the trace's byte order. Must be a constant from the ByteOrder
2815 class. Defaults to the host machine's endianness
2818 ret
= nbt
._bt
_ctf
_writer
_set
_byte
_order
(self
._w
, byte_order
)
2821 raise ValueError("Could not set trace's byte order.")