3 # Babeltrace reader 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
29 import babeltrace
.common
as common
32 from datetime
import datetime
35 class TraceCollection
:
37 A :class:`TraceCollection` is a collection of opened traces.
39 Once a trace collection is created, you can add traces to the
40 collection by using the :meth:`add_trace` or
41 :meth:`add_traces_recursive`, and then iterate on the merged
42 events using :attr:`events`.
44 You may use :meth:`remove_trace` to close and remove a specific
45 trace from a trace collection.
50 Creates an empty trace collection.
53 self
._tc
= nbt
._bt
_context
_create
()
56 nbt
._bt
_context
_put
(self
._tc
)
58 def add_trace(self
, path
, format_str
):
60 Adds a trace to the trace collection.
62 *path* is the exact path of the trace on the filesystem.
64 *format_str* is a string indicating the type of trace to
65 add. ``ctf`` is currently the only supported trace format.
67 Returns the corresponding :class:`TraceHandle` instance for
68 this opened trace on success, or ``None`` on error.
70 This function **does not** recurse directories to find a
71 trace. See :meth:`add_traces_recursive` for a recursive
72 version of this function.
75 ret
= nbt
._bt
_context
_add
_trace
(self
._tc
, path
, format_str
,
81 th
= TraceHandle
.__new
__(TraceHandle
)
83 th
._trace
_collection
= self
87 def add_traces_recursive(self
, path
, format_str
):
89 Adds traces to this trace collection by recursively searching
90 in the *path* directory.
92 *format_str* is a string indicating the type of trace to add.
93 ``ctf`` is currently the only supported trace format.
95 Returns a :class:`dict` object mapping full paths to trace
96 handles for each trace found, or ``None`` on error.
98 See also :meth:`add_trace`.
105 for fullpath
, dirs
, files
in os
.walk(path
):
106 if "metadata" in files
:
107 trace_handle
= self
.add_trace(fullpath
, format_str
)
109 if trace_handle
is None:
113 trace_handles
[fullpath
] = trace_handle
116 if noTrace
and error
:
121 def remove_trace(self
, trace_handle
):
123 Removes a trace from the trace collection using its trace
124 handle *trace_handle*.
126 :class:`TraceHandle` objects are returned by :meth:`add_trace`
127 and :meth:`add_traces_recursive`.
131 nbt
._bt
_context
_remove
_trace
(self
._tc
, trace_handle
._id
)
132 except AttributeError:
133 raise TypeError("in remove_trace, argument 2 must be a TraceHandle instance")
138 Generates the ordered :class:`Event` objects of all the opened
139 traces contained in this trace collection.
141 Due to limitations of the native Babeltrace API, only one event
142 may be "alive" at a given time, i.e. a user **should never**
143 store a copy of the events returned by this function for
144 ulterior use. Users shall make sure to copy the information
145 they need *from* an event before accessing the next one.
148 begin_pos_ptr
= nbt
._bt
_iter
_pos
()
149 end_pos_ptr
= nbt
._bt
_iter
_pos
()
150 begin_pos_ptr
.type = nbt
.SEEK_BEGIN
151 end_pos_ptr
.type = nbt
.SEEK_LAST
153 for event
in self
._events
(begin_pos_ptr
, end_pos_ptr
):
156 def events_timestamps(self
, timestamp_begin
, timestamp_end
):
158 Generates the ordered :class:`Event` objects of all the opened
159 traces contained in this trace collection from *timestamp_begin*
162 *timestamp_begin* and *timestamp_end* are given in nanoseconds
165 See :attr:`events` for notes and limitations.
168 begin_pos_ptr
= nbt
._bt
_iter
_pos
()
169 end_pos_ptr
= nbt
._bt
_iter
_pos
()
170 begin_pos_ptr
.type = end_pos_ptr
.type = nbt
.SEEK_TIME
171 begin_pos_ptr
.u
.seek_time
= timestamp_begin
172 end_pos_ptr
.u
.seek_time
= timestamp_end
174 for event
in self
._events
(begin_pos_ptr
, end_pos_ptr
):
178 def timestamp_begin(self
):
180 Begin timestamp of this trace collection (nanoseconds since
184 pos_ptr
= nbt
._bt
_iter
_pos
()
185 pos_ptr
.type = nbt
.SEEK_BEGIN
187 return self
._timestamp
_at
_pos
(pos_ptr
)
190 def timestamp_end(self
):
192 End timestamp of this trace collection (nanoseconds since
196 pos_ptr
= nbt
._bt
_iter
_pos
()
197 pos_ptr
.type = nbt
.SEEK_LAST
199 return self
._timestamp
_at
_pos
(pos_ptr
)
201 def _timestamp_at_pos(self
, pos_ptr
):
202 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, pos_ptr
, pos_ptr
)
204 if ctf_it_ptr
is None:
205 raise NotImplementedError("Creation of multiple iterators is unsupported.")
207 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
208 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
210 ev
= Event
.__new
__(Event
)
215 def _events(self
, begin_pos_ptr
, end_pos_ptr
):
216 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, begin_pos_ptr
, end_pos_ptr
)
218 if ctf_it_ptr
is None:
219 raise NotImplementedError("Creation of multiple iterators is unsupported.")
222 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
227 ev
= Event
.__new
__(Event
)
232 except GeneratorExit
:
235 ret
= nbt
._bt
_iter
_next
(nbt
._bt
_ctf
_get
_iter
(ctf_it_ptr
))
240 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
243 # Based on enum bt_clock_type in clock-type.h
251 A :class:`TraceHandle` is a handle allowing the user to manipulate
252 a specific trace directly. It is a unique identifier representing a
253 trace, and is not meant to be instantiated by the user.
257 raise NotImplementedError("TraceHandle cannot be instantiated")
260 return "Babeltrace TraceHandle: trace_id('{0}')".format(self
._id
)
265 Numeric ID of this trace handle.
273 Path of the underlying trace.
276 return nbt
._bt
_trace
_handle
_get
_path
(self
._trace
_collection
._tc
,
280 def timestamp_begin(self
):
282 Buffers creation timestamp (nanoseconds since Epoch) of the
286 return nbt
._bt
_trace
_handle
_get
_timestamp
_begin
(self
._trace
_collection
._tc
,
288 _ClockType
.CLOCK_REAL
)
291 def timestamp_end(self
):
293 Buffers destruction timestamp (nanoseconds since Epoch) of the
297 return nbt
._bt
_trace
_handle
_get
_timestamp
_end
(self
._trace
_collection
._tc
,
299 _ClockType
.CLOCK_REAL
)
304 Generates all the :class:`EventDeclaration` objects of the
308 ret
= nbt
._bt
_python
_event
_decl
_listcaller
(self
.id,
309 self
._trace
_collection
._tc
)
311 if not isinstance(ret
, list):
314 ptr_list
, count
= ret
316 for i
in range(count
):
317 tmp
= EventDeclaration
.__new
__(EventDeclaration
)
318 tmp
._ed
= nbt
._bt
_python
_decl
_one
_from
_list
(ptr_list
, i
)
324 # Priority of the scopes when searching for event fields
326 common
.CTFScope
.EVENT_FIELDS
,
327 common
.CTFScope
.EVENT_CONTEXT
,
328 common
.CTFScope
.STREAM_EVENT_CONTEXT
,
329 common
.CTFScope
.STREAM_EVENT_HEADER
,
330 common
.CTFScope
.STREAM_PACKET_CONTEXT
,
331 common
.CTFScope
.TRACE_PACKET_HEADER
335 class Event(collections
.Mapping
):
337 An :class:`Event` object represents a trace event. :class:`Event`
338 objects are returned by :attr:`TraceCollection.events` and are
339 not meant to be instantiated by the user.
341 :class:`Event` has a :class:`dict`-like interface for accessing
342 an event's field value by field name:
344 .. code-block:: python
348 If a field name exists in multiple scopes, the value of the first
349 field found is returned. The scopes are searched in the following
352 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
353 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
354 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
355 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
356 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
357 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
359 It is still possible to obtain a field's value from a specific
360 scope using :meth:`field_with_scope`.
362 Field values are returned as native Python types, that is:
364 +-----------------------+----------------------------------+
365 | Field type | Python type |
366 +=======================+==================================+
367 | Integer | :class:`int` |
368 +-----------------------+----------------------------------+
369 | Floating point number | :class:`float` |
370 +-----------------------+----------------------------------+
371 | Enumeration | :class:`str` (enumeration label) |
372 +-----------------------+----------------------------------+
373 | String | :class:`str` |
374 +-----------------------+----------------------------------+
375 | Array | :class:`list` of native Python |
377 +-----------------------+----------------------------------+
378 | Sequence | :class:`list` of native Python |
380 +-----------------------+----------------------------------+
381 | Structure | :class:`dict` mapping field |
382 | | names to native Python objects |
383 +-----------------------+----------------------------------+
385 For example, printing the third element of a sequence named ``seq``
386 in a structure named ``my_struct`` of the ``event``'s field named
387 ``my_field`` is done this way:
389 .. code-block:: python
391 print(event['my_field']['my_struct']['seq'][2])
395 raise NotImplementedError("Event cannot be instantiated")
400 Event name or ``None`` on error.
403 return nbt
._bt
_ctf
_event
_name
(self
._e
)
408 Event timestamp in cycles or -1 on error.
411 return nbt
._bt
_ctf
_get
_cycles
(self
._e
)
416 Event timestamp (nanoseconds since Epoch) or -1 on error.
419 return nbt
._bt
_ctf
_get
_timestamp
(self
._e
)
424 Event timestamp as a standard :class:`datetime.datetime`
427 Note that the :class:`datetime.datetime` class' precision
428 is limited to microseconds, whereas :attr:`timestamp` provides
429 the event's timestamp with a nanosecond resolution.
432 return datetime
.fromtimestamp(self
.timestamp
/ 1E9
)
434 def field_with_scope(self
, field_name
, scope
):
436 Returns the value of a field named *field_name* within the
437 scope *scope*, or ``None`` if the field cannot be found.
439 *scope* must be one of :class:`babeltrace.common.CTFScope`
443 if scope
not in _scopes
:
444 raise ValueError("Invalid scope provided")
446 field
= self
._field
_with
_scope
(field_name
, scope
)
448 if field
is not None:
451 def field_list_with_scope(self
, scope
):
453 Returns a list of field names in the scope *scope*.
456 if scope
not in _scopes
:
457 raise ValueError("Invalid scope provided")
461 for field
in self
._field
_list
_with
_scope
(scope
):
462 field_names
.append(field
.name
)
469 :class:`TraceHandle` object containing this event, or ``None``
473 ret
= nbt
._bt
_ctf
_event
_get
_handle
_id
(self
._e
)
478 th
= TraceHandle
.__new
__(TraceHandle
)
480 th
._trace
_collection
= self
.get_trace_collection()
485 def trace_collection(self
):
487 :class:`TraceCollection` object containing this event, or
491 trace_collection
= TraceCollection()
492 trace_collection
._tc
= nbt
._bt
_ctf
_event
_get
_context
(self
._e
)
494 if trace_collection
._tc
is not None:
495 return trace_collection
497 def __getitem__(self
, field_name
):
498 field
= self
._field
(field_name
)
500 if field
is not None:
503 raise KeyError(field_name
)
506 for key
in self
.keys():
512 for scope
in _scopes
:
513 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
514 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
516 if isinstance(ret
, list):
521 def __contains__(self
, field_name
):
522 return self
._field
(field_name
) is not None
526 Returns the list of field names.
528 Note: field names are unique within the returned list, although
529 a field name could exist in multiple scopes. Use
530 :meth:`field_list_with_scope` to obtain the list of field names
536 for scope
in _scopes
:
537 for name
in self
.field_list_with_scope(scope
):
538 field_names
.add(name
)
540 return list(field_names
)
542 def get(self
, field_name
, default
=None):
544 Returns the value of the field named *field_name*, or *default*
547 See :class:`Event` note about how fields are retrieved by
548 name when multiple fields share the same name in different
552 field
= self
._field
(field_name
)
561 Generates pairs of (field name, field value).
563 This method iterates :meth:`keys` to find field names, which
564 means some fields could be unavailable if other fields share
565 their names in scopes with higher priorities.
568 for field
in self
.keys():
569 yield (field
, self
[field
])
571 def _field_with_scope(self
, field_name
, scope
):
572 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
574 if scope_ptr
is None:
577 definition_ptr
= nbt
._bt
_ctf
_get
_field
(self
._e
, scope_ptr
, field_name
)
579 if definition_ptr
is None:
582 field
= _Definition(definition_ptr
, scope
)
586 def _field(self
, field_name
):
589 for scope
in _scopes
:
590 field
= self
._field
_with
_scope
(field_name
, scope
)
592 if field
is not None:
597 def _field_list_with_scope(self
, scope
):
599 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
601 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
602 # provide the "count" return value
605 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
607 if isinstance(ret
, list):
608 list_ptr
, count
= ret
610 for i
in range(count
):
611 definition_ptr
= nbt
._bt
_python
_field
_one
_from
_list
(list_ptr
, i
)
613 if definition_ptr
is not None:
614 definition
= _Definition(definition_ptr
, scope
)
615 fields
.append(definition
)
620 class FieldError(Exception):
622 Field error, raised when the value of a field cannot be accessed.
625 def __init__(self
, value
):
629 return repr(self
.value
)
632 class EventDeclaration
:
634 An event declaration contains the properties of a class of events,
635 that is, the common properties and fields layout of all the actual
636 recorded events associated with this declaration.
638 This class is not meant to be instantiated by the user. It is
639 returned by :attr:`TraceHandle.events`.
642 MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
645 raise NotImplementedError("EventDeclaration cannot be instantiated")
650 Event name, or ``None`` on error.
653 return nbt
._bt
_ctf
_get
_decl
_event
_name
(self
._ed
)
658 Event numeric ID, or -1 on error.
661 id = nbt
._bt
_ctf
_get
_decl
_event
_id
(self
._ed
)
663 if id == self
.MAX_UINT64
:
671 Generates all the field declarations of this event, going
672 through each scope in the following order:
674 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
675 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
676 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
677 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
678 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
679 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
681 All the generated field declarations inherit
682 :class:`FieldDeclaration`, and are among:
684 * :class:`IntegerFieldDeclaration`
685 * :class:`FloatFieldDeclaration`
686 * :class:`EnumerationFieldDeclaration`
687 * :class:`StringFieldDeclaration`
688 * :class:`ArrayFieldDeclaration`
689 * :class:`SequenceFieldDeclaration`
690 * :class:`StructureFieldDeclaration`
691 * :class:`VariantFieldDeclaration`
694 for scope
in _scopes
:
695 for declaration
in self
.fields_scope(scope
):
698 def fields_scope(self
, scope
):
700 Generates all the field declarations of the event's scope
703 *scope* must be one of :class:`babeltrace.common.CTFScope` constants.
705 All the generated field declarations inherit
706 :class:`FieldDeclaration`, and are among:
708 * :class:`IntegerFieldDeclaration`
709 * :class:`FloatFieldDeclaration`
710 * :class:`EnumerationFieldDeclaration`
711 * :class:`StringFieldDeclaration`
712 * :class:`ArrayFieldDeclaration`
713 * :class:`SequenceFieldDeclaration`
714 * :class:`StructureFieldDeclaration`
715 * :class:`VariantFieldDeclaration`
717 ret
= nbt
._by
_python
_field
_decl
_listcaller
(self
._ed
, scope
)
719 if not isinstance(ret
, list):
722 list_ptr
, count
= ret
724 for i
in range(count
):
725 field_decl_ptr
= nbt
._bt
_python
_field
_decl
_one
_from
_list
(list_ptr
, i
)
727 if field_decl_ptr
is not None:
728 decl_ptr
= nbt
._bt
_ctf
_get
_decl
_from
_field
_decl
(field_decl_ptr
)
729 name
= nbt
._bt
_ctf
_get
_decl
_field
_name
(field_decl_ptr
)
730 field_declaration
= _create_field_declaration(decl_ptr
, name
,
732 yield field_declaration
735 class FieldDeclaration
:
737 Base class for concrete field declarations.
739 This class is not meant to be instantiated by the user.
743 raise NotImplementedError("FieldDeclaration cannot be instantiated")
746 return "({0}) {1} {2}".format(common
.CTFScope
.scope_name(self
.scope
),
747 common
.CTFTypeId
.type_name(self
.type),
753 Field name, or ``None`` on error.
761 Field type (one of :class:`babeltrace.common.CTFTypeId`
765 return nbt
._bt
_ctf
_field
_type
(self
._fd
)
770 Field scope (one of:class:`babeltrace.common.CTFScope`
777 class IntegerFieldDeclaration(FieldDeclaration
):
779 Integer field declaration.
783 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
786 def signedness(self
):
788 0 if this integer is unsigned, 1 if signed, or -1 on error.
791 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
796 Integer base (:class:`int`), or a negative value on error.
799 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
802 def byte_order(self
):
804 Integer byte order (one of
805 :class:`babeltrace.common.ByteOrder` constants).
808 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
811 return common
.ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
813 return common
.ByteOrder
.BYTE_ORDER_BIG_ENDIAN
815 return common
.ByteOrder
.BYTE_ORDER_UNKNOWN
820 Integer size in bits, or a negative value on error.
822 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
831 Integer encoding (one of
832 :class:`babeltrace.common.CTFStringEncoding` constants).
835 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
838 class EnumerationFieldDeclaration(FieldDeclaration
):
840 Enumeration field declaration.
844 As of this version, this class is missing some properties.
848 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
851 class ArrayFieldDeclaration(FieldDeclaration
):
853 Static array field declaration.
857 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
862 Fixed length of this static array (number of contained
863 elements), or a negative value on error.
866 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
869 def element_declaration(self
):
871 Field declaration of the underlying element.
874 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
876 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
879 class SequenceFieldDeclaration(FieldDeclaration
):
881 Sequence (dynamic array) field declaration.
885 As of this version, this class is missing some properties.
889 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
892 def element_declaration(self
):
894 Field declaration of the underlying element.
897 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
899 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
902 class FloatFieldDeclaration(FieldDeclaration
):
904 Floating point number field declaration.
908 As of this version, this class is missing some properties.
912 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
915 class StructureFieldDeclaration(FieldDeclaration
):
917 Structure (ordered map of field names to field declarations) field
922 As of this version, this class is missing some properties.
926 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
929 class StringFieldDeclaration(FieldDeclaration
):
931 String (NULL-terminated array of bytes) field declaration.
935 As of this version, this class is missing some properties.
939 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
942 class VariantFieldDeclaration(FieldDeclaration
):
944 Variant (dynamic selection between different types) field declaration.
948 As of this version, this class is missing some properties.
952 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
957 Return the last error code encountered while
958 accessing a field and reset the error flag.
959 Return 0 if no error, a negative value otherwise.
962 return nbt
._bt
_ctf
_field
_get
_error
()
965 def _create_field_declaration(declaration_ptr
, name
, scope
):
967 Private field declaration factory.
970 if declaration_ptr
is None:
971 raise ValueError("declaration_ptr must be valid")
972 if scope
not in _scopes
:
973 raise ValueError("Invalid scope provided")
975 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
978 if type == common
.CTFTypeId
.INTEGER
:
979 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
980 elif type == common
.CTFTypeId
.ENUM
:
981 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
982 elif type == common
.CTFTypeId
.ARRAY
:
983 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
984 elif type == common
.CTFTypeId
.SEQUENCE
:
985 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
986 elif type == common
.CTFTypeId
.FLOAT
:
987 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
988 elif type == common
.CTFTypeId
.STRUCT
:
989 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
990 elif type == common
.CTFTypeId
.STRING
:
991 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
992 elif type == common
.CTFTypeId
.VARIANT
:
993 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
997 declaration
._fd
= declaration_ptr
998 declaration
._s
= scope
999 declaration
._name
= name
1005 def __init__(self
, definition_ptr
, scope
):
1006 self
._d
= definition_ptr
1009 if scope
not in _scopes
:
1010 ValueError("Invalid scope provided")
1014 """Return the name of a field or None on error."""
1016 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1020 """Return the type of a field or -1 if unknown."""
1022 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1025 def declaration(self
):
1026 """Return the associated Definition object."""
1028 return _create_field_declaration(
1029 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1031 def _get_enum_str(self
):
1033 Return the string matching the current enumeration.
1034 Return None on error.
1037 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1039 def _get_array_element_at(self
, index
):
1041 Return the array's element at position index.
1042 Return None on error
1045 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1047 if array_ptr
is None:
1050 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1052 if definition_ptr
is None:
1055 return _Definition(definition_ptr
, self
.scope
)
1057 def _get_sequence_len(self
):
1059 Return the len of a sequence or a negative
1063 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1065 return nbt
._bt
_sequence
_len
(seq
)
1067 def _get_sequence_element_at(self
, index
):
1069 Return the sequence's element at position index,
1070 otherwise return None
1073 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1076 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1078 if definition_ptr
is not None:
1079 return _Definition(definition_ptr
, self
.scope
)
1081 def _get_uint64(self
):
1083 Return the value associated with the field.
1084 If the field does not exist or is not of the type requested,
1085 the value returned is undefined. To check if an error occured,
1086 use the field_error() function after accessing a field.
1089 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1091 def _get_int64(self
):
1093 Return the value associated with the field.
1094 If the field does not exist or is not of the type requested,
1095 the value returned is undefined. To check if an error occured,
1096 use the field_error() function after accessing a field.
1099 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1101 def _get_char_array(self
):
1103 Return the value associated with the field.
1104 If the field does not exist or is not of the type requested,
1105 the value returned is undefined. To check if an error occurred,
1106 use the field_error() function after accessing a field.
1109 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1113 Return the value associated with the field.
1114 If the field does not exist or is not of the type requested,
1115 the value returned is undefined. To check if an error occurred,
1116 use the field_error() function after accessing a field.
1119 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1121 def _get_float(self
):
1123 Return the value associated with the field.
1124 If the field does not exist or is not of the type requested,
1125 the value returned is undefined. To check if an error occurred,
1126 use the field_error() function after accessing a field.
1129 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1131 def _get_variant(self
):
1133 Return the variant's selected field.
1134 If the field does not exist or is not of the type requested,
1135 the value returned is undefined. To check if an error occurred,
1136 use the field_error() function after accessing a field.
1139 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1141 def _get_struct_field_count(self
):
1143 Return the number of fields contained in the structure.
1144 If the field does not exist or is not of the type requested,
1145 the value returned is undefined.
1148 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1150 def _get_struct_field_at(self
, i
):
1152 Return the structure's field at position i.
1153 If the field does not exist or is not of the type requested,
1154 the value returned is undefined. To check if an error occurred,
1155 use the field_error() function after accessing a field.
1158 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1163 Return the value associated with the field according to its type.
1164 Return None on error.
1170 if id == common
.CTFTypeId
.STRING
:
1171 value
= self
._get
_str
()
1172 elif id == common
.CTFTypeId
.ARRAY
:
1173 element_decl
= self
.declaration
.element_declaration
1175 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1176 and element_decl
.length
== 8)
1177 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1178 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1182 for i
in range(self
.declaration
.length
):
1183 element
= self
._get
_array
_element
_at
(i
)
1184 value
.append(element
.value
)
1185 elif id == common
.CTFTypeId
.INTEGER
:
1186 if self
.declaration
.signedness
== 0:
1187 value
= self
._get
_uint
64()
1189 value
= self
._get
_int
64()
1190 elif id == common
.CTFTypeId
.ENUM
:
1191 value
= self
._get
_enum
_str
()
1192 elif id == common
.CTFTypeId
.SEQUENCE
:
1193 element_decl
= self
.declaration
.element_declaration
1195 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1196 and element_decl
.length
== 8)
1197 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1198 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1200 seq_len
= self
._get
_sequence
_len
()
1203 for i
in range(seq_len
):
1204 evDef
= self
._get
_sequence
_element
_at
(i
)
1205 value
.append(evDef
.value
)
1206 elif id == common
.CTFTypeId
.FLOAT
:
1207 value
= self
._get
_float
()
1208 elif id == common
.CTFTypeId
.VARIANT
:
1209 variant
= _Definition
.__new
__(_Definition
)
1210 variant
._d
= self
._get
_variant
()
1211 value
= variant
.value
1212 elif id == common
.CTFTypeId
.STRUCT
:
1215 for i
in range(self
._get
_struct
_field
_count
()):
1216 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1217 value
[member
.name
] = member
.value
1221 "Error occurred while accessing field {} of type {}".format(
1223 common
.CTFTypeId
.type_name(id)))
1229 """Return the scope of a field or None on error."""