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.
818 return nbt
._bt
_ctf
_get
_int
_len
(self
._fd
)
823 Integer encoding (one of
824 :class:`babeltrace.common.CTFStringEncoding` constants).
827 return nbt
._bt
_ctf
_get
_encoding
(self
._fd
)
830 class EnumerationFieldDeclaration(FieldDeclaration
):
832 Enumeration field declaration.
836 As of this version, this class is missing some properties.
840 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
843 class ArrayFieldDeclaration(FieldDeclaration
):
845 Static array field declaration.
849 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
854 Fixed length of this static array (number of contained
855 elements), or a negative value on error.
858 return nbt
._bt
_ctf
_get
_array
_len
(self
._fd
)
861 def element_declaration(self
):
863 Field declaration of the underlying element.
866 field_decl_ptr
= nbt
._bt
_python
_get
_array
_element
_declaration
(self
._fd
)
868 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
871 class SequenceFieldDeclaration(FieldDeclaration
):
873 Sequence (dynamic array) field declaration.
877 As of this version, this class is missing some properties.
881 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
884 def element_declaration(self
):
886 Field declaration of the underlying element.
889 field_decl_ptr
= nbt
._bt
_python
_get
_sequence
_element
_declaration
(self
._fd
)
891 return _create_field_declaration(field_decl_ptr
, "", self
.scope
)
894 class FloatFieldDeclaration(FieldDeclaration
):
896 Floating point number field declaration.
900 As of this version, this class is missing some properties.
904 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
907 class StructureFieldDeclaration(FieldDeclaration
):
909 Structure (ordered map of field names to field declarations) field
914 As of this version, this class is missing some properties.
918 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
921 class StringFieldDeclaration(FieldDeclaration
):
923 String (NULL-terminated array of bytes) field declaration.
927 As of this version, this class is missing some properties.
931 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
934 class VariantFieldDeclaration(FieldDeclaration
):
936 Variant (dynamic selection between different types) field declaration.
940 As of this version, this class is missing some properties.
944 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
949 Return the last error code encountered while
950 accessing a field and reset the error flag.
951 Return 0 if no error, a negative value otherwise.
954 return nbt
._bt
_ctf
_field
_get
_error
()
957 def _create_field_declaration(declaration_ptr
, name
, scope
):
959 Private field declaration factory.
962 if declaration_ptr
is None:
963 raise ValueError("declaration_ptr must be valid")
964 if scope
not in _scopes
:
965 raise ValueError("Invalid scope provided")
967 type = nbt
._bt
_ctf
_field
_type
(declaration_ptr
)
970 if type == common
.CTFTypeId
.INTEGER
:
971 declaration
= IntegerFieldDeclaration
.__new
__(IntegerFieldDeclaration
)
972 elif type == common
.CTFTypeId
.ENUM
:
973 declaration
= EnumerationFieldDeclaration
.__new
__(EnumerationFieldDeclaration
)
974 elif type == common
.CTFTypeId
.ARRAY
:
975 declaration
= ArrayFieldDeclaration
.__new
__(ArrayFieldDeclaration
)
976 elif type == common
.CTFTypeId
.SEQUENCE
:
977 declaration
= SequenceFieldDeclaration
.__new
__(SequenceFieldDeclaration
)
978 elif type == common
.CTFTypeId
.FLOAT
:
979 declaration
= FloatFieldDeclaration
.__new
__(FloatFieldDeclaration
)
980 elif type == common
.CTFTypeId
.STRUCT
:
981 declaration
= StructureFieldDeclaration
.__new
__(StructureFieldDeclaration
)
982 elif type == common
.CTFTypeId
.STRING
:
983 declaration
= StringFieldDeclaration
.__new
__(StringFieldDeclaration
)
984 elif type == common
.CTFTypeId
.VARIANT
:
985 declaration
= VariantFieldDeclaration
.__new
__(VariantFieldDeclaration
)
989 declaration
._fd
= declaration_ptr
990 declaration
._s
= scope
991 declaration
._name
= name
997 def __init__(self
, definition_ptr
, scope
):
998 self
._d
= definition_ptr
1001 if scope
not in _scopes
:
1002 ValueError("Invalid scope provided")
1006 """Return the name of a field or None on error."""
1008 return nbt
._bt
_ctf
_field
_name
(self
._d
)
1012 """Return the type of a field or -1 if unknown."""
1014 return nbt
._bt
_ctf
_field
_type
(nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
))
1017 def declaration(self
):
1018 """Return the associated Definition object."""
1020 return _create_field_declaration(
1021 nbt
._bt
_ctf
_get
_decl
_from
_def
(self
._d
), self
.name
, self
.scope
)
1023 def _get_enum_str(self
):
1025 Return the string matching the current enumeration.
1026 Return None on error.
1029 return nbt
._bt
_ctf
_get
_enum
_str
(self
._d
)
1031 def _get_array_element_at(self
, index
):
1033 Return the array's element at position index.
1034 Return None on error
1037 array_ptr
= nbt
._bt
_python
_get
_array
_from
_def
(self
._d
)
1039 if array_ptr
is None:
1042 definition_ptr
= nbt
._bt
_array
_index
(array_ptr
, index
)
1044 if definition_ptr
is None:
1047 return _Definition(definition_ptr
, self
.scope
)
1049 def _get_sequence_len(self
):
1051 Return the len of a sequence or a negative
1055 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1057 return nbt
._bt
_sequence
_len
(seq
)
1059 def _get_sequence_element_at(self
, index
):
1061 Return the sequence's element at position index,
1062 otherwise return None
1065 seq
= nbt
._bt
_python
_get
_sequence
_from
_def
(self
._d
)
1068 definition_ptr
= nbt
._bt
_sequence
_index
(seq
, index
)
1070 if definition_ptr
is not None:
1071 return _Definition(definition_ptr
, self
.scope
)
1073 def _get_uint64(self
):
1075 Return the value associated with the field.
1076 If the field does not exist or is not of the type requested,
1077 the value returned is undefined. To check if an error occured,
1078 use the field_error() function after accessing a field.
1081 return nbt
._bt
_ctf
_get
_uint
64(self
._d
)
1083 def _get_int64(self
):
1085 Return the value associated with the field.
1086 If the field does not exist or is not of the type requested,
1087 the value returned is undefined. To check if an error occured,
1088 use the field_error() function after accessing a field.
1091 return nbt
._bt
_ctf
_get
_int
64(self
._d
)
1093 def _get_char_array(self
):
1095 Return the value associated with the field.
1096 If the field does not exist or is not of the type requested,
1097 the value returned is undefined. To check if an error occurred,
1098 use the field_error() function after accessing a field.
1101 return nbt
._bt
_ctf
_get
_char
_array
(self
._d
)
1105 Return the value associated with the field.
1106 If the field does not exist or is not of the type requested,
1107 the value returned is undefined. To check if an error occurred,
1108 use the field_error() function after accessing a field.
1111 return nbt
._bt
_ctf
_get
_string
(self
._d
)
1113 def _get_float(self
):
1115 Return the value associated with the field.
1116 If the field does not exist or is not of the type requested,
1117 the value returned is undefined. To check if an error occurred,
1118 use the field_error() function after accessing a field.
1121 return nbt
._bt
_ctf
_get
_float
(self
._d
)
1123 def _get_variant(self
):
1125 Return the variant's selected field.
1126 If the field does not exist or is not of the type requested,
1127 the value returned is undefined. To check if an error occurred,
1128 use the field_error() function after accessing a field.
1131 return nbt
._bt
_ctf
_get
_variant
(self
._d
)
1133 def _get_struct_field_count(self
):
1135 Return the number of fields contained in the structure.
1136 If the field does not exist or is not of the type requested,
1137 the value returned is undefined.
1140 return nbt
._bt
_ctf
_get
_struct
_field
_count
(self
._d
)
1142 def _get_struct_field_at(self
, i
):
1144 Return the structure's field at position i.
1145 If the field does not exist or is not of the type requested,
1146 the value returned is undefined. To check if an error occurred,
1147 use the field_error() function after accessing a field.
1150 return nbt
._bt
_ctf
_get
_struct
_field
_index
(self
._d
, i
)
1155 Return the value associated with the field according to its type.
1156 Return None on error.
1162 if id == common
.CTFTypeId
.STRING
:
1163 value
= self
._get
_str
()
1164 elif id == common
.CTFTypeId
.ARRAY
:
1165 element_decl
= self
.declaration
.element_declaration
1167 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1168 and element_decl
.length
== 8)
1169 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1170 value
= nbt
._bt
_python
_get
_array
_string
(self
._d
)
1174 for i
in range(self
.declaration
.length
):
1175 element
= self
._get
_array
_element
_at
(i
)
1176 value
.append(element
.value
)
1177 elif id == common
.CTFTypeId
.INTEGER
:
1178 if self
.declaration
.signedness
== 0:
1179 value
= self
._get
_uint
64()
1181 value
= self
._get
_int
64()
1182 elif id == common
.CTFTypeId
.ENUM
:
1183 value
= self
._get
_enum
_str
()
1184 elif id == common
.CTFTypeId
.SEQUENCE
:
1185 element_decl
= self
.declaration
.element_declaration
1187 if ((element_decl
.type == common
.CTFTypeId
.INTEGER
1188 and element_decl
.length
== 8)
1189 and (element_decl
.encoding
== common
.CTFStringEncoding
.ASCII
or element_decl
.encoding
== common
.CTFStringEncoding
.UTF8
)):
1190 value
= nbt
._bt
_python
_get
_sequence
_string
(self
._d
)
1192 seq_len
= self
._get
_sequence
_len
()
1195 for i
in range(seq_len
):
1196 evDef
= self
._get
_sequence
_element
_at
(i
)
1197 value
.append(evDef
.value
)
1198 elif id == common
.CTFTypeId
.FLOAT
:
1199 value
= self
._get
_float
()
1200 elif id == common
.CTFTypeId
.VARIANT
:
1201 variant
= _Definition
.__new
__(_Definition
)
1202 variant
._d
= self
._get
_variant
()
1203 value
= variant
.value
1204 elif id == common
.CTFTypeId
.STRUCT
:
1207 for i
in range(self
._get
_struct
_field
_count
()):
1208 member
= _Definition(self
._get
_struct
_field
_at
(i
), self
.scope
)
1209 value
[member
.name
] = member
.value
1213 "Error occurred while accessing field {} of type {}".format(
1215 common
.CTFTypeId
.type_name(id)))
1221 """Return the scope of a field or None on error."""