static bool DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**, const SourceDataType*, UTF8**, UTF8*, ConversionFlags), const DataExtractor& data, Stream& stream, char prefix_token, char quote, uint32_t sourceSize, bool escapeNonPrintables) { if (prefix_token != 0) stream.Printf("%c",prefix_token); if (quote != 0) stream.Printf("%c",quote); if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd()) { const int bufferSPSize = data.GetByteSize(); if (sourceSize == 0) { const int origin_encoding = 8*sizeof(SourceDataType); sourceSize = bufferSPSize/(origin_encoding / 4); } const SourceDataType *data_ptr = (const SourceDataType*)data.GetDataStart(); const SourceDataType *data_end_ptr = data_ptr + sourceSize; while (data_ptr < data_end_ptr) { if (!*data_ptr) { data_end_ptr = data_ptr; break; } data_ptr++; } data_ptr = (const SourceDataType*)data.GetDataStart(); lldb::DataBufferSP utf8_data_buffer_sp; UTF8* utf8_data_ptr = nullptr; UTF8* utf8_data_end_ptr = nullptr; if (ConvertFunction) { utf8_data_buffer_sp.reset(new DataBufferHeap(4*bufferSPSize,0)); utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize(); ConvertFunction ( &data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion ); utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr } else { // just copy the pointers - the cast is necessary to make the compiler happy // but this should only happen if we are reading UTF8 data utf8_data_ptr = (UTF8*)data_ptr; utf8_data_end_ptr = (UTF8*)data_end_ptr; } // since we tend to accept partial data (and even partially malformed data) // we might end up with no NULL terminator before the end_ptr // hence we need to take a slower route and ensure we stay within boundaries for (; utf8_data_ptr < utf8_data_end_ptr;) { if (!*utf8_data_ptr) break; if (escapeNonPrintables) { uint8_t* next_data = nullptr; auto printable = GetPrintable(StringElementType::UTF8, utf8_data_ptr, utf8_data_end_ptr, next_data); auto printable_bytes = printable.GetBytes(); auto printable_size = printable.GetSize(); if (!printable_bytes || !next_data) { // GetPrintable() failed on us - print one byte in a desperate resync attempt printable_bytes = utf8_data_ptr; printable_size = 1; next_data = utf8_data_ptr+1; } for (unsigned c = 0; c < printable_size; c++) stream.Printf("%c", *(printable_bytes+c)); utf8_data_ptr = (uint8_t*)next_data; } else { stream.Printf("%c",*utf8_data_ptr); utf8_data_ptr++; } } } if (quote != 0) stream.Printf("%c",quote); return true; }
static bool DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**, const SourceDataType*, UTF8**, UTF8*, ConversionFlags), DataExtractor& data, Stream& stream, char prefix_token = '@', char quote = '"', uint32_t sourceSize = 0) { if (prefix_token != 0) stream.Printf("%c",prefix_token); if (quote != 0) stream.Printf("%c",quote); if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd()) { const int bufferSPSize = data.GetByteSize(); if (sourceSize == 0) { const int origin_encoding = 8*sizeof(SourceDataType); sourceSize = bufferSPSize/(origin_encoding / 4); } SourceDataType *data_ptr = (SourceDataType*)data.GetDataStart(); SourceDataType *data_end_ptr = data_ptr + sourceSize; while (data_ptr < data_end_ptr) { if (!*data_ptr) { data_end_ptr = data_ptr; break; } data_ptr++; } data_ptr = (SourceDataType*)data.GetDataStart(); lldb::DataBufferSP utf8_data_buffer_sp; UTF8* utf8_data_ptr = nullptr; UTF8* utf8_data_end_ptr = nullptr; if (ConvertFunction) { utf8_data_buffer_sp.reset(new DataBufferHeap(4*bufferSPSize,0)); utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize(); ConvertFunction ( (const SourceDataType**)&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion ); utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr } else { // just copy the pointers - the cast is necessary to make the compiler happy // but this should only happen if we are reading UTF8 data utf8_data_ptr = (UTF8*)data_ptr; utf8_data_end_ptr = (UTF8*)data_end_ptr; } // since we tend to accept partial data (and even partially malformed data) // we might end up with no NULL terminator before the end_ptr // hence we need to take a slower route and ensure we stay within boundaries for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++) { if (!*utf8_data_ptr) break; stream.Printf("%c",*utf8_data_ptr); } } if (quote != 0) stream.Printf("%c",quote); return true; }