forked from qt-creator/qt-creator
CDB: Dump QStringRef.
Extend QString dumper to be able to dump a substring. Change-Id: I1f64e441980a7c2c295f40317b2b187cfebcd7ea Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -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,
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user