#include "lldb/Core/ValueObjectSyntheticFilter.h"
#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/Endian.h"
return len;
}
+static bool
+CopyStringDataToBufferSP(const StreamString& source,
+ lldb::DataBufferSP& destination)
+{
+ destination.reset(new DataBufferHeap(source.GetSize()+1,0));
+ memcpy(destination->GetBytes(), source.GetString().c_str(), source.GetSize());
+ return true;
+}
+
size_t
-ValueObject::ReadPointedString (Stream& s,
+ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp,
Error& error,
uint32_t max_length,
bool honor_array,
Format item_format)
{
+ StreamString s;
ExecutionContext exe_ctx (GetExecutionContextRef());
Target* target = exe_ctx.GetTargetPtr();
-
+
if (!target)
{
s << "<no target to read from>";
error.SetErrorString("no target to read from");
+ CopyStringDataToBufferSP(s, buffer_sp);
return 0;
}
{
s << "<invalid address>";
error.SetErrorString("invalid address");
+ CopyStringDataToBufferSP(s, buffer_sp);
return 0;
}
-
+
Address cstr_so_addr (cstr_address);
DataExtractor data;
if (cstr_len > 0 && honor_array)
// I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
// but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
GetPointeeData(data, 0, cstr_len);
-
+
if ((bytes_read = data.GetByteSize()) > 0)
{
total_bytes_read = bytes_read;
- s << '"';
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
if (capped_data)
s << "...";
- s << '"';
}
}
else
{
cstr_len = max_length;
const size_t k_max_buf_size = 64;
-
+
size_t offset = 0;
int cstr_len_displayed = -1;
size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
if (len > k_max_buf_size)
len = k_max_buf_size;
- if (cstr && cstr_len_displayed < 0)
- s << '"';
-
+
if (cstr_len_displayed < 0)
cstr_len_displayed = len;
-
+
if (len == 0)
break;
cstr_len_displayed += len;
if (len > cstr_len)
len = cstr_len;
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
if (len < k_max_buf_size)
break;
capped_cstr = true;
break;
}
-
+
cstr_len -= len;
offset += len;
}
if (cstr_len_displayed >= 0)
{
- s << '"';
if (capped_cstr)
s << "...";
}
error.SetErrorString("not a string object");
s << "<not a string object>";
}
+ CopyStringDataToBufferSP(s, buffer_sp);
return total_bytes_read;
}
custom_format == eFormatVectorOfChar)) // print char[] & char* directly
{
Error error;
- ReadPointedString(s,
+ lldb::DataBufferSP buffer_sp;
+ ReadPointedString(buffer_sp,
error,
0,
(custom_format == eFormatVectorOfChar) ||
(custom_format == eFormatCharArray));
+ lldb_private::formatters::ReadBufferAndDumpToStreamOptions options;
+ options.SetData(DataExtractor(buffer_sp, lldb::eByteOrderInvalid, 8)); // none of this matters for a string - pass some defaults
+ options.SetStream(&s);
+ options.SetPrefixToken(0);
+ options.SetQuote('"');
+ options.SetSourceSize(buffer_sp->GetByteSize());
+ options.SetEscapeNonPrintables(true);
+ lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
return !error.Fail();
}
{
uint64_t size = 0;
ValueObjectSP location_sp((ValueObject*)nullptr);
+
if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
return false;
+
if (size == 0)
{
stream.Printf("\"\"");
return true;
}
+
if (!location_sp)
return false;
- Error error;
- if (location_sp->ReadPointedString(stream,
- error,
- 0, // max length is decided by the settings
- false) == 0) // do not honor array (terminates on first 0 byte even for a char[])
- stream.Printf("\"\""); // if nothing was read, print an empty string
- return error.Success();
+
+ DataExtractor extractor;
+ size = std::min<decltype(size)>(size, valobj.GetTargetSP()->GetMaximumSizeOfStringSummary());
+ location_sp->GetPointeeData(extractor, 0, size);
+
+ lldb_private::formatters::ReadBufferAndDumpToStreamOptions options;
+ options.SetData(extractor); // none of this matters for a string - pass some defaults
+ options.SetStream(&stream);
+ options.SetPrefixToken(0);
+ options.SetQuote('"');
+ options.SetSourceSize(size);
+ options.SetEscapeNonPrintables(true);
+ lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
+
+ return true;
}
bool