Hi Enrico & Daniel,
Thanks all, I’m browsing through the formatters page. I managed to throw together a skeleton, but it doesn’t seem to work too well. Maybe I failed to grasp something:
import lldb
def UniString_SummaryProvider(valobj, dict):
e = lldb.SBError()
s = u’"’
if valobj.GetValue() != 0:
content = valobj.GetChildMemberWithName(‘content’)
length = content.GetPointeeData(0,1).GetChildMemberWithName(‘length’)
string = content.GetPointeeData(0,1).GetChildMemberWithName(‘string’)
i = 0
newchar = -1
while newchar != 0 and i < length:
read next wchar character out of memory
data_val = string.GetPointeeData(i, 1)
newchar = data_val.GetUnsignedInt16(e, 0) # utf-16
if e.fail:
return ‘’
i = i + 1
add the character to our string ‘s’
if newchar != 0:
s = s + unichr(newchar)
s = s + u’"’
return s.encode(‘utf-8’)
def __lldb_init_module(debugger,dict):
debugger.HandleCommand(“type summary add -F UniString.UniString_SummaryProvider GS::UniString”)
Yes, I’d like to show the string member (it’s in UTF-16) in the summary. I was looking at the CFString.py formatter, but that seems to be an overkill in our case.
The string[1] member is an ‘old’ C trick, here’s the allocation routine. It preallocates a separate buffer of the right size, then uses placement new to put the SharedBuffer member there.
inline GS::UniString::SharedBuffer::SharedBuffer (USize initialLength, USize initialCapacity, Int32 initialRefCounter):
length (initialLength),
capacity (initialCapacity),
refCounter (initialRefCounter)
{
}
inline USize GS::UniString::CapacityToBufferSize (USize capacity)
{
return (sizeof (SharedBuffer) + (capacity - 1) * sizeof (unichar));
}
inline USize GS::UniString::BufferSizeToCapacity (USize bufferSize)
{
return ((bufferSize - sizeof (SharedBuffer)) / sizeof (unichar) + 1);
}
GS::UniString::SharedBuffer* GS::UniString::AllocateBuffer (USize capacity)
{
if (capacity == 0)
return ShareEmptyBuffer ();
capacity++; // to ensure capacity for the closing 0 (used in conversion)
USize bufferSize = CapacityToBufferSize (capacity);
if (bufferSize < MinBufferSize4) {
if (bufferSize < MinBufferSize1)
bufferSize = MinBufferSize1;
else if (bufferSize < MinBufferSize2)
bufferSize = MinBufferSize2;
else if (bufferSize < MinBufferSize3)
bufferSize = MinBufferSize3;
else
bufferSize = MinBufferSize4;
}
void* buffer = cachedAllocator.Allocate (bufferSize, &bufferSize);
capacity = BufferSizeToCapacity (bufferSize);
return new (buffer) SharedBuffer (0, capacity, 1);
}
Best, Akos