# -*- coding: utf-8 -*- """ Debugging Helpers for use with QtCreator. To activate, in QtCreator open Tools -> Options... -> Debugger -> Locals & Expressions and put the absolut path to this file into the "Extra Debugging Helpers" field. @author Christian Fröbel """ from dumper import * from datetime import datetime def qdump__dds__core__basic_string(d, value): d.putItem(value['str_']) d.putBetterType('dds::core::string') def qdump__rti__core__vector(d, value): innerType = value.type[0] capacity = value['seq_']['_maximum'].integer() size = value['seq_']['_length'].integer() d.putItemCount(size) d.putNumChild(size) if d.isExpanded(): with Children(d): with SubItem(d, 'capacity'): d.putValue(capacity) with SubItem(d, 'values'): d.putItemCount(size) if d.isExpanded(): rawBuffer = value['seq_']['_contiguous_buffer'] d.putArrayData(rawBuffer.integer(), size, innerType) def qdump__rti__core__optional(d, value): innerType = value.type[0] stringType = d.createType('dds::core::string') # Kann man Types direkt vergleichen, auch wenn innerType ein Alias ist? if innerType.name == 'dds::core::basic_string >': _dumpOptionalString(d, value) else: _dumpOptionalCommon(d, value) def _dumpOptionalCommon(d, value): """Default implementation for dds::core::optional""" ptrToValue = value['value_'] isInitialized = ptrToValue.integer() != 0 if isInitialized: innerType = value.type[0] d.putItem(ptrToValue.dereference()) d.putBetterType(innerType) else: d.putValue("uninitialized") d.putNumChild(0) def _dumpOptionalString(d, value): """Specialization for dds::core::optional""" strValue = value['value_'] isInitialized = strValue['str_'].integer() != 0 if isInitialized: d.putItem(strValue) d.putBetterType('dds::core::string') else: d.putValue("uninitialized") d.putBetterType('dds::core::optional') d.putNumChild(0) def qdump__Core__BaseEntity(d, value): name = d.extractCString(value['m_name_']['str_'].integer()) d.putValue('{}: \\"{}\\"'.format(value['m_id_'].integer(), name)) d.putNumChild(5) if d.isExpanded(): with Children(d): for member in 'm_id_ m_name_ m_isDeleted_ m_isUsed_ m_isBlockedForEdit_'.split(): with SubItem(d, member): d.putItem(value[member]) def qdump__dds__core__safe_enum(d, value): d.putItem(value['val']) def qdump__std__chrono__duration(d, value): seconds = _createSecondsFromDuration(value) ms = int(seconds*1000) d.putValue('{}ms'.format(ms)) d.putPlainChildren(value) def qdump__AudioVideoManagement__AvaTimePoint(d, value): dt = _createDateTimeFromTimePoint(value) d.putValue(_isoFormat(dt, nachkommaStellen=2)) d.putPlainChildren(value) def qdump__std__chrono__time_point(d, value): dt = _createDateTimeFromTimePoint(value) d.putValue(_isoFormat(dt, nachkommaStellen=6)) d.putPlainChildren(value) def qdump__NTPTimestamp(d, value): dt = _createDateTimeFromNtpTimestamp(value) d.putValue(_isoFormat(dt, nachkommaStellen=3)) d.putPlainChildren(value) def qdump__NTPRange(d, value): dtBegin = _createDateTimeFromNtpTimestamp(value['m_begin']) dtEnd = _createDateTimeFromNtpTimestamp(value['m_end']) delta = dtEnd - dtBegin seconds = delta.total_seconds() # float fractionInMilli = int(seconds * 1000 + 0.5) % 1000 d.putValue('{} - {}, {:d}.{:03d}s'.format(_isoFormat(dtBegin, nachkommaStellen=3), _isoFormat(dtEnd, nachkommaStellen=3), int(seconds), fractionInMilli)) d.putPlainChildren(value) def _createSecondsFromDuration(value): """Create seconds as float from a std::chrono::duration value""" durationType = value.type if durationType.code == TypeCodeTypedef: durationType = durationType.stripTypedefs() ratioType = durationType[1] dividend = ratioType[0] divisor = ratioType[1] duration = int(value['__r']) seconds = duration * dividend / float(divisor) return seconds def _createDateTimeFromTimePoint(value): """Create a datatime from a std::chrono::timepoint value""" sSinceEpoch = _createSecondsFromDuration(value['__d']) return datetime.utcfromtimestamp(sSinceEpoch) NTP_OFFSET = 2208988800 # in s; NTP starts at 1900-01-01 where unix epoch is 1970-01-01; difference is 70 years plus 17 leap years def _createSecondsFromNtpTimestamp(value): """Create seconds as float from AVS NTPTimestamp. The format is a fixed 64 bit floating point number where the upper 32 bit denote the seconds and the lower 32 bit denote the fraction of a second.""" fixedFloatValue = int(value['m_data']) seconds = fixedFloatValue >> 32 fract = fixedFloatValue & 0xffffffff return seconds + float(fract) / (1 << 32) - NTP_OFFSET def _createDateTimeFromNtpTimestamp(value): """Create a datetime from AVS NTPTimestamp""" sSinceEpoch = _createSecondsFromNtpTimestamp(value) return datetime.utcfromtimestamp(sSinceEpoch) def _isoFormat(dt, nachkommaStellen): """Return the ISO-representation for a given datetime instance with the requested number of Nachkommastellen""" assert nachkommaStellen >= 0 and nachkommaStellen <= 6 s = dt.isoformat(' ') if dt.microsecond > 0: if nachkommaStellen == 6: return s return s[:-(6-nachkommaStellen)] return s + '.' + nachkommaStellen * '0'