From 23b7dc5b5c1c68df28e162ebdf33873480f24f78 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@digia.com> Date: Fri, 18 Jan 2013 14:19:20 +0100 Subject: [PATCH] CDB: Dump QStringRef. Extend QString dumper to be able to dump a substring. Change-Id: I1f64e441980a7c2c295f40317b2b187cfebcd7ea Reviewed-by: hjk <qthjk@ovi.com> --- src/libs/qtcreatorcdbext/knowntype.h | 1 + src/libs/qtcreatorcdbext/symbolgroupvalue.cpp | 60 +++++++++++++++---- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/libs/qtcreatorcdbext/knowntype.h b/src/libs/qtcreatorcdbext/knowntype.h index 39e8c8cd501..9d197d345c7 100644 --- a/src/libs/qtcreatorcdbext/knowntype.h +++ b/src/libs/qtcreatorcdbext/knowntype.h @@ -71,6 +71,7 @@ enum KnownType KT_QVariant = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + KT_HasComplexDumper + 17, KT_QBasicAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 18, KT_QAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 19, + KT_QStringRef = KT_Qt_Type + KT_HasSimpleDumper + 20, KT_QObject = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 20, KT_QWindow = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 21, KT_QWidget = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 22, diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 3016dfe2efa..d4bff299324 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -30,6 +30,10 @@ // std::copy is perfectly fine, don't let MSVC complain about it being deprecated #pragma warning (disable: 4996) +#ifndef NOMINMAX +# define NOMINMAX +#endif + #include "symbolgroupvalue.h" #include "symbolgroup.h" #include "stringutils.h" @@ -38,6 +42,7 @@ #include <iomanip> #include <algorithm> +#include <limits> #include <ctype.h> typedef std::vector<int>::size_type VectorIndexType; @@ -1263,6 +1268,8 @@ static KnownType knownClassTypeHelper(const std::string &type, return KT_QTransform; if (!type.compare(qPos, 10, "QFixedSize")) return KT_QFixedSize; + if (!type.compare(qPos, 10, "QStringRef")) + return KT_QStringRef; break; case 11: if (!type.compare(qPos, 11, "QStringList")) @@ -1517,36 +1524,40 @@ QtStringAddressData readQtStringAddressData(const SymbolGroupValue &dV, // Retrieve data from a QByteArrayData(char)/QStringData(wchar_t) // in desired type. For empty arrays, no data are allocated. +// All sizes are in CharType units. zeroTerminated means data are 0-terminated +// in the data type, but "size" does not contain it. template <typename CharType> bool readQt5StringData(const SymbolGroupValue &dV, int qtMajorVersion, - bool zeroTerminated, unsigned sizeLimit, + bool zeroTerminated, unsigned position, unsigned sizeLimit, unsigned *fullSize, unsigned *arraySize, CharType **array) { *array = 0; - QtStringAddressData data = readQtStringAddressData(dV, qtMajorVersion); - *arraySize = *fullSize = data.size; - if (!data.address) + const QtStringAddressData data = readQtStringAddressData(dV, qtMajorVersion); + if (!data.address || position > data.size) return false; + const ULONG64 address = data.address + sizeof(CharType) * position; + *fullSize = data.size - position; + *arraySize = std::min(*fullSize, sizeLimit); if (!*fullSize) return true; - const bool truncated = *fullSize > sizeLimit; - *arraySize = truncated ? sizeLimit : *fullSize; const unsigned memorySize = sizeof(CharType) * (*arraySize + (zeroTerminated ? 1 : 0)); unsigned char *memory = SymbolGroupValue::readMemory(dV.context().dataspaces, - data.address, memorySize); + address, memorySize); if (!memory) return false; *array = reinterpret_cast<CharType *>(memory); - if (truncated && zeroTerminated) + if ((*arraySize < *fullSize) && zeroTerminated) *(*array + *arraySize) = CharType(0); return true; } static inline bool dumpQString(const SymbolGroupValue &v, std::wostream &str, - MemoryHandle **memoryHandle = 0) + MemoryHandle **memoryHandle = 0, + unsigned position = 0, + unsigned length = std::numeric_limits<unsigned>::max()) { const QtInfo &qtInfo = QtInfo::get(v.context()); const SymbolGroupValue dV = v["d"]; @@ -1557,7 +1568,11 @@ static inline bool dumpQString(const SymbolGroupValue &v, std::wostream &str, if (const SymbolGroupValue sizeValue = dV["size"]) { const int size = sizeValue.intValue(); if (size >= 0) { - const std::wstring stringData = dV["data"].wcharPointerData(size); + std::wstring stringData = dV["data"].wcharPointerData(size); + if (position && position < stringData.size()) + stringData.erase(0, position); + if (length < stringData.size()) + stringData.erase(length, stringData.size() - length); str << L'"' << stringData << L'"'; if (memoryHandle) *memoryHandle = MemoryHandle::fromStdWString(stringData); @@ -1574,11 +1589,13 @@ static inline bool dumpQString(const SymbolGroupValue &v, std::wostream &str, const SymbolGroupValue typeArrayV = dV[unsigned(0)]; if (!typeArrayV) return false; - if (!readQt5StringData(typeArrayV, qtInfo.version, true, 10240, &fullSize, &size, &memory)) + if (!readQt5StringData(typeArrayV, qtInfo.version, true, position, + std::min(length, unsigned(10240)), + &fullSize, &size, &memory)) return false; if (size) { str << L'"' << memory; - if (fullSize > size) + if (std::min(fullSize, length) > size) str << L"..."; str << L'"'; } else { @@ -1591,6 +1608,20 @@ static inline bool dumpQString(const SymbolGroupValue &v, std::wostream &str, return true; } +static inline bool dumpQStringRef(const SymbolGroupValue &v, std::wostream &str, + MemoryHandle **memoryHandle = 0) +{ + const int position = v["m_position"].intValue(); + const int size = v["m_size"].intValue(); + if (position < 0 || size < 0) + return false; + const SymbolGroupValue string = v["m_string"]; + if (!string || !dumpQString(string, str, memoryHandle, position, size)) + return false; + str << L" (" << position << ',' << size << L')'; + return true; +} + /* Pad a memory offset to align with pointer size */ static inline unsigned padOffset(unsigned offset) { @@ -1670,7 +1701,7 @@ static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str, const SymbolGroupValue typeArrayV = dV[unsigned(0)]; if (!typeArrayV) return false; - if (!readQt5StringData(typeArrayV, qtInfo.version, false, 10240, &fullSize, &size, &memory)) + if (!readQt5StringData(typeArrayV, qtInfo.version, false, 0, 10240, &fullSize, &size, &memory)) return false; if (size) { // Emulate CDB's behavior of replacing unprintable characters @@ -2593,6 +2624,9 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx, case KT_QString: rc = dumpQString(v, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed; break; + case KT_QStringRef: + rc = dumpQStringRef(v, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed; + break; case KT_QColor: rc = dumpQColor(v, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed; break; -- GitLab