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
_python
_create
_iter
_pos
()
149 end_pos_ptr
= nbt
._bt
_python
_create
_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 nbt
._bt
_iter
_free
_pos
(begin_pos_ptr
);
157 nbt
._bt
_iter
_free
_pos
(end_pos_ptr
);
159 def events_timestamps(self
, timestamp_begin
, timestamp_end
):
161 Generates the ordered :class:`Event` objects of all the opened
162 traces contained in this trace collection from *timestamp_begin*
165 *timestamp_begin* and *timestamp_end* are given in nanoseconds
168 See :attr:`events` for notes and limitations.
171 begin_pos_ptr
= nbt
._bt
_python
_create
_iter
_pos
()
172 end_pos_ptr
= nbt
._bt
_python
_create
_iter
_pos
()
173 begin_pos_ptr
.type = end_pos_ptr
.type = nbt
.SEEK_TIME
174 begin_pos_ptr
.u
.seek_time
= timestamp_begin
175 end_pos_ptr
.u
.seek_time
= timestamp_end
177 for event
in self
._events
(begin_pos_ptr
, end_pos_ptr
):
180 nbt
._bt
_iter
_free
_pos
(begin_pos_ptr
);
181 nbt
._bt
_iter
_free
_pos
(end_pos_ptr
);
184 def timestamp_begin(self
):
186 Begin timestamp of this trace collection (nanoseconds since
190 pos_ptr
= nbt
._bt
_iter
_pos
()
191 pos_ptr
.type = nbt
.SEEK_BEGIN
193 return self
._timestamp
_at
_pos
(pos_ptr
)
196 def timestamp_end(self
):
198 End timestamp of this trace collection (nanoseconds since
202 pos_ptr
= nbt
._bt
_iter
_pos
()
203 pos_ptr
.type = nbt
.SEEK_LAST
205 return self
._timestamp
_at
_pos
(pos_ptr
)
207 def _timestamp_at_pos(self
, pos_ptr
):
208 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, pos_ptr
, pos_ptr
)
210 if ctf_it_ptr
is None:
211 raise NotImplementedError("Creation of multiple iterators is unsupported.")
213 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
214 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
216 ev
= Event
.__new
__(Event
)
221 def _events(self
, begin_pos_ptr
, end_pos_ptr
):
222 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, begin_pos_ptr
, end_pos_ptr
)
224 if ctf_it_ptr
is None:
225 raise NotImplementedError("Creation of multiple iterators is unsupported.")
228 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
233 ev
= Event
.__new
__(Event
)
238 except GeneratorExit
:
241 ret
= nbt
._bt
_iter
_next
(nbt
._bt
_ctf
_get
_iter
(ctf_it_ptr
))
246 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
249 # Based on enum bt_clock_type in clock-type.h
257 A :class:`TraceHandle` is a handle allowing the user to manipulate
258 a specific trace directly. It is a unique identifier representing a
259 trace, and is not meant to be instantiated by the user.
263 raise NotImplementedError("TraceHandle cannot be instantiated")
266 return "Babeltrace TraceHandle: trace_id('{0}')".format(self
._id
)
271 Numeric ID of this trace handle.
279 Path of the underlying trace.
282 return nbt
._bt
_trace
_handle
_get
_path
(self
._trace
_collection
._tc
,
286 def timestamp_begin(self
):
288 Buffers creation timestamp (nanoseconds since Epoch) of the
292 return nbt
._bt
_trace
_handle
_get
_timestamp
_begin
(self
._trace
_collection
._tc
,
294 _ClockType
.CLOCK_REAL
)
297 def timestamp_end(self
):
299 Buffers destruction timestamp (nanoseconds since Epoch) of the
303 return nbt
._bt
_trace
_handle
_get
_timestamp
_end
(self
._trace
_collection
._tc
,
305 _ClockType
.CLOCK_REAL
)
310 Generates all the :class:`EventDeclaration` objects of the
314 ret
= nbt
._bt
_python
_event
_decl
_listcaller
(self
.id,
315 self
._trace
_collection
._tc
)
317 if not isinstance(ret
, list):
320 ptr_list
, count
= ret
322 for i
in range(count
):
323 tmp
= EventDeclaration
.__new
__(EventDeclaration
)
324 tmp
._ed
= nbt
._bt
_python
_decl
_one
_from
_list
(ptr_list
, i
)
330 # Priority of the scopes when searching for event fields
332 common
.CTFScope
.EVENT_FIELDS
,
333 common
.CTFScope
.EVENT_CONTEXT
,
334 common
.CTFScope
.STREAM_EVENT_CONTEXT
,
335 common
.CTFScope
.STREAM_EVENT_HEADER
,
336 common
.CTFScope
.STREAM_PACKET_CONTEXT
,
337 common
.CTFScope
.TRACE_PACKET_HEADER
341 class Event(collections
.Mapping
):
343 An :class:`Event` object represents a trace event. :class:`Event`
344 objects are returned by :attr:`TraceCollection.events` and are
345 not meant to be instantiated by the user.
347 :class:`Event` has a :class:`dict`-like interface for accessing
348 an event's field value by field name:
350 .. code-block:: python
354 If a field name exists in multiple scopes, the value of the first
355 field found is returned. The scopes are searched in the following
358 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
359 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
360 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
361 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
362 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
363 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
365 It is still possible to obtain a field's value from a specific
366 scope using :meth:`field_with_scope`.
368 Field values are returned as native Python types, that is:
370 +-----------------------+----------------------------------+
371 | Field type | Python type |
372 +=======================+==================================+
373 | Integer | :class:`int` |
374 +-----------------------+----------------------------------+
375 | Floating point number | :class:`float` |
376 +-----------------------+----------------------------------+
377 | Enumeration | :class:`str` (enumeration label) |
378 +-----------------------+----------------------------------+
379 | String | :class:`str` |
380 +-----------------------+----------------------------------+
381 | Array | :class:`list` of native Python |
383 +-----------------------+----------------------------------+
384 | Sequence | :class:`list` of native Python |
386 +-----------------------+----------------------------------+
387 | Structure | :class:`dict` mapping field |
388 | | names to native Python objects |
389 +-----------------------+----------------------------------+
391 For example, printing the third element of a sequence named ``seq``
392 in a structure named ``my_struct`` of the ``event``'s field named
393 ``my_field`` is done this way:
395 .. code-block:: python
397 print(event['my_field']['my_struct']['seq'][2])
401 raise NotImplementedError("Event cannot be instantiated")
406 Event name or ``None`` on error.
409 return nbt
._bt
_ctf
_event
_name
(self
._e
)
414 Event timestamp in cycles or -1 on error.
417 return nbt
._bt
_ctf
_get
_cycles
(self
._e
)
422 Event timestamp (nanoseconds since Epoch) or -1 on error.
425 return nbt
._bt
_ctf
_get
_timestamp
(self
._e
)
430 Event timestamp as a standard :class:`datetime.datetime`
433 Note that the :class:`datetime.datetime` class' precision
434 is limited to microseconds, whereas :attr:`timestamp` provides
435 the event's timestamp with a nanosecond resolution.
438 return datetime
.fromtimestamp(self
.timestamp
/ 1E9
)
440 def field_with_scope(self
, field_name
, scope
):
442 Returns the value of a field named *field_name* within the
443 scope *scope*, or ``None`` if the field cannot be found.
445 *scope* must be one of :class:`babeltrace.common.CTFScope`
449 if scope
not in _scopes
:
450 raise ValueError("Invalid scope provided")
452 field
= self
._field
_with
_scope
(field_name
, scope
)
454 if field
is not None:
457 def field_list_with_scope(self
, scope
):
459 Returns a list of field names in the scope *scope*.
462 if scope
not in _scopes
:
463 raise ValueError("Invalid scope provided")
467 for field
in self
._field
_list
_with
_scope
(scope
):
468 field_names
.append(field
.name
)
475 :class:`TraceHandle` object containing this event, or ``None``
479 ret
= nbt
._bt
_ctf
_event
_get
_handle
_id
(self
._e
)
484 th
= TraceHandle
.__new
__(TraceHandle
)
486 th
._trace
_collection
= self
.get_trace_collection()
491 def trace_collection(self
):
493 :class:`TraceCollection` object containing this event, or
497 trace_collection
= TraceCollection()
498 trace_collection
._tc
= nbt
._bt
_ctf
_event
_get
_context
(self
._e
)
500 if trace_collection
._tc
is not None:
501 return trace_collection
503 def __getitem__(self
, field_name
):
504 field
= self
._field
(field_name
)
506 if field
is not None:
509 raise KeyError(field_name
)
512 for key
in self
.keys():
518 for scope
in _scopes
:
519 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
520 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
522 if isinstance(ret
, list):
527 def __contains__(self
, field_name
):
528 return self
._field
(field_name
) is not None
532 Returns the list of field names.
534 Note: field names are unique within the returned list, although
535 a field name could exist in multiple scopes. Use
536 :meth:`field_list_with_scope` to obtain the list of field names
542 for scope
in _scopes
:
543 for name
in self
.field_list_with_scope(scope
):
544 field_names
.add(name
)
546 return list(field_names
)
548 def get(self
, field_name
, default
=None):
550 Returns the value of the field named *field_name*, or *default*
553 See :class:`Event` note about how fields are retrieved by
554 name when multiple fields share the same name in different
558 field
= self
._field
(field_name
)
567 Generates pairs of (field name, field value).
569 This method iterates :meth:`keys` to find field names, which
570 means some fields could be unavailable if other fields share
571 their names in scopes with higher priorities.
574 for field
in self
.keys():
575 yield (field
, self
[field
])
577 def _field_with_scope(self
, field_name
, scope
):
578 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
580 if scope_ptr
is None:
583 definition_ptr
= nbt
._bt
_ctf
_get
_field
(self
._e
, scope_ptr
, field_name
)
585 if definition_ptr
is None:
588 field
= _Definition(definition_ptr
, scope
)
592 def _field(self
, field_name
):
595 for scope
in _scopes
:
596 field
= self
._field
_with
_scope
(field_name
, scope
)
598 if field
is not None:
603 def _field_list_with_scope(self
, scope
):
605 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
607 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
608 # provide the "count" return value
611 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
613 if isinstance(ret
, list):
614 list_ptr
, count
= ret
616 for i
in range(count
):
617 definition_ptr
= nbt
._bt
_python
_field
_one
_from
_list
(list_ptr
, i
)
619 if definition_ptr
is not None:
620 definition
= _Definition(definition_ptr
, scope
)
621 fields
.append(definition
)
626 class FieldError(Exception):
628 Field error, raised when the value of a field cannot be accessed.
631 def __init__(self
, value
):
635 return repr(self
.value
)
638 class EventDeclaration
:
640 An event declaration contains the properties of a class of events,
641 that is, the common properties and fields layout of all the actual
642 recorded events associated with this declaration.
644 This class is not meant to be instantiated by the user. It is
645 returned by :attr:`TraceHandle.events`.
648 MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
651 raise NotImplementedError("EventDeclaration cannot be instantiated")
656 Event name, or ``None`` on error.
659 return nbt
._bt
_ctf
_get
_decl
_event
_name
(self
._ed
)
664 Event numeric ID, or -1 on error.
667 id = nbt
._bt
_ctf
_get
_decl
_event
_id
(self
._ed
)
669 if id == self
.MAX_UINT64
:
677 Generates all the field declarations of this event, going
678 through each scope in the following order:
680 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
681 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
682 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
683 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
684 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
685 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
687 All the generated field declarations inherit
688 :class:`FieldDeclaration`, and are among:
690 * :class:`IntegerFieldDeclaration`
691 * :class:`FloatFieldDeclaration`
692 * :class:`EnumerationFieldDeclaration`
693 * :class:`StringFieldDeclaration`
694 * :class:`ArrayFieldDeclaration`
695 * :class:`SequenceFieldDeclaration`
696 * :class:`StructureFieldDeclaration`
697 * :class:`VariantFieldDeclaration`
700 for scope
in _scopes
:
701 for declaration
in self
.fields_scope(scope
):
704 def fields_scope(self
, scope
):
706 Generates all the field declarations of the event's scope
709 *scope* must be one of :class:`babeltrace.common.CTFScope` constants.
711 All the generated field declarations inherit
712 :class:`FieldDeclaration`, and are among:
714 * :class:`IntegerFieldDeclaration`
715 * :class:`FloatFieldDeclaration`
716 * :class:`EnumerationFieldDeclaration`
717 * :class:`StringFieldDeclaration`
718 * :class:`ArrayFieldDeclaration`
719 * :class:`SequenceFieldDeclaration`
720 * :class:`StructureFieldDeclaration`
721 * :class:`VariantFieldDeclaration`
723 ret
= nbt
._by
_python
_field
_decl
_listcaller
(self
._ed
, scope
)
725 if not isinstance(ret
, list):
728 list_ptr
, count
= ret
730 for i
in range(count
):
731 field_decl_ptr
= nbt
._bt
_python
_field
_decl
_one
_from
_list
(list_ptr
, i
)
733 if field_decl_ptr
is not None:
734 decl_ptr
= nbt
._bt
_ctf
_get
_decl
_from
_field
_decl
(field_decl_ptr
)
735 name
= nbt
._bt
_ctf
_get
_decl
_field
_name
(field_decl_ptr
)
736 field_declaration
= _create_field_declaration(decl_ptr
, name
,
738 yield field_declaration
741 class FieldDeclaration
:
743 Base class for concrete field declarations.
745 This class is not meant to be instantiated by the user.
749 raise NotImplementedError("FieldDeclaration cannot be instantiated")
752 return "({0}) {1} {2}".format(common
.CTFScope
.scope_name(self
.scope
),
753 common
.CTFTypeId
.type_name(self
.type),
759 Field name, or ``None`` on error.
767 Field type (one of :class:`babeltrace.common.CTFTypeId`
771 return nbt
._bt
_ctf
_field
_type
(self
._fd
)
776 Field scope (one of:class:`babeltrace.common.CTFScope`
783 class IntegerFieldDeclaration(FieldDeclaration
):
785 Integer field declaration.
789 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
792 def signedness(self
):
794 0 if this integer is unsigned, 1 if signed, or -1 on error.
797 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
802 Integer base (:class:`int`), or a negative value on error.
805 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
808 def byte_order(self
):
810 Integer byte order (one of
811 :class:`babeltrace.common.ByteOrder` constants).
814 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
817 return common
.ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
819 return common
.ByteOrder
.BYTE_ORDER_BIG_ENDIAN
821 return common
.ByteOrder
.BYTE_ORDER_UNKNOWN
826 Integer size in bits, or a negative value on error.
828 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
837 Integer encoding (one of
838 :class:`babeltrace.common.CTFStringEncoding` constants).
841 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
844 class EnumerationFieldDeclaration(FieldDeclaration
):
846 Enumeration field declaration.
850 As of this version, this class is missing some properties.
854 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
857 class ArrayFieldDeclaration(FieldDeclaration
):
859 Static array field declaration.
863 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
868 Fixed length of this static array (number of contained
869 elements), or a negative value on error.
872 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
875 def element_declaration(self
):
877 Field declaration of the underlying element.
880 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
882 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
885 class SequenceFieldDeclaration(FieldDeclaration
):
887 Sequence (dynamic array) field declaration.
891 As of this version, this class is missing some properties.
895 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
898 def element_declaration(self
):
900 Field declaration of the underlying element.
903 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
905 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
908 class FloatFieldDeclaration(FieldDeclaration
):
910 Floating point number field declaration.
914 As of this version, this class is missing some properties.
918 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
921 class StructureFieldDeclaration(FieldDeclaration
):
923 Structure (ordered map of field names to field declarations) field
928 As of this version, this class is missing some properties.
932 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
935 class StringFieldDeclaration(FieldDeclaration
):
937 String (NULL-terminated array of bytes) field declaration.
941 As of this version, this class is missing some properties.
945 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
948 class VariantFieldDeclaration(FieldDeclaration
):
950 Variant (dynamic selection between different types) field declaration.
954 As of this version, this class is missing some properties.
958 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
963 Return the last error code encountered while
964 accessing a field and reset the error flag.
965 Return 0 if no error, a negative value otherwise.
968 return nbt
._bt
_ctf
_field
_get
_error
()
971 def _create_field_declaration(declaration_ptr
, name
, scope
):
973 Private field declaration factory.
976 if declaration_ptr
is None:
977 raise ValueError("declaration_ptr must be valid")
978 if scope
not in _scopes
:
979 raise ValueError("Invalid scope provided")
981 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
984 if type == common
.CTFTypeId
.INTEGER
:
985 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
986 elif type == common
.CTFTypeId
.ENUM
:
987 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
988 elif type == common
.CTFTypeId
.ARRAY
:
989 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
990 elif type == common
.CTFTypeId
.SEQUENCE
:
991 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
992 elif type == common
.CTFTypeId
.FLOAT
:
993 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
994 elif type == common
.CTFTypeId
.STRUCT
:
995 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
996 elif type == common
.CTFTypeId
.STRING
:
997 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
998 elif type == common
.CTFTypeId
.VARIANT
:
999 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
1003 declaration
._fd
= declaration_ptr
1004 declaration
._s
= scope
1005 declaration
._name
= name
1011 def __init__(self
, definition_ptr
, scope
):
1012 self
._d
= definition_ptr
1015 if scope
not in _scopes
:
1016 ValueError("Invalid scope provided")
1020 """Return the name of a field or None on error."""
1022 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1026 """Return the type of a field or -1 if unknown."""
1028 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1031 def declaration(self
):
1032 """Return the associated Definition object."""
1034 return _create_field_declaration(
1035 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1037 def _get_enum_str(self
):
1039 Return the string matching the current enumeration.
1040 Return None on error.
1043 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1045 def _get_array_element_at(self
, index
):
1047 Return the array's element at position index.
1048 Return None on error
1051 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1053 if array_ptr
is None:
1056 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1058 if definition_ptr
is None:
1061 return _Definition(definition_ptr
, self
.scope
)
1063 def _get_sequence_len(self
):
1065 Return the len of a sequence or a negative
1069 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1071 return nbt
._bt
_sequence
_len
(seq
)
1073 def _get_sequence_element_at(self
, index
):
1075 Return the sequence's element at position index,
1076 otherwise return None
1079 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1082 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1084 if definition_ptr
is not None:
1085 return _Definition(definition_ptr
, self
.scope
)
1087 def _get_uint64(self
):
1089 Return the value associated with the field.
1090 If the field does not exist or is not of the type requested,
1091 the value returned is undefined. To check if an error occured,
1092 use the field_error() function after accessing a field.
1095 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1097 def _get_int64(self
):
1099 Return the value associated with the field.
1100 If the field does not exist or is not of the type requested,
1101 the value returned is undefined. To check if an error occured,
1102 use the field_error() function after accessing a field.
1105 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1107 def _get_char_array(self
):
1109 Return the value associated with the field.
1110 If the field does not exist or is not of the type requested,
1111 the value returned is undefined. To check if an error occurred,
1112 use the field_error() function after accessing a field.
1115 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1119 Return the value associated with the field.
1120 If the field does not exist or is not of the type requested,
1121 the value returned is undefined. To check if an error occurred,
1122 use the field_error() function after accessing a field.
1125 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1127 def _get_float(self
):
1129 Return the value associated with the field.
1130 If the field does not exist or is not of the type requested,
1131 the value returned is undefined. To check if an error occurred,
1132 use the field_error() function after accessing a field.
1135 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1137 def _get_variant(self
):
1139 Return the variant's selected field.
1140 If the field does not exist or is not of the type requested,
1141 the value returned is undefined. To check if an error occurred,
1142 use the field_error() function after accessing a field.
1145 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1147 def _get_struct_field_count(self
):
1149 Return the number of fields contained in the structure.
1150 If the field does not exist or is not of the type requested,
1151 the value returned is undefined.
1154 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1156 def _get_struct_field_at(self
, i
):
1158 Return the structure's field at position i.
1159 If the field does not exist or is not of the type requested,
1160 the value returned is undefined. To check if an error occurred,
1161 use the field_error() function after accessing a field.
1164 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1169 Return the value associated with the field according to its type.
1170 Return None on error.
1176 if id == common
.CTFTypeId
.STRING
:
1177 value
= self
._get
_str
()
1178 elif id == common
.CTFTypeId
.ARRAY
:
1179 element_decl
= self
.declaration
.element_declaration
1181 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1182 and element_decl
.length
== 8)
1183 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1184 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1188 for i
in range(self
.declaration
.length
):
1189 element
= self
._get
_array
_element
_at
(i
)
1190 value
.append(element
.value
)
1191 elif id == common
.CTFTypeId
.INTEGER
:
1192 if self
.declaration
.signedness
== 0:
1193 value
= self
._get
_uint
64()
1195 value
= self
._get
_int
64()
1196 elif id == common
.CTFTypeId
.ENUM
:
1197 value
= self
._get
_enum
_str
()
1198 elif id == common
.CTFTypeId
.SEQUENCE
:
1199 element_decl
= self
.declaration
.element_declaration
1201 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1202 and element_decl
.length
== 8)
1203 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1204 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1206 seq_len
= self
._get
_sequence
_len
()
1209 for i
in range(seq_len
):
1210 evDef
= self
._get
_sequence
_element
_at
(i
)
1211 value
.append(evDef
.value
)
1212 elif id == common
.CTFTypeId
.FLOAT
:
1213 value
= self
._get
_float
()
1214 elif id == common
.CTFTypeId
.VARIANT
:
1215 variant
= _Definition
.__new
__(_Definition
)
1216 variant
._d
= self
._get
_variant
()
1217 value
= variant
.value
1218 elif id == common
.CTFTypeId
.STRUCT
:
1221 for i
in range(self
._get
_struct
_field
_count
()):
1222 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1223 value
[member
.name
] = member
.value
1227 "Error occurred while accessing field {} of type {}".format(
1229 common
.CTFTypeId
.type_name(id)))
1235 """Return the scope of a field or None on error."""