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 def _events(self
, begin_pos_ptr
, end_pos_ptr
):
211 ctf_it_ptr
= nbt
._bt
_ctf
_iter
_create
(self
._tc
, begin_pos_ptr
, end_pos_ptr
)
213 if ctf_it_ptr
is None:
214 raise NotImplementedError("Creation of multiple iterators is unsupported.")
217 ev_ptr
= nbt
._bt
_ctf
_iter
_read
_event
(ctf_it_ptr
)
222 ev
= Event
.__new
__(Event
)
227 except GeneratorExit
:
230 ret
= nbt
._bt
_iter
_next
(nbt
._bt
_ctf
_get
_iter
(ctf_it_ptr
))
235 nbt
._bt
_ctf
_iter
_destroy
(ctf_it_ptr
)
238 # Based on enum bt_clock_type in clock-type.h
246 A :class:`TraceHandle` is a handle allowing the user to manipulate
247 a specific trace directly. It is a unique identifier representing a
248 trace, and is not meant to be instantiated by the user.
252 raise NotImplementedError("TraceHandle cannot be instantiated")
255 return "Babeltrace TraceHandle: trace_id('{0}')".format(self
._id
)
260 Numeric ID of this trace handle.
268 Path of the underlying trace.
271 return nbt
._bt
_trace
_handle
_get
_path
(self
._trace
_collection
._tc
,
275 def timestamp_begin(self
):
277 Buffers creation timestamp (nanoseconds since Epoch) of the
281 return nbt
._bt
_trace
_handle
_get
_timestamp
_begin
(self
._trace
_collection
._tc
,
283 _ClockType
.CLOCK_REAL
)
286 def timestamp_end(self
):
288 Buffers destruction timestamp (nanoseconds since Epoch) of the
292 return nbt
._bt
_trace
_handle
_get
_timestamp
_end
(self
._trace
_collection
._tc
,
294 _ClockType
.CLOCK_REAL
)
299 Generates all the :class:`EventDeclaration` objects of the
303 ret
= nbt
._bt
_python
_event
_decl
_listcaller
(self
.id,
304 self
._trace
_collection
._tc
)
306 if not isinstance(ret
, list):
309 ptr_list
, count
= ret
311 for i
in range(count
):
312 tmp
= EventDeclaration
.__new
__(EventDeclaration
)
313 tmp
._ed
= nbt
._bt
_python
_decl
_one
_from
_list
(ptr_list
, i
)
319 # Priority of the scopes when searching for event fields
321 common
.CTFScope
.EVENT_FIELDS
,
322 common
.CTFScope
.EVENT_CONTEXT
,
323 common
.CTFScope
.STREAM_EVENT_CONTEXT
,
324 common
.CTFScope
.STREAM_EVENT_HEADER
,
325 common
.CTFScope
.STREAM_PACKET_CONTEXT
,
326 common
.CTFScope
.TRACE_PACKET_HEADER
330 class Event(collections
.Mapping
):
332 An :class:`Event` object represents a trace event. :class:`Event`
333 objects are returned by :attr:`TraceCollection.events` and are
334 not meant to be instantiated by the user.
336 :class:`Event` has a :class:`dict`-like interface for accessing
337 an event's field value by field name:
339 .. code-block:: python
343 If a field name exists in multiple scopes, the value of the first
344 field found is returned. The scopes are searched in the following
347 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
348 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
349 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
350 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
351 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
352 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
354 It is still possible to obtain a field's value from a specific
355 scope using :meth:`field_with_scope`.
357 Field values are returned as native Python types, that is:
359 +-----------------------+----------------------------------+
360 | Field type | Python type |
361 +=======================+==================================+
362 | Integer | :class:`int` |
363 +-----------------------+----------------------------------+
364 | Floating point number | :class:`float` |
365 +-----------------------+----------------------------------+
366 | Enumeration | :class:`str` (enumeration label) |
367 +-----------------------+----------------------------------+
368 | String | :class:`str` |
369 +-----------------------+----------------------------------+
370 | Array | :class:`list` of native Python |
372 +-----------------------+----------------------------------+
373 | Sequence | :class:`list` of native Python |
375 +-----------------------+----------------------------------+
376 | Structure | :class:`dict` mapping field |
377 | | names to native Python objects |
378 +-----------------------+----------------------------------+
380 For example, printing the third element of a sequence named ``seq``
381 in a structure named ``my_struct`` of the ``event``'s field named
382 ``my_field`` is done this way:
384 .. code-block:: python
386 print(event['my_field']['my_struct']['seq'][2])
390 raise NotImplementedError("Event cannot be instantiated")
395 Event name or ``None`` on error.
398 return nbt
._bt
_ctf
_event
_name
(self
._e
)
403 Event timestamp in cycles or -1 on error.
406 return nbt
._bt
_ctf
_get
_cycles
(self
._e
)
411 Event timestamp (nanoseconds since Epoch) or -1 on error.
414 return nbt
._bt
_ctf
_get
_timestamp
(self
._e
)
419 Event timestamp as a standard :class:`datetime.datetime`
422 Note that the :class:`datetime.datetime` class' precision
423 is limited to microseconds, whereas :attr:`timestamp` provides
424 the event's timestamp with a nanosecond resolution.
427 return datetime
.fromtimestamp(self
.timestamp
/ 1E9
)
429 def field_with_scope(self
, field_name
, scope
):
431 Returns the value of a field named *field_name* within the
432 scope *scope*, or ``None`` if the field cannot be found.
434 *scope* must be one of :class:`babeltrace.common.CTFScope`
438 if scope
not in _scopes
:
439 raise ValueError("Invalid scope provided")
441 field
= self
._field
_with
_scope
(field_name
, scope
)
443 if field
is not None:
446 def field_list_with_scope(self
, scope
):
448 Returns a list of field names in the scope *scope*.
451 if scope
not in _scopes
:
452 raise ValueError("Invalid scope provided")
456 for field
in self
._field
_list
_with
_scope
(scope
):
457 field_names
.append(field
.name
)
464 :class:`TraceHandle` object containing this event, or ``None``
468 ret
= nbt
._bt
_ctf
_event
_get
_handle
_id
(self
._e
)
473 th
= TraceHandle
.__new
__(TraceHandle
)
475 th
._trace
_collection
= self
.get_trace_collection()
480 def trace_collection(self
):
482 :class:`TraceCollection` object containing this event, or
486 trace_collection
= TraceCollection()
487 trace_collection
._tc
= nbt
._bt
_ctf
_event
_get
_context
(self
._e
)
489 if trace_collection
._tc
is not None:
490 return trace_collection
492 def __getitem__(self
, field_name
):
493 field
= self
._field
(field_name
)
495 if field
is not None:
498 raise KeyError(field_name
)
501 for key
in self
.keys():
507 for scope
in _scopes
:
508 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
509 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
511 if isinstance(ret
, list):
516 def __contains__(self
, field_name
):
517 return self
._field
(field_name
) is not None
521 Returns the list of field names.
523 Note: field names are unique within the returned list, although
524 a field name could exist in multiple scopes. Use
525 :meth:`field_list_with_scope` to obtain the list of field names
531 for scope
in _scopes
:
532 for name
in self
.field_list_with_scope(scope
):
533 field_names
.add(name
)
535 return list(field_names
)
537 def get(self
, field_name
, default
=None):
539 Returns the value of the field named *field_name*, or *default*
542 See :class:`Event` note about how fields are retrieved by
543 name when multiple fields share the same name in different
547 field
= self
._field
(field_name
)
556 Generates pairs of (field name, field value).
558 This method iterates :meth:`keys` to find field names, which
559 means some fields could be unavailable if other fields share
560 their names in scopes with higher priorities.
563 for field
in self
.keys():
564 yield (field
, self
[field
])
566 def _field_with_scope(self
, field_name
, scope
):
567 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
569 if scope_ptr
is None:
572 definition_ptr
= nbt
._bt
_ctf
_get
_field
(self
._e
, scope_ptr
, field_name
)
574 if definition_ptr
is None:
577 field
= _Definition(definition_ptr
, scope
)
581 def _field(self
, field_name
):
584 for scope
in _scopes
:
585 field
= self
._field
_with
_scope
(field_name
, scope
)
587 if field
is not None:
592 def _field_list_with_scope(self
, scope
):
594 scope_ptr
= nbt
._bt
_ctf
_get
_top
_level
_scope
(self
._e
, scope
)
596 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
597 # provide the "count" return value
600 ret
= nbt
._bt
_python
_field
_listcaller
(self
._e
, scope_ptr
)
602 if isinstance(ret
, list):
603 list_ptr
, count
= ret
605 for i
in range(count
):
606 definition_ptr
= nbt
._bt
_python
_field
_one
_from
_list
(list_ptr
, i
)
608 if definition_ptr
is not None:
609 definition
= _Definition(definition_ptr
, scope
)
610 fields
.append(definition
)
615 class FieldError(Exception):
617 Field error, raised when the value of a field cannot be accessed.
620 def __init__(self
, value
):
624 return repr(self
.value
)
627 class EventDeclaration
:
629 An event declaration contains the properties of a class of events,
630 that is, the common properties and fields layout of all the actual
631 recorded events associated with this declaration.
633 This class is not meant to be instantiated by the user. It is
634 returned by :attr:`TraceHandle.events`.
637 MAX_UINT64
= 0xFFFFFFFFFFFFFFFF
640 raise NotImplementedError("EventDeclaration cannot be instantiated")
645 Event name, or ``None`` on error.
648 return nbt
._bt
_ctf
_get
_decl
_event
_name
(self
._ed
)
653 Event numeric ID, or -1 on error.
656 id = nbt
._bt
_ctf
_get
_decl
_event
_id
(self
._ed
)
658 if id == self
.MAX_UINT64
:
666 Generates all the field declarations of this event, going
667 through each scope in the following order:
669 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`)
670 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`)
671 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`)
672 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`)
673 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`)
674 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`)
676 All the generated field declarations inherit
677 :class:`FieldDeclaration`, and are among:
679 * :class:`IntegerFieldDeclaration`
680 * :class:`FloatFieldDeclaration`
681 * :class:`EnumerationFieldDeclaration`
682 * :class:`StringFieldDeclaration`
683 * :class:`ArrayFieldDeclaration`
684 * :class:`SequenceFieldDeclaration`
685 * :class:`StructureFieldDeclaration`
686 * :class:`VariantFieldDeclaration`
689 for scope
in _scopes
:
690 for declaration
in self
.fields_scope(scope
):
693 def fields_scope(self
, scope
):
695 Generates all the field declarations of the event's scope
698 *scope* must be one of :class:`babeltrace.common.CTFScope` constants.
700 All the generated field declarations inherit
701 :class:`FieldDeclaration`, and are among:
703 * :class:`IntegerFieldDeclaration`
704 * :class:`FloatFieldDeclaration`
705 * :class:`EnumerationFieldDeclaration`
706 * :class:`StringFieldDeclaration`
707 * :class:`ArrayFieldDeclaration`
708 * :class:`SequenceFieldDeclaration`
709 * :class:`StructureFieldDeclaration`
710 * :class:`VariantFieldDeclaration`
712 ret
= nbt
._by
_python
_field
_decl
_listcaller
(self
._ed
, scope
)
714 if not isinstance(ret
, list):
717 list_ptr
, count
= ret
719 for i
in range(count
):
720 field_decl_ptr
= nbt
._bt
_python
_field
_decl
_one
_from
_list
(list_ptr
, i
)
722 if field_decl_ptr
is not None:
723 decl_ptr
= nbt
._bt
_ctf
_get
_decl
_from
_field
_decl
(field_decl_ptr
)
724 name
= nbt
._bt
_ctf
_get
_decl
_field
_name
(field_decl_ptr
)
725 field_declaration
= _create_field_declaration(decl_ptr
, name
,
727 yield field_declaration
730 class FieldDeclaration
:
732 Base class for concrete field declarations.
734 This class is not meant to be instantiated by the user.
738 raise NotImplementedError("FieldDeclaration cannot be instantiated")
741 return "({0}) {1} {2}".format(common
.CTFScope
.scope_name(self
.scope
),
742 common
.CTFTypeId
.type_name(self
.type),
748 Field name, or ``None`` on error.
756 Field type (one of :class:`babeltrace.common.CTFTypeId`
760 return nbt
._bt
_ctf
_field
_type
(self
._fd
)
765 Field scope (one of:class:`babeltrace.common.CTFScope`
772 class IntegerFieldDeclaration(FieldDeclaration
):
774 Integer field declaration.
778 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
781 def signedness(self
):
783 0 if this integer is unsigned, 1 if signed, or -1 on error.
786 return nbt
._bt
_ctf
_get
_int
_signedness
(self
._fd
)
791 Integer base (:class:`int`), or a negative value on error.
794 return nbt
._bt
_ctf
_get
_int
_base
(self
._fd
)
797 def byte_order(self
):
799 Integer byte order (one of
800 :class:`babeltrace.common.ByteOrder` constants).
803 ret
= nbt
._bt
_ctf
_get
_int
_byte
_order
(self
._fd
)
806 return common
.ByteOrder
.BYTE_ORDER_LITTLE_ENDIAN
808 return common
.ByteOrder
.BYTE_ORDER_BIG_ENDIAN
810 return common
.ByteOrder
.BYTE_ORDER_UNKNOWN
815 Integer size in bits, or a negative value on error.
817 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
826 Integer encoding (one of
827 :class:`babeltrace.common.CTFStringEncoding` constants).
830 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
833 class EnumerationFieldDeclaration(FieldDeclaration
):
835 Enumeration field declaration.
839 As of this version, this class is missing some properties.
843 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
846 class ArrayFieldDeclaration(FieldDeclaration
):
848 Static array field declaration.
852 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
857 Fixed length of this static array (number of contained
858 elements), or a negative value on error.
861 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
864 def element_declaration(self
):
866 Field declaration of the underlying element.
869 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
871 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
874 class SequenceFieldDeclaration(FieldDeclaration
):
876 Sequence (dynamic array) field declaration.
880 As of this version, this class is missing some properties.
884 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
887 def element_declaration(self
):
889 Field declaration of the underlying element.
892 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
894 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
897 class FloatFieldDeclaration(FieldDeclaration
):
899 Floating point number field declaration.
903 As of this version, this class is missing some properties.
907 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
910 class StructureFieldDeclaration(FieldDeclaration
):
912 Structure (ordered map of field names to field declarations) field
917 As of this version, this class is missing some properties.
921 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
924 class StringFieldDeclaration(FieldDeclaration
):
926 String (NULL-terminated array of bytes) field declaration.
930 As of this version, this class is missing some properties.
934 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
937 class VariantFieldDeclaration(FieldDeclaration
):
939 Variant (dynamic selection between different types) field declaration.
943 As of this version, this class is missing some properties.
947 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
952 Return the last error code encountered while
953 accessing a field and reset the error flag.
954 Return 0 if no error, a negative value otherwise.
957 return nbt
._bt
_ctf
_field
_get
_error
()
960 def _create_field_declaration(declaration_ptr
, name
, scope
):
962 Private field declaration factory.
965 if declaration_ptr
is None:
966 raise ValueError("declaration_ptr must be valid")
967 if scope
not in _scopes
:
968 raise ValueError("Invalid scope provided")
970 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
973 if type == common
.CTFTypeId
.INTEGER
:
974 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
975 elif type == common
.CTFTypeId
.ENUM
:
976 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
977 elif type == common
.CTFTypeId
.ARRAY
:
978 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
979 elif type == common
.CTFTypeId
.SEQUENCE
:
980 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
981 elif type == common
.CTFTypeId
.FLOAT
:
982 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
983 elif type == common
.CTFTypeId
.STRUCT
:
984 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
985 elif type == common
.CTFTypeId
.STRING
:
986 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
987 elif type == common
.CTFTypeId
.VARIANT
:
988 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
992 declaration
._fd
= declaration_ptr
993 declaration
._s
= scope
994 declaration
._name
= name
1000 def __init__(self
, definition_ptr
, scope
):
1001 self
._d
= definition_ptr
1004 if scope
not in _scopes
:
1005 ValueError("Invalid scope provided")
1009 """Return the name of a field or None on error."""
1011 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1015 """Return the type of a field or -1 if unknown."""
1017 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1020 def declaration(self
):
1021 """Return the associated Definition object."""
1023 return _create_field_declaration(
1024 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1026 def _get_enum_str(self
):
1028 Return the string matching the current enumeration.
1029 Return None on error.
1032 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1034 def _get_array_element_at(self
, index
):
1036 Return the array's element at position index.
1037 Return None on error
1040 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1042 if array_ptr
is None:
1045 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1047 if definition_ptr
is None:
1050 return _Definition(definition_ptr
, self
.scope
)
1052 def _get_sequence_len(self
):
1054 Return the len of a sequence or a negative
1058 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1060 return nbt
._bt
_sequence
_len
(seq
)
1062 def _get_sequence_element_at(self
, index
):
1064 Return the sequence's element at position index,
1065 otherwise return None
1068 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1071 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1073 if definition_ptr
is not None:
1074 return _Definition(definition_ptr
, self
.scope
)
1076 def _get_uint64(self
):
1078 Return the value associated with the field.
1079 If the field does not exist or is not of the type requested,
1080 the value returned is undefined. To check if an error occured,
1081 use the field_error() function after accessing a field.
1084 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1086 def _get_int64(self
):
1088 Return the value associated with the field.
1089 If the field does not exist or is not of the type requested,
1090 the value returned is undefined. To check if an error occured,
1091 use the field_error() function after accessing a field.
1094 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1096 def _get_char_array(self
):
1098 Return the value associated with the field.
1099 If the field does not exist or is not of the type requested,
1100 the value returned is undefined. To check if an error occurred,
1101 use the field_error() function after accessing a field.
1104 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1108 Return the value associated with the field.
1109 If the field does not exist or is not of the type requested,
1110 the value returned is undefined. To check if an error occurred,
1111 use the field_error() function after accessing a field.
1114 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1116 def _get_float(self
):
1118 Return the value associated with the field.
1119 If the field does not exist or is not of the type requested,
1120 the value returned is undefined. To check if an error occurred,
1121 use the field_error() function after accessing a field.
1124 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1126 def _get_variant(self
):
1128 Return the variant's selected field.
1129 If the field does not exist or is not of the type requested,
1130 the value returned is undefined. To check if an error occurred,
1131 use the field_error() function after accessing a field.
1134 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1136 def _get_struct_field_count(self
):
1138 Return the number of fields contained in the structure.
1139 If the field does not exist or is not of the type requested,
1140 the value returned is undefined.
1143 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1145 def _get_struct_field_at(self
, i
):
1147 Return the structure's field at position i.
1148 If the field does not exist or is not of the type requested,
1149 the value returned is undefined. To check if an error occurred,
1150 use the field_error() function after accessing a field.
1153 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1158 Return the value associated with the field according to its type.
1159 Return None on error.
1165 if id == common
.CTFTypeId
.STRING
:
1166 value
= self
._get
_str
()
1167 elif id == common
.CTFTypeId
.ARRAY
:
1168 element_decl
= self
.declaration
.element_declaration
1170 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1171 and element_decl
.length
== 8)
1172 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1173 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1177 for i
in range(self
.declaration
.length
):
1178 element
= self
._get
_array
_element
_at
(i
)
1179 value
.append(element
.value
)
1180 elif id == common
.CTFTypeId
.INTEGER
:
1181 if self
.declaration
.signedness
== 0:
1182 value
= self
._get
_uint
64()
1184 value
= self
._get
_int
64()
1185 elif id == common
.CTFTypeId
.ENUM
:
1186 value
= self
._get
_enum
_str
()
1187 elif id == common
.CTFTypeId
.SEQUENCE
:
1188 element_decl
= self
.declaration
.element_declaration
1190 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1191 and element_decl
.length
== 8)
1192 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1193 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1195 seq_len
= self
._get
_sequence
_len
()
1198 for i
in range(seq_len
):
1199 evDef
= self
._get
_sequence
_element
_at
(i
)
1200 value
.append(evDef
.value
)
1201 elif id == common
.CTFTypeId
.FLOAT
:
1202 value
= self
._get
_float
()
1203 elif id == common
.CTFTypeId
.VARIANT
:
1204 variant
= _Definition
.__new
__(_Definition
)
1205 variant
._d
= self
._get
_variant
()
1206 value
= variant
.value
1207 elif id == common
.CTFTypeId
.STRUCT
:
1210 for i
in range(self
._get
_struct
_field
_count
()):
1211 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1212 value
[member
.name
] = member
.value
1216 "Error occurred while accessing field {} of type {}".format(
1218 common
.CTFTypeId
.type_name(id)))
1224 """Return the scope of a field or None on error."""