|
|
|||
File indexing completed on 2026-05-10 08:42:58
0001 //===-- Stream.h ------------------------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLDB_UTILITY_STREAM_H 0010 #define LLDB_UTILITY_STREAM_H 0011 0012 #include "lldb/Utility/Flags.h" 0013 #include "lldb/lldb-defines.h" 0014 #include "lldb/lldb-enumerations.h" 0015 #include "llvm/ADT/StringRef.h" 0016 #include "llvm/Support/FormatVariadic.h" 0017 #include "llvm/Support/raw_ostream.h" 0018 0019 #include <cstdarg> 0020 #include <cstddef> 0021 #include <cstdint> 0022 #include <type_traits> 0023 0024 namespace lldb_private { 0025 0026 /// \class Stream Stream.h "lldb/Utility/Stream.h" 0027 /// A stream class that can stream formatted output to a file. 0028 class Stream { 0029 public: 0030 /// \a m_flags bit values. 0031 enum { 0032 eBinary = (1 << 0) ///< Get and put data as binary instead of as the default 0033 /// string mode. 0034 }; 0035 0036 /// Struct to store information for color highlighting in the stream. 0037 struct HighlightSettings { 0038 llvm::StringRef pattern; ///< Regex pattern for highlighting. 0039 llvm::StringRef prefix; ///< ANSI color code to start colorization. 0040 llvm::StringRef suffix; ///< ANSI color code to end colorization. 0041 0042 HighlightSettings(llvm::StringRef p, llvm::StringRef pre, 0043 llvm::StringRef suf) 0044 : pattern(p), prefix(pre), suffix(suf) {} 0045 }; 0046 0047 /// Utility class for counting the bytes that were written to a stream in a 0048 /// certain time span. 0049 /// 0050 /// \example 0051 /// ByteDelta delta(*this); 0052 /// WriteDataToStream("foo"); 0053 /// return *delta; 0054 class ByteDelta { 0055 Stream *m_stream; 0056 /// Bytes we have written so far when ByteDelta was created. 0057 size_t m_start; 0058 0059 public: 0060 ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {} 0061 /// Returns the number of bytes written to the given Stream since this 0062 /// ByteDelta object was created. 0063 size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; } 0064 }; 0065 0066 /// Construct with flags and address size and byte order. 0067 /// 0068 /// Construct with dump flags \a flags and the default address size. \a 0069 /// flags can be any of the above enumeration logical OR'ed together. 0070 Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, 0071 bool colors = false); 0072 0073 /// Construct a default Stream, not binary, host byte order and host addr 0074 /// size. 0075 /// 0076 Stream(bool colors = false); 0077 0078 // FIXME: Streams should not be copyable. 0079 Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } 0080 0081 Stream &operator=(const Stream &rhs) { 0082 m_flags = rhs.m_flags; 0083 m_addr_size = rhs.m_addr_size; 0084 m_byte_order = rhs.m_byte_order; 0085 m_indent_level = rhs.m_indent_level; 0086 return *this; 0087 } 0088 0089 /// Destructor 0090 virtual ~Stream(); 0091 0092 // Subclasses must override these methods 0093 0094 /// Flush the stream. 0095 /// 0096 /// Subclasses should flush the stream to make any output appear if the 0097 /// stream has any buffering. 0098 virtual void Flush() = 0; 0099 0100 /// Output character bytes to the stream. 0101 /// 0102 /// Appends \a src_len characters from the buffer \a src to the stream. 0103 /// 0104 /// \param[in] src 0105 /// A buffer containing at least \a src_len bytes of data. 0106 /// 0107 /// \param[in] src_len 0108 /// A number of bytes to append to the stream. 0109 /// 0110 /// \return 0111 /// The number of bytes that were appended to the stream. 0112 size_t Write(const void *src, size_t src_len) { 0113 size_t appended_byte_count = WriteImpl(src, src_len); 0114 m_bytes_written += appended_byte_count; 0115 return appended_byte_count; 0116 } 0117 0118 size_t GetWrittenBytes() const { return m_bytes_written; } 0119 0120 // Member functions 0121 size_t PutChar(char ch); 0122 0123 /// Set the byte_order value. 0124 /// 0125 /// Sets the byte order of the data to extract. Extracted values will be 0126 /// swapped if necessary when decoding. 0127 /// 0128 /// \param[in] byte_order 0129 /// The byte order value to use when extracting data. 0130 /// 0131 /// \return 0132 /// The old byte order value. 0133 lldb::ByteOrder SetByteOrder(lldb::ByteOrder byte_order); 0134 0135 /// Format a C string from a printf style format and variable arguments and 0136 /// encode and append the resulting C string as hex bytes. 0137 /// 0138 /// \param[in] format 0139 /// A printf style format string. 0140 /// 0141 /// \param[in] ... 0142 /// Any additional arguments needed for the printf format string. 0143 /// 0144 /// \return 0145 /// The number of bytes that were appended to the stream. 0146 size_t PrintfAsRawHex8(const char *format, ...) 0147 __attribute__((__format__(__printf__, 2, 3))); 0148 0149 /// Append an uint8_t value in the hexadecimal format to the stream. 0150 /// 0151 /// \param[in] uvalue 0152 /// The value to append. 0153 /// 0154 /// \return 0155 /// The number of bytes that were appended to the stream. 0156 size_t PutHex8(uint8_t uvalue); 0157 0158 size_t PutNHex8(size_t n, uint8_t uvalue); 0159 0160 size_t PutHex16(uint16_t uvalue, 0161 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0162 0163 size_t PutHex32(uint32_t uvalue, 0164 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0165 0166 size_t PutHex64(uint64_t uvalue, 0167 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0168 0169 size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, 0170 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0171 size_t PutFloat(float f, 0172 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0173 0174 size_t PutDouble(double d, 0175 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0176 0177 size_t PutLongDouble(long double ld, 0178 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 0179 0180 size_t PutPointer(void *ptr); 0181 0182 // Append \a src_len bytes from \a src to the stream as hex characters (two 0183 // ascii characters per byte of input data) 0184 size_t 0185 PutBytesAsRawHex8(const void *src, size_t src_len, 0186 lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, 0187 lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); 0188 0189 // Append \a src_len bytes from \a s to the stream as binary data. 0190 size_t PutRawBytes(const void *s, size_t src_len, 0191 lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, 0192 lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); 0193 0194 size_t PutStringAsRawHex8(llvm::StringRef s); 0195 0196 /// Output a NULL terminated C string \a cstr to the stream \a s. 0197 /// 0198 /// \param[in] cstr 0199 /// A NULL terminated C string. 0200 /// 0201 /// \return 0202 /// A reference to this class so multiple things can be streamed 0203 /// in one statement. 0204 Stream &operator<<(const char *cstr); 0205 0206 Stream &operator<<(llvm::StringRef str); 0207 0208 /// Output a pointer value \a p to the stream \a s. 0209 /// 0210 /// \param[in] p 0211 /// A void pointer. 0212 /// 0213 /// \return 0214 /// A reference to this class so multiple things can be streamed 0215 /// in one statement. 0216 Stream &operator<<(const void *p); 0217 0218 /// Output a character \a ch to the stream \a s. 0219 /// 0220 /// \param[in] ch 0221 /// A printable character value. 0222 /// 0223 /// \return 0224 /// A reference to this class so multiple things can be streamed 0225 /// in one statement. 0226 Stream &operator<<(char ch); 0227 0228 Stream &operator<<(uint8_t uval) = delete; 0229 Stream &operator<<(uint16_t uval) = delete; 0230 Stream &operator<<(uint32_t uval) = delete; 0231 Stream &operator<<(uint64_t uval) = delete; 0232 Stream &operator<<(int8_t sval) = delete; 0233 Stream &operator<<(int16_t sval) = delete; 0234 Stream &operator<<(int32_t sval) = delete; 0235 Stream &operator<<(int64_t sval) = delete; 0236 0237 /// Output a C string to the stream. 0238 /// 0239 /// Print a C string \a cstr to the stream. 0240 /// 0241 /// \param[in] cstr 0242 /// The string to be output to the stream. 0243 size_t PutCString(llvm::StringRef cstr); 0244 0245 /// Output a C string to the stream with color highlighting. 0246 /// 0247 /// Print a C string \a text to the stream, applying color highlighting to 0248 /// the portions of the string that match the regex pattern \a pattern. The 0249 /// pattern is matched as many times as possible throughout the string. If \a 0250 /// pattern is nullptr, then no highlighting is applied. 0251 /// 0252 /// The highlighting is applied by enclosing the matching text in ANSI color 0253 /// codes. The \a prefix parameter specifies the ANSI code to start the color 0254 /// (the standard value is assumed to be 'ansi.fg.red', representing red 0255 /// foreground), and the \a suffix parameter specifies the ANSI code to end 0256 /// the color (the standard value is assumed to be 'ansi.normal', resetting to 0257 /// default text style). These constants should be defined appropriately in 0258 /// your environment. 0259 /// 0260 /// \param[in] text 0261 /// The string to be output to the stream. 0262 /// 0263 /// \param[in] pattern 0264 /// The regex pattern to match against the \a text string. Portions of \a 0265 /// text matching this pattern will be colorized. If this parameter is 0266 /// nullptr, highlighting is not performed. 0267 /// \param[in] prefix 0268 /// The ANSI color code to start colorization. This is 0269 /// environment-dependent. 0270 /// \param[in] suffix 0271 /// The ANSI color code to end colorization. This is 0272 /// environment-dependent. 0273 0274 void PutCStringColorHighlighted( 0275 llvm::StringRef text, 0276 std::optional<HighlightSettings> settings = std::nullopt); 0277 0278 /// Output and End of Line character to the stream. 0279 size_t EOL(); 0280 0281 /// Get the address size in bytes. 0282 /// 0283 /// \return 0284 /// The size of an address in bytes that is used when outputting 0285 /// address and pointer values to the stream. 0286 uint32_t GetAddressByteSize() const; 0287 0288 /// The flags accessor. 0289 /// 0290 /// \return 0291 /// A reference to the Flags member variable. 0292 Flags &GetFlags(); 0293 0294 /// The flags const accessor. 0295 /// 0296 /// \return 0297 /// A const reference to the Flags member variable. 0298 const Flags &GetFlags() const; 0299 0300 //// The byte order accessor. 0301 //// 0302 //// \return 0303 //// The byte order. 0304 lldb::ByteOrder GetByteOrder() const; 0305 0306 /// Get the current indentation level. 0307 /// 0308 /// \return 0309 /// The current indentation level. 0310 unsigned GetIndentLevel() const; 0311 0312 /// Indent the current line in the stream. 0313 /// 0314 /// Indent the current line using the current indentation level and print an 0315 /// optional string following the indentation spaces. 0316 /// 0317 /// \param[in] s 0318 /// A string to print following the indentation. 0319 size_t Indent(llvm::StringRef s = ""); 0320 0321 /// Decrement the current indentation level. 0322 void IndentLess(unsigned amount = 2); 0323 0324 /// Increment the current indentation level. 0325 void IndentMore(unsigned amount = 2); 0326 0327 /// Output an offset value. 0328 /// 0329 /// Put an offset \a uval out to the stream using the printf format in \a 0330 /// format. 0331 /// 0332 /// \param[in] offset 0333 /// The offset value. 0334 /// 0335 /// \param[in] format 0336 /// The printf style format to use when outputting the offset. 0337 void Offset(uint32_t offset, const char *format = "0x%8.8x: "); 0338 0339 /// Output printf formatted output to the stream. 0340 /// 0341 /// Print some formatted output to the stream. 0342 /// 0343 /// \param[in] format 0344 /// A printf style format string. 0345 /// 0346 /// \param[in] ... 0347 /// Variable arguments that are needed for the printf style 0348 /// format string \a format. 0349 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 0350 0351 size_t PrintfVarArg(const char *format, va_list args); 0352 0353 template <typename... Args> void Format(const char *format, Args &&... args) { 0354 PutCString(llvm::formatv(format, std::forward<Args>(args)...).str()); 0355 } 0356 0357 /// Output a quoted C string value to the stream. 0358 /// 0359 /// Print a double quoted NULL terminated C string to the stream using the 0360 /// printf format in \a format. 0361 /// 0362 /// \param[in] cstr 0363 /// A NULL terminated C string value. 0364 /// 0365 /// \param[in] format 0366 /// The optional C string format that can be overridden. 0367 void QuotedCString(const char *cstr, const char *format = "\"%s\""); 0368 0369 /// Set the address size in bytes. 0370 /// 0371 /// \param[in] addr_size 0372 /// The new size in bytes of an address to use when outputting 0373 /// address and pointer values. 0374 void SetAddressByteSize(uint32_t addr_size); 0375 0376 /// Set the current indentation level. 0377 /// 0378 /// \param[in] level 0379 /// The new indentation level. 0380 void SetIndentLevel(unsigned level); 0381 0382 /// Output a SLEB128 number to the stream. 0383 /// 0384 /// Put an SLEB128 \a uval out to the stream using the printf format in \a 0385 /// format. 0386 /// 0387 /// \param[in] uval 0388 /// A uint64_t value that was extracted as a SLEB128 value. 0389 size_t PutSLEB128(int64_t uval); 0390 0391 /// Output a ULEB128 number to the stream. 0392 /// 0393 /// Put an ULEB128 \a uval out to the stream using the printf format in \a 0394 /// format. 0395 /// 0396 /// \param[in] uval 0397 /// A uint64_t value that was extracted as a ULEB128 value. 0398 size_t PutULEB128(uint64_t uval); 0399 0400 /// Returns a raw_ostream that forwards the data to this Stream object. 0401 llvm::raw_ostream &AsRawOstream() { 0402 return m_forwarder; 0403 } 0404 0405 protected: 0406 // Member variables 0407 Flags m_flags; ///< Dump flags. 0408 uint32_t m_addr_size = 4; ///< Size of an address in bytes. 0409 lldb::ByteOrder 0410 m_byte_order; ///< Byte order to use when encoding scalar types. 0411 unsigned m_indent_level = 0; ///< Indention level. 0412 std::size_t m_bytes_written = 0; ///< Number of bytes written so far. 0413 0414 void _PutHex8(uint8_t uvalue, bool add_prefix); 0415 0416 /// Output character bytes to the stream. 0417 /// 0418 /// Appends \a src_len characters from the buffer \a src to the stream. 0419 /// 0420 /// \param[in] src 0421 /// A buffer containing at least \a src_len bytes of data. 0422 /// 0423 /// \param[in] src_len 0424 /// A number of bytes to append to the stream. 0425 /// 0426 /// \return 0427 /// The number of bytes that were appended to the stream. 0428 virtual size_t WriteImpl(const void *src, size_t src_len) = 0; 0429 0430 /// \class RawOstreamForward Stream.h "lldb/Utility/Stream.h" 0431 /// This is a wrapper class that exposes a raw_ostream interface that just 0432 /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take 0433 /// a raw_ostream within the LLDB code base. 0434 class RawOstreamForward : public llvm::raw_ostream { 0435 // Note: This stream must *not* maintain its own buffer, but instead 0436 // directly write everything to the internal Stream class. Without this, 0437 // we would run into the problem that the Stream written byte count would 0438 // differ from the actually written bytes by the size of the internal 0439 // raw_ostream buffer. 0440 0441 Stream &m_target; 0442 void write_impl(const char *Ptr, size_t Size) override { 0443 m_target.Write(Ptr, Size); 0444 } 0445 0446 uint64_t current_pos() const override { 0447 return m_target.GetWrittenBytes(); 0448 } 0449 0450 public: 0451 RawOstreamForward(Stream &target, bool colors = false) 0452 : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) { 0453 enable_colors(colors); 0454 } 0455 }; 0456 RawOstreamForward m_forwarder; 0457 }; 0458 0459 /// Output an address value to this stream. 0460 /// 0461 /// Put an address \a addr out to the stream with optional \a prefix and \a 0462 /// suffix strings. 0463 /// 0464 /// \param[in] s 0465 /// The output stream. 0466 /// 0467 /// \param[in] addr 0468 /// An address value. 0469 /// 0470 /// \param[in] addr_size 0471 /// Size in bytes of the address, used for formatting. 0472 /// 0473 /// \param[in] prefix 0474 /// A prefix C string. If nullptr, no prefix will be output. 0475 /// 0476 /// \param[in] suffix 0477 /// A suffix C string. If nullptr, no suffix will be output. 0478 void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, 0479 const char *prefix = nullptr, const char *suffix = nullptr); 0480 0481 /// Output an address range to this stream. 0482 /// 0483 /// Put an address range \a lo_addr - \a hi_addr out to the stream with 0484 /// optional \a prefix and \a suffix strings. 0485 /// 0486 /// \param[in] s 0487 /// The output stream. 0488 /// 0489 /// \param[in] lo_addr 0490 /// The start address of the address range. 0491 /// 0492 /// \param[in] hi_addr 0493 /// The end address of the address range. 0494 /// 0495 /// \param[in] addr_size 0496 /// Size in bytes of the address, used for formatting. 0497 /// 0498 /// \param[in] prefix 0499 /// A prefix C string. If nullptr, no prefix will be output. 0500 /// 0501 /// \param[in] suffix 0502 /// A suffix C string. If nullptr, no suffix will be output. 0503 void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr, 0504 uint32_t addr_size, const char *prefix = nullptr, 0505 const char *suffix = nullptr); 0506 0507 } // namespace lldb_private 0508 0509 #endif // LLDB_UTILITY_STREAM_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|