1 //===-- StringPrinter.h -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_StringPrinter_h_
10 #define liblldb_StringPrinter_h_
15 #include "lldb/lldb-forward.h"
17 #include "lldb/Utility/DataExtractor.h"
19 namespace lldb_private {
20 namespace formatters {
23 enum class StringElementType { ASCII, UTF8, UTF16, UTF32 };
25 enum class GetPrintableElementType { ASCII, UTF8 };
27 class ReadStringAndDumpToStreamOptions {
29 ReadStringAndDumpToStreamOptions()
30 : m_location(0), m_process_sp(), m_stream(nullptr), m_prefix_token(),
31 m_suffix_token(), m_quote('"'), m_source_size(0),
32 m_needs_zero_termination(true), m_escape_non_printables(true),
33 m_ignore_max_length(false), m_zero_is_terminator(true),
34 m_language_type(lldb::eLanguageTypeUnknown) {}
36 ReadStringAndDumpToStreamOptions(ValueObject &valobj);
38 ReadStringAndDumpToStreamOptions &SetLocation(uint64_t l) {
43 uint64_t GetLocation() const { return m_location; }
45 ReadStringAndDumpToStreamOptions &SetProcessSP(lldb::ProcessSP p) {
50 lldb::ProcessSP GetProcessSP() const { return m_process_sp; }
52 ReadStringAndDumpToStreamOptions &SetStream(Stream *s) {
57 Stream *GetStream() const { return m_stream; }
59 ReadStringAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
64 ReadStringAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
65 m_prefix_token.clear();
69 const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
71 ReadStringAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
76 ReadStringAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
77 m_suffix_token.clear();
81 const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
83 ReadStringAndDumpToStreamOptions &SetQuote(char q) {
88 char GetQuote() const { return m_quote; }
90 ReadStringAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
95 uint32_t GetSourceSize() const { return m_source_size; }
97 ReadStringAndDumpToStreamOptions &SetNeedsZeroTermination(bool z) {
98 m_needs_zero_termination = z;
102 bool GetNeedsZeroTermination() const { return m_needs_zero_termination; }
104 ReadStringAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
105 m_zero_is_terminator = e;
109 bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
111 ReadStringAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
112 m_escape_non_printables = e;
116 bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
118 ReadStringAndDumpToStreamOptions &SetIgnoreMaxLength(bool e) {
119 m_ignore_max_length = e;
123 bool GetIgnoreMaxLength() const { return m_ignore_max_length; }
125 ReadStringAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
130 lldb::LanguageType GetLanguage() const
133 return m_language_type;
138 lldb::ProcessSP m_process_sp;
140 std::string m_prefix_token;
141 std::string m_suffix_token;
143 uint32_t m_source_size;
144 bool m_needs_zero_termination;
145 bool m_escape_non_printables;
146 bool m_ignore_max_length;
147 bool m_zero_is_terminator;
148 lldb::LanguageType m_language_type;
151 class ReadBufferAndDumpToStreamOptions {
153 ReadBufferAndDumpToStreamOptions()
154 : m_data(), m_stream(nullptr), m_prefix_token(), m_suffix_token(),
155 m_quote('"'), m_source_size(0), m_escape_non_printables(true),
156 m_zero_is_terminator(true), m_is_truncated(false),
157 m_language_type(lldb::eLanguageTypeUnknown) {}
159 ReadBufferAndDumpToStreamOptions(ValueObject &valobj);
161 ReadBufferAndDumpToStreamOptions(
162 const ReadStringAndDumpToStreamOptions &options);
164 ReadBufferAndDumpToStreamOptions &SetData(DataExtractor d) {
169 lldb_private::DataExtractor GetData() const { return m_data; }
171 ReadBufferAndDumpToStreamOptions &SetStream(Stream *s) {
176 Stream *GetStream() const { return m_stream; }
178 ReadBufferAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
183 ReadBufferAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
184 m_prefix_token.clear();
188 const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
190 ReadBufferAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
195 ReadBufferAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
196 m_suffix_token.clear();
200 const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
202 ReadBufferAndDumpToStreamOptions &SetQuote(char q) {
207 char GetQuote() const { return m_quote; }
209 ReadBufferAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
214 uint32_t GetSourceSize() const { return m_source_size; }
216 ReadBufferAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
217 m_escape_non_printables = e;
221 bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
223 ReadBufferAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
224 m_zero_is_terminator = e;
228 bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
230 ReadBufferAndDumpToStreamOptions &SetIsTruncated(bool t) {
235 bool GetIsTruncated() const { return m_is_truncated; }
237 ReadBufferAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
242 lldb::LanguageType GetLanguage() const
245 return m_language_type;
249 DataExtractor m_data;
251 std::string m_prefix_token;
252 std::string m_suffix_token;
254 uint32_t m_source_size;
255 bool m_escape_non_printables;
256 bool m_zero_is_terminator;
258 lldb::LanguageType m_language_type;
261 // I can't use a std::unique_ptr for this because the Deleter is a template
263 // and I want the same type to represent both pointers I want to free and
264 // pointers I don't need to free - which is what this class essentially is
265 // It's very specialized to the needs of this file, and not suggested for
267 template <typename T = uint8_t, typename U = char, typename S = size_t>
268 struct StringPrinterBufferPointer {
270 typedef std::function<void(const T *)> Deleter;
272 StringPrinterBufferPointer(std::nullptr_t ptr)
273 : m_data(nullptr), m_size(0), m_deleter() {}
275 StringPrinterBufferPointer(const T *bytes, S size,
276 Deleter deleter = nullptr)
277 : m_data(bytes), m_size(size), m_deleter(deleter) {}
279 StringPrinterBufferPointer(const U *bytes, S size,
280 Deleter deleter = nullptr)
281 : m_data(reinterpret_cast<const T *>(bytes)), m_size(size),
282 m_deleter(deleter) {}
284 StringPrinterBufferPointer(StringPrinterBufferPointer &&rhs)
285 : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) {
286 rhs.m_data = nullptr;
289 StringPrinterBufferPointer(const StringPrinterBufferPointer &rhs)
290 : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) {
291 rhs.m_data = nullptr; // this is why m_data has to be mutable
294 ~StringPrinterBufferPointer() {
295 if (m_data && m_deleter)
300 const T *GetBytes() const { return m_data; }
302 const S GetSize() const { return m_size; }
304 StringPrinterBufferPointer &
305 operator=(const StringPrinterBufferPointer &rhs) {
306 if (m_data && m_deleter)
310 m_deleter = rhs.m_deleter;
311 rhs.m_data = nullptr;
316 mutable const T *m_data;
321 typedef std::function<StringPrinter::StringPrinterBufferPointer<
322 uint8_t, char, size_t>(uint8_t *, uint8_t *, uint8_t *&)>
324 typedef std::function<EscapingHelper(GetPrintableElementType)>
325 EscapingHelperGenerator;
327 static EscapingHelper
328 GetDefaultEscapingHelper(GetPrintableElementType elem_type);
330 template <StringElementType element_type>
332 ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options);
334 template <StringElementType element_type>
336 ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options);
339 } // namespace formatters
340 } // namespace lldb_private
342 #endif // liblldb_StringPrinter_h_