From: Jérémie Galarneau Date: Thu, 21 Nov 2013 01:35:51 +0000 (-0500) Subject: Python-bindings: Refactor the Event class X-Git-Tag: v1.2.0-rc1~49 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=78d714e8ac623952af0eabe791ac3ee38b5876a0 Python-bindings: Refactor the Event class The Event class now implements the collections.Mapping interface and provides properties where appropriate. The Definition class is now private and renamed to _Definition. The examples are modified to take these changes into account. Signed-off-by: Jérémie Galarneau --- diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index ef2474ad..1dec941f 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -259,7 +259,7 @@ class TraceCollection: if ev_ptr is None: break - ev = CTFReader.Event.__new__(CTFReader.Event) + ev = Event.__new__(Event) ev._e = ev_ptr try: yield ev @@ -570,498 +570,507 @@ class CTFTypeId: break return name -class CTFReader: - class scope: - TRACE_PACKET_HEADER = 0 - STREAM_PACKET_CONTEXT = 1 - STREAM_EVENT_HEADER = 2 - STREAM_EVENT_CONTEXT = 3 - EVENT_CONTEXT = 4 - EVENT_FIELDS = 5 - class Event(object): +class scope: + TRACE_PACKET_HEADER = 0 + STREAM_PACKET_CONTEXT = 1 + STREAM_EVENT_HEADER = 2 + STREAM_EVENT_CONTEXT = 3 + EVENT_CONTEXT = 4 + EVENT_FIELDS = 5 + +import collections +class Event(collections.Mapping): + """ + This class represents an event from the trace. + It is obtained using the TraceCollection generator functions. + Do not instantiate. + """ + i = scope.EVENT_FIELDS + _scopes = [scope.EVENT_FIELDS, scope.EVENT_CONTEXT, scope.STREAM_EVENT_CONTEXT, + scope.STREAM_EVENT_HEADER, scope.STREAM_PACKET_CONTEXT, scope.TRACE_PACKET_HEADER] + + def __init__(self): + raise NotImplementedError("Event cannot be instantiated") + + @property + def name(self): + """Return the name of the event or None on error.""" + return _bt_ctf_event_name(self._e) + + @property + def cycles(self): """ - This class represents an event from the trace. - It is obtained using the TraceCollection generator functions. - Do not instantiate. + Return the timestamp of the event as written in + the packet (in cycles) or -1ULL on error. """ + return _bt_ctf_get_cycles(self._e) - def __init__(self): - raise NotImplementedError("CTFReader.Event cannot be instantiated") - - def get_top_level_scope(self, scope): - """ - Return a definition of the top-level scope - Top-level scopes are defined in CTFReader.scope. - In order to get a field or a field list, the user needs to pass a - scope as argument, this scope can be a top-level scope or a scope - relative to an arbitrary field. This function provides the mapping - between the scope and the actual definition of top-level scopes. - On error return None. - """ - evDef = CTFReader.Definition.__new__(CTFReader.Definition) - evDef._d = _bt_ctf_get_top_level_scope(self._e, scope) - if evDef._d is None: - return None - return evDef - - def get_name(self): - """Return the name of the event or None on error.""" - return _bt_ctf_event_name(self._e) - - def get_cycles(self): - """ - Return the timestamp of the event as written in - the packet (in cycles) or -1ULL on error. - """ - return _bt_ctf_get_cycles(self._e) - - def get_timestamp(self): - """ - Return the timestamp of the event offsetted with the - system clock source or -1ULL on error. - """ - return _bt_ctf_get_timestamp(self._e) - - def get_field_with_scope(self, scope, field): - """ - Return the definition of a specific field. - Return None on error. - """ - evDef = CTFReader.Definition.__new__(CTFReader.Definition) - try: - evDef._d = _bt_ctf_get_field(self._e, scope._d, field) - except AttributeError: - raise TypeError("in get_field, argument 2 must be a " - "Definition (scope) instance") - if evDef._d is None: - return None - evDef._s = scope - return evDef - - def get_field(self, field): - """ - Return the definition of fields by a name - Return None on error - """ - eventScope = self.get_top_level_scope(CTFReader.scope.EVENT_FIELDS) - streamScope = self.get_top_level_scope(CTFReader.scope.STREAM_EVENT_CONTEXT) - fields_by_name = [] - - if eventScope is not None: - evDef = self.get_field_with_scope(eventScope, field) - if evDef is not None: - fields_by_name.append(evDef) - - if streamScope is not None: - evDef = self.get_field_with_scope(streamScope, field) - if evDef is not None: - fields_by_name.append(evDef); - - if not fields_by_name: - return None - return fields_by_name - - def get_field_list_with_scope(self, scope): - """ - Return a list of Definitions associated with the scope - Return None on error. - """ - try: - field_lc, count = _bt_python_field_listcaller(self._e, scope._d) - except AttributeError: - raise TypeError("in get_field_list, argument 2 must be a " - "Definition (scope) instance") - - if field_lc is None: - return None - - def_list = [] - for i in range(count): - tmp = CTFReader.Definition.__new__(CTFReader.Definition) - tmp._d = _bt_python_field_one_from_list(field_lc, i) - tmp._s = scope - def_list.append(tmp) - - return def_list - - def get_field_list(self): - """Return a list of Definitions or None on error.""" - eventScope = self.get_top_level_scope(CTFReader.scope.EVENT_FIELDS) - streamScope = self.get_top_level_scope(CTFReader.scope.STREAM_EVENT_CONTEXT) - - def_list = [] - if eventScope is not None: - event_field_list = self.get_field_list_with_scope(eventScope) - if event_field_list is not None: - def_list = event_field_list - - if streamScope is not None: - event_field_list = self.get_field_list_with_scope(streamScope) - if event_field_list is not None: - def_list.extend(event_field_list) - - if not def_list: - return None - return def_list - - def get_index(self, field, index): - """ - If the field is an array or a sequence, return the element - at position index, otherwise return None - """ - evDef = CTFReader.Definition.__new__(CTFReader.Definition) - try: - evDef._d = _bt_ctf_get_index(self._e, field._d, index) - except AttributeError: - raise TypeError("in get_index, argument 2 must be a " - "Definition (field) instance") - - if evDef._d is None: - return None - return evDef - - def get_handle(self): - """ - Get the TraceHandle associated with this event - Return None on error - """ - ret = _bt_ctf_event_get_handle_id(self._e) - if ret < 0: - return None - - th = TraceHandle.__new__(TraceHandle) - th._id = ret - th._trace_collection = self.get_trace_collection() - return th - - def get_trace_collection(self): - """ - Get the TraceCollection associated with this event. - Return None on error. - """ - trace_collection = TraceCollection() - trace_collection._tc = _bt_ctf_event_get_context(self._e); - if trace_collection._tc is None: - return None - else: - return trace_collection + @property + def timestamp(self): + """ + Return the timestamp of the event offset with the + system clock source or -1ULL on error. + """ + return _bt_ctf_get_timestamp(self._e) - class FieldError(Exception): - def __init__(self, value): - self.value = value + def field_with_scope(self, field_name, scope): + """ + Get field_name's value in scope. + None is returned if no field matches field_name. + """ + if not scope in self._scopes: + raise ValueError("Invalid scope provided") + field = self._field_with_scope(field_name, scope) + if field is not None: + return field.value + return None - def __str__(self): - return repr(self.value) + def field_list_with_scope(self, scope): + """Return a list of field names in scope.""" + if not scope in self._scopes: + raise ValueError("Invalid scope provided") + field_names = [] + for field in self._field_list_with_scope(scope): + field_names.append(field.name) + return field_names - class Definition(object): - """Definition class. Do not instantiate.""" + @property + def handle(self): + """ + Get the TraceHandle associated with this event + Return None on error + """ + ret = _bt_ctf_event_get_handle_id(self._e) + if ret < 0: + return None - def __init__(self): - raise NotImplementedError("CTFReader.Definition cannot be instantiated") - - def __repr__(self): - return "Babeltrace Definition: name('{0}'), type({1})".format( - self.field_name(), self.field_type()) - - def field_name(self): - """Return the name of a field or None on error.""" - return _bt_ctf_field_name(self._d) - - def field_type(self): - """Return the type of a field or -1 if unknown.""" - return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d)) - - def get_int_signedness(self): - """ - Return the signedness of an integer: - 0 if unsigned; 1 if signed; -1 on error. - """ - return _bt_ctf_get_int_signedness(_bt_ctf_get_decl_from_def(self._d)) - - def get_int_base(self): - """Return the base of an int or a negative value on error.""" - return _bt_ctf_get_int_base(_bt_ctf_get_decl_from_def(self._d)) - - def get_int_byte_order(self): - """ - Return the byte order of an int or a negative - value on error. - """ - return _bt_ctf_get_int_byte_order(_bt_ctf_get_decl_from_def(self._d)) - - def get_int_len(self): - """ - Return the size, in bits, of an int or a negative - value on error. - """ - return _bt_ctf_get_int_len(_bt_ctf_get_decl_from_def(self._d)) - - def get_enum_str(self): - """ - Return the string matching the current enumeration. - Return None on error. - """ - return _bt_ctf_get_enum_str(self._d) - - def get_encoding(self): - """ - Return the encoding of an int or a string. - Return a negative value on error. - """ - return _bt_ctf_get_encoding(_bt_ctf_get_decl_from_def(self._d)) - - def get_array_len(self): - """ - Return the len of an array or a negative - value on error. - """ - return _bt_ctf_get_array_len(_bt_ctf_get_decl_from_def(self._d)) - - def get_array_element_at(self, index): - """ - Return the array's element at position index. - Return None on error - """ - array = _bt_python_get_array_from_def(self._d) - if array is None: - return None - - element = CTFReader.Definition.__new__(CTFReader.Definition) - element._d = _bt_array_index(array, index) - if element._d is None: - return None - return element - - def get_sequence_len(self): - """ - Return the len of a sequence or a negative - value on error. - """ - seq = _bt_python_get_sequence_from_def(self._d) - return _bt_sequence_len(seq) - - def get_sequence_element_at(self, index): - """ - Return the sequence's element at position index, - otherwise return None - """ - seq = _bt_python_get_sequence_from_def(self._d) - if seq is not None: - element = CTFReader.Definition.__new__(CTFReader.Definition) - element._d = _bt_sequence_index(seq, index) - if element._d is not None: - return element + th = TraceHandle.__new__(TraceHandle) + th._id = ret + th._trace_collection = self.get_trace_collection() + return th + + @property + def trace_collection(self): + """ + Get the TraceCollection associated with this event. + Return None on error. + """ + trace_collection = TraceCollection() + trace_collection._tc = _bt_ctf_event_get_context(self._e); + if trace_collection._tc is None: + return None + else: + return trace_collection + + def __getitem__(self, field_name): + """ + Get field_name's value. If the field_name exists in multiple + scopes, the first field found is returned. The scopes are searched + in the following order: + 1) EVENT_FIELDS + 2) EVENT_CONTEXT + 3) STREAM_EVENT_CONTEXT + 4) STREAM_EVENT_HEADER + 5) STREAM_PACKET_CONTEXT + 6) TRACE_PACKET_HEADER + None is returned if no field matches field_name. + + Use field_with_scope() to explicitly access fields in a given + scope. + """ + field = self._field(field_name) + if field is not None: + return field.value + raise KeyError(field_name) + + def __iter__(self): + for key in self.keys(): + yield key + + def __len__(self): + count = 0 + for scope in self._scopes: + scope_ptr = _bt_ctf_get_top_level_scope(self._e, scope) + ret = _bt_python_field_listcaller(self._e, scope_ptr) + if isinstance(ret, list): + count += ret[1] + return count + + def __contains__(self, field_name): + return self._field(field_name) is not None + + def keys(self): + """Return a list of field names.""" + field_names = set() + for scope in self._scopes: + for name in self.field_list_with_scope(scope): + field_names.add(name) + return list(field_names) + + def get(self, field_name, default = None): + field = self._field(field_name) + if field is None: + return default + return field.value + + def items(self): + for field in self.keys(): + yield (field, self[field]) + + def _field_with_scope(self, field_name, scope): + scope_ptr = _bt_ctf_get_top_level_scope(self._e, scope) + if scope_ptr is None: return None - def get_uint64(self): - """ - Return the value associated with the field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_uint64(self._d) - - def get_int64(self): - """ - Return the value associated with the field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_int64(self._d) - - def get_char_array(self): - """ - Return the value associated with the field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_char_array(self._d) - - def get_str(self): - """ - Return the value associated with the field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_string(self._d) - - def get_float(self): - """ - Return the value associated with the field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_float(self._d) - - def get_variant(self): - """ - Return the variant's selected field. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_variant(self._d) - - def get_struct_field_count(self): - """ - Return the number of fields contained in the structure. - If the field does not exist or is not of the type requested, - the value returned is undefined. - """ - return _bt_ctf_get_struct_field_count(self._d) - - def get_struct_field_at(self, i): - """ - Return the structure's field at position i. - If the field does not exist or is not of the type requested, - the value returned is undefined. To check if an error occured, - use the CTFReader.field_error() function after accessing a field. - """ - return _bt_ctf_get_struct_field_index(self._d, i) - - def get_value(self): - """ - Return the value associated with the field according to its type. - Return None on error. - """ - id = self.field_type() - value = None - if id == CTFTypeId.STRING: - value = self.get_str() - elif id == CTFTypeId.ARRAY: - value = [] - for i in range(self.get_array_len()): - element = self.get_array_element_at(i) - value.append(element.get_value()) - elif id == CTFTypeId.INTEGER: - if self.get_int_signedness() == 0: - value = self.get_uint64() - else: - value = self.get_int64() - elif id == CTFTypeId.ENUM: - value = self.get_enum_str() - elif id == CTFTypeId.SEQUENCE: - seq_len = self.get_sequence_len() - value = [] - for i in range(seq_len): - evDef = self.get_sequence_element_at(i) - value.append(evDef.get_value()) - elif id == CTFTypeId.FLOAT: - value = self.get_float() - elif id == CTFTypeId.VARIANT: - variant = CTFReader.Definition.__new__(CTFReader.Definition) - variant._d = self.get_variant(); - value = variant.get_value() - elif id == CTFTypeId.STRUCT: - value = {} - for i in range(self.get_struct_field_count()): - member = CTFReader.Definition.__new__(CTFReader.Definition) - member._d = self.get_struct_field_at(i); - value[member.field_name()] = member.get_value() - - if CTFReader.field_error(): - raise CTFReader.FieldError("Error occured while accessing field {} of type {}".format(self.field_name(), CTFTypeId.get_type_name(self.field_type()))) - return value - - def get_scope(self): - """Return the scope of a field or None on error.""" - return self._s - - class EventDecl(object): - """Event declaration class. Do not instantiate.""" + definition_ptr = _bt_ctf_get_field(self._e, scope_ptr, field_name) + if definition_ptr is None: + return None - def __init__(self): - raise NotImplementedError("CTFReader.EventDecl cannot be instantiated") + field = _Definition(definition_ptr, scope) + return field - def __repr__(self): - return "Babeltrace EventDecl: name {0}".format(self.get_name()) + def _field(self, field_name): + field = None + for scope in self._scopes: + field = self._field_with_scope(field_name, scope) + if field is not None: + break + return field + + def _field_list_with_scope(self, scope): + fields = [] + scope_ptr = _bt_ctf_get_top_level_scope(self._e, scope) + + # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only + # provide the "count" return value + count = 0 + list_ptr = None + ret = _bt_python_field_listcaller(self._e, scope_ptr) + if isinstance(ret, list): + list_ptr, count = ret - def get_name(self): - """Return the name of the event or None on error""" - return _bt_ctf_get_decl_event_name(self._d) + for i in range(count): + definition_ptr = _bt_python_field_one_from_list(list_ptr, i) + if definition_ptr is not None: + definition = _Definition(definition_ptr, scope) + fields.append(definition) + return fields - def get_decl_fields(self, scope): - """ - Return a list of CTFReader.FieldDecl - Return None on error. - """ - ptr_list = _by_python_field_decl_listcaller(self._d, scope) +class FieldError(Exception): + def __init__(self, value): + self.value = value - if ptr_list is None: - return None + def __str__(self): + return repr(self.value) - decl_list = [] - i = 0 - while True: - tmp = CTFReader.FieldDecl.__new__(CTFReader.FieldDecl) - tmp._d = _bt_python_field_decl_one_from_list( - ptr_list, i) +class EventDecl(object): + """Event declaration class. Do not instantiate.""" - if tmp._d is None: - #Last item of list is None - break + def __init__(self): + raise NotImplementedError("EventDecl cannot be instantiated") - decl_list.append(tmp) - i += 1 - return decl_list + def __repr__(self): + return "Babeltrace EventDecl: name {0}".format(self.get_name()) + def get_name(self): + """Return the name of the event or None on error""" + return _bt_ctf_get_decl_event_name(self._d) - class FieldDecl(object): - """Field declaration class. Do not instantiate.""" + def get_decl_fields(self, scope): + """ + Return a list of FieldDecl + Return None on error. + """ + ptr_list = _by_python_field_decl_listcaller(self._d, scope) - def __init__(self): - raise NotImplementedError("CTFReader.FieldDecl cannot be instantiated") + if ptr_list is None: + return None - def __repr__(self): - return "Babeltrace FieldDecl: name {0}".format(self.get_name()) + decl_list = [] + i = 0 + while True: + tmp = FieldDecl.__new__(FieldDecl) + tmp._d = _bt_python_field_decl_one_from_list( + ptr_list, i) - def get_name(self): - """Return the name of a FieldDecl or None on error""" - return _bt_ctf_get_decl_field_name(self._d) + if tmp._d is None: + #Last item of list is None + break + decl_list.append(tmp) + i += 1 + return decl_list - @staticmethod - def field_error(): + +class FieldDecl(object): + """Field declaration class. Do not instantiate.""" + + def __init__(self): + raise NotImplementedError("FieldDecl cannot be instantiated") + + def __repr__(self): + return "Babeltrace FieldDecl: name {0}".format(self.get_name()) + + def get_name(self): + """Return the name of a FieldDecl or None on error""" + return _bt_ctf_get_decl_field_name(self._d) + + +def field_error(): + """ + Return the last error code encountered while + accessing a field and reset the error flag. + Return 0 if no error, a negative value otherwise. + """ + return _bt_ctf_field_get_error() + +def get_event_decl_list(trace_handle, trace_collection): + """ + Return a list of EventDecl + Return None on error. + """ + try: + handle_id = trace_handle._id + except AttributeError: + raise TypeError("in get_event_decl_list, " + "argument 1 must be a TraceHandle instance") + try: + ptr_list, count = _bt_python_event_decl_listcaller(handle_id, trace_collection._tc) + except AttributeError: + raise TypeError("in get_event_decl_list, " + "argument 2 must be a TraceCollection instance") + + if ptr_list is None: + return None + + decl_list = [] + for i in range(count): + tmp = EventDecl.__new__(EventDecl) + tmp._d = _bt_python_decl_one_from_list(ptr_list, i) + decl_list.append(tmp) + + return decl_list + +class _Definition(object): + def __init__(self, definition_ptr, scope): + self._d = definition_ptr + self._s = scope + if not scope in Event._scopes: + ValueError("Invalid scope provided") + + def __repr__(self): + return "Babeltrace Definition: name('{0}'), type({1})".format(self.name, self.type) + + @property + def name(self): + """Return the name of a field or None on error.""" + return _bt_ctf_field_name(self._d) + + @property + def type(self): + """Return the type of a field or -1 if unknown.""" + return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d)) + + def get_int_signedness(self): """ - Return the last error code encountered while - accessing a field and reset the error flag. - Return 0 if no error, a negative value otherwise. + Return the signedness of an integer: + 0 if unsigned; 1 if signed; -1 on error. """ - return _bt_ctf_field_get_error() + return _bt_ctf_get_int_signedness(_bt_ctf_get_decl_from_def(self._d)) - @staticmethod - def get_event_decl_list(trace_handle, trace_collection): + def get_int_base(self): + """Return the base of an int or a negative value on error.""" + return _bt_ctf_get_int_base(_bt_ctf_get_decl_from_def(self._d)) + + def get_int_byte_order(self): + """ + Return the byte order of an int or a negative + value on error. + """ + return _bt_ctf_get_int_byte_order(_bt_ctf_get_decl_from_def(self._d)) + + def get_int_len(self): """ - Return a list of CTFReader.EventDecl + Return the size, in bits, of an int or a negative + value on error. + """ + return _bt_ctf_get_int_len(_bt_ctf_get_decl_from_def(self._d)) + + def get_enum_str(self): + """ + Return the string matching the current enumeration. Return None on error. """ - try: - handle_id = trace_handle._id - except AttributeError: - raise TypeError("in get_event_decl_list, " - "argument 1 must be a TraceHandle instance") - try: - ptr_list, count = _bt_python_event_decl_listcaller(handle_id, trace_collection._tc) - except AttributeError: - raise TypeError("in get_event_decl_list, " - "argument 2 must be a TraceCollection instance") + return _bt_ctf_get_enum_str(self._d) - if ptr_list is None: + def get_encoding(self): + """ + Return the encoding of an int or a string. + Return a negative value on error. + """ + return _bt_ctf_get_encoding(_bt_ctf_get_decl_from_def(self._d)) + + def get_array_len(self): + """ + Return the len of an array or a negative + value on error. + """ + return _bt_ctf_get_array_len(_bt_ctf_get_decl_from_def(self._d)) + + def get_array_element_at(self, index): + """ + Return the array's element at position index. + Return None on error + """ + array_ptr = _bt_python_get_array_from_def(self._d) + if array_ptr is None: return None - decl_list = [] - for i in range(count): - tmp = CTFReader.EventDecl.__new__(CTFReader.EventDecl) - tmp._d = _bt_python_decl_one_from_list(ptr_list, i) - decl_list.append(tmp) + definition_ptr = _bt_array_index(array_ptr, index) + if definition_ptr is None: + return None + return _Definition(definition_ptr, self.scope) - return decl_list + def get_sequence_len(self): + """ + Return the len of a sequence or a negative + value on error. + """ + seq = _bt_python_get_sequence_from_def(self._d) + return _bt_sequence_len(seq) + + def get_sequence_element_at(self, index): + """ + Return the sequence's element at position index, + otherwise return None + """ + seq = _bt_python_get_sequence_from_def(self._d) + if seq is not None: + definition_ptr = _bt_sequence_index(seq, index) + if definition_ptr is not None: + return _Definition(definition_ptr, self.scope) + return None + + def get_uint64(self): + """ + Return the value associated with the field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occured, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_uint64(self._d) + + def get_int64(self): + """ + Return the value associated with the field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occured, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_int64(self._d) + + def get_char_array(self): + """ + Return the value associated with the field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occurred, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_char_array(self._d) + + def get_str(self): + """ + Return the value associated with the field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occurred, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_string(self._d) + + def get_float(self): + """ + Return the value associated with the field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occurred, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_float(self._d) + + def get_variant(self): + """ + Return the variant's selected field. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occurred, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_variant(self._d) + + def get_struct_field_count(self): + """ + Return the number of fields contained in the structure. + If the field does not exist or is not of the type requested, + the value returned is undefined. + """ + return _bt_ctf_get_struct_field_count(self._d) + + def get_struct_field_at(self, i): + """ + Return the structure's field at position i. + If the field does not exist or is not of the type requested, + the value returned is undefined. To check if an error occurred, + use the field_error() function after accessing a field. + """ + return _bt_ctf_get_struct_field_index(self._d, i) + + @property + def value(self): + """ + Return the value associated with the field according to its type. + Return None on error. + """ + id = self.type + value = None + if id == CTFTypeId.STRING: + value = self.get_str() + elif id == CTFTypeId.ARRAY: + value = [] + for i in range(self.get_array_len()): + element = self.get_array_element_at(i) + value.append(element.value) + elif id == CTFTypeId.INTEGER: + if self.get_int_signedness() == 0: + value = self.get_uint64() + else: + value = self.get_int64() + elif id == CTFTypeId.ENUM: + value = self.get_enum_str() + elif id == CTFTypeId.SEQUENCE: + seq_len = self.get_sequence_len() + value = [] + for i in range(seq_len): + evDef = self.get_sequence_element_at(i) + value.append(evDef.value) + elif id == CTFTypeId.FLOAT: + value = self.get_float() + elif id == CTFTypeId.VARIANT: + variant = Definition.__new__(Definition) + variant._d = self.get_variant(); + value = variant.value + elif id == CTFTypeId.STRUCT: + value = {} + for i in range(self.get_struct_field_count()): + member = _Definition(self.get_struct_field_at(i), self.scope) + value[member.name] = member.value + + if field_error(): + raise FieldError("Error occurred while accessing field {} of type {}".format(self.field_name(), CTFTypeId.get_type_name(self.field_type()))) + return value + + @property + def scope(self): + """Return the scope of a field or None on error.""" + return self._s %} diff --git a/bindings/python/examples/babeltrace_and_lttng.py b/bindings/python/examples/babeltrace_and_lttng.py index 3e7d57f5..42ebc85e 100644 --- a/bindings/python/examples/babeltrace_and_lttng.py +++ b/bindings/python/examples/babeltrace_and_lttng.py @@ -110,8 +110,7 @@ print("Writing trace file...") output = open(out_file, "wt") for event in traces.events: - output.write("TS: {}, {} : {}\n".format(event.get_timestamp(), - event.get_cycles(), event.get_name())) + output.write("TS: {}, {} : {}\n".format(event.timestamp, event.cycles, event.name)) # Closing file output.close() diff --git a/bindings/python/examples/example-api-test.py b/bindings/python/examples/example-api-test.py index 12cfb6eb..3b59a94b 100644 --- a/bindings/python/examples/example-api-test.py +++ b/bindings/python/examples/example-api-test.py @@ -34,31 +34,25 @@ if trace_handle is None: raise IOError("Error adding trace") # Listing events -lst = CTFReader.get_event_decl_list(trace_handle, traces) +lst = get_event_decl_list(trace_handle, traces) print("--- Event list ---") for item in lst: print("event : {}".format(item.get_name())) print("--- Done ---") for event in traces.events: - print("TS: {}, {} : {}".format(event.get_timestamp(), - event.get_cycles(), event.get_name())) + print("TS: {}, {} : {}".format(event.timestamp, event.cycles, event.name)) - if event.get_name() == "sched_switch": - prev_field = event.get_field("prev_comm") - if prev_field is None: + if event.name == "sched_switch": + prev_comm = event["prev_comm"] + if prev_comm is None: print("ERROR: Missing prev_comm context info") else: - prev_comm = prev_field[0].get_value() - if prev_comm is not None: - print("sched_switch prev_comm: {}".format(prev_comm)) + print("sched_switch prev_comm: {}".format(prev_comm)) - if event.get_name() == "exit_syscall": - ret_field = event.get_field("ret") - if ret_field is None: + if event.name == "exit_syscall": + ret_code = event["ret"] + if ret_code is None: print("ERROR: Unable to extract ret") else: - ret_code = ret_field[0].get_value() - if ret_code is not None: - print("exit_syscall ret: {}".format(ret_code)) - + print("exit_syscall ret: {}".format(ret_code)) diff --git a/bindings/python/examples/sched_switch.py b/bindings/python/examples/sched_switch.py index 1f4f48c7..32d1ef8c 100644 --- a/bindings/python/examples/sched_switch.py +++ b/bindings/python/examples/sched_switch.py @@ -42,71 +42,29 @@ if ret is None: for event in traces.events: while True: - if event.get_name() == "sched_switch": - # Getting scope definition - sco = event.get_top_level_scope(CTFReader.scope.STREAM_EVENT_CONTEXT) - if sco is None: - print("ERROR: Cannot get definition scope for sched_switch") - break # Next event - + if event.name == "sched_switch": # Getting PID - pid_field = event.get_field_with_scope(sco, "pid") - if pid_field is None: + pid = event.field_with_scope("pid", scope.STREAM_EVENT_CONTEXT) + if pid is None: print("ERROR: Missing PID info for sched_switch") break # Next event - pid = pid_field.get_value() + if usePID and (pid != long(sys.argv[1])): break # Next event - sco = event.get_top_level_scope(CTFReader.scope.EVENT_FIELDS) - - # prev_comm - field = event.get_field_with_scope(sco, "prev_comm") - if field is None: - print("ERROR: Missing prev_comm context info") - prev_comm = field.get_value() - - # prev_tid - field = event.get_field_with_scope(sco, "prev_tid") - if field is None: - print("ERROR: Missing prev_tid context info") - prev_tid = field.get_value() - - # prev_prio - field = event.get_field_with_scope(sco, "prev_prio") - if field is None: - print("ERROR: Missing prev_prio context info") - prev_prio = field.get_value() - - # prev_state - field = event.get_field_with_scope(sco, "prev_state") - if field is None: - print("ERROR: Missing prev_state context info") - prev_state = field.get_value() - - # next_comm - field = event.get_field_with_scope(sco, "next_comm") - if field is None: - print("ERROR: Missing next_comm context info") - next_comm = field.get_value() - - # next_tid - field = event.get_field_with_scope(sco, "next_tid") - if field is None: - print("ERROR: Missing next_tid context info") - next_tid = field.get_value() - - # next_prio - field = event.get_field_with_scope(sco, "next_prio") - if field is None: - print("ERROR: Missing next_prio context info") - next_prio = field.get_value() + prev_comm = event["prev_comm"] + prev_tid = event["prev_tid"] + prev_prio = event["prev_prio"] + prev_state = event["prev_state"] + next_comm = event["next_comm"] + next_tid = event["next_tid"] + next_prio = event["next_prio"] # Output print("sched_switch, pid = {}, TS = {}, prev_comm = {},\n\t" "prev_tid = {}, prev_prio = {}, prev_state = {},\n\t" "next_comm = {}, next_tid = {}, next_prio = {}".format( - pid, event.get_timestamp(), prev_comm, prev_tid, + pid, event.timestamp, prev_comm, prev_tid, prev_prio, prev_state, next_comm, next_tid, next_prio)) break # Next event diff --git a/bindings/python/examples/sequence_test.py b/bindings/python/examples/sequence_test.py index 2379d9b9..cf0e2c8e 100644 --- a/bindings/python/examples/sequence_test.py +++ b/bindings/python/examples/sequence_test.py @@ -36,18 +36,24 @@ if trace_handle is None: raise IOError("Error adding trace") # Listing events -lst = CTFReader.get_event_decl_list(trace_handle, traces) +lst = get_event_decl_list(trace_handle, traces) print("--- Event list ---") for item in lst: print("event : {}".format(item.get_name())) print("--- Done ---") for event in traces.events: - print("TS: {}, {} : {}".format(event.get_timestamp(), - event.get_cycles(), event.get_name())) - field = event.get_field("seq_int_field") - if field is not None: - print("int sequence values: {}". format(field[0].get_value())) - field = event.get_field("seq_long_field") - if field is not None: - print("long sequence values: {}". format(field[0].get_value())) + print("TS: {}, {} : {}".format(event.timestamp, + event.cycles, event.name)) + + try: + sequence = event["seq_int_field"] + print("int sequence values: {}". format(sequence)) + except KeyError: + pass + + try: + sequence = event["seq_long_field"] + print("long sequence values: {}". format(sequence)) + except KeyError: + pass