| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- //===-- Stream.h ------------------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLDB_UTILITY_STREAM_H
- #define LLDB_UTILITY_STREAM_H
- #include "lldb/Utility/Flags.h"
- #include "lldb/lldb-defines.h"
- #include "lldb/lldb-enumerations.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Support/FormatVariadic.h"
- #include "llvm/Support/raw_ostream.h"
- #include <cstdarg>
- #include <cstddef>
- #include <cstdint>
- #include <type_traits>
- namespace lldb_private {
- /// \class Stream Stream.h "lldb/Utility/Stream.h"
- /// A stream class that can stream formatted output to a file.
- class Stream {
- public:
- /// \a m_flags bit values.
- enum {
- eBinary = (1 << 0) ///< Get and put data as binary instead of as the default
- /// string mode.
- };
- /// Utility class for counting the bytes that were written to a stream in a
- /// certain time span.
- ///
- /// \example
- /// ByteDelta delta(*this);
- /// WriteDataToStream("foo");
- /// return *delta;
- class ByteDelta {
- Stream *m_stream;
- /// Bytes we have written so far when ByteDelta was created.
- size_t m_start;
- public:
- ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {}
- /// Returns the number of bytes written to the given Stream since this
- /// ByteDelta object was created.
- size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; }
- };
- /// Construct with flags and address size and byte order.
- ///
- /// Construct with dump flags \a flags and the default address size. \a
- /// flags can be any of the above enumeration logical OR'ed together.
- Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order,
- bool colors = false);
- /// Construct a default Stream, not binary, host byte order and host addr
- /// size.
- ///
- Stream(bool colors = false);
- // FIXME: Streams should not be copyable.
- Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; }
- Stream &operator=(const Stream &rhs) {
- m_flags = rhs.m_flags;
- m_addr_size = rhs.m_addr_size;
- m_byte_order = rhs.m_byte_order;
- m_indent_level = rhs.m_indent_level;
- return *this;
- }
- /// Destructor
- virtual ~Stream();
- // Subclasses must override these methods
- /// Flush the stream.
- ///
- /// Subclasses should flush the stream to make any output appear if the
- /// stream has any buffering.
- virtual void Flush() = 0;
- /// Output character bytes to the stream.
- ///
- /// Appends \a src_len characters from the buffer \a src to the stream.
- ///
- /// \param[in] src
- /// A buffer containing at least \a src_len bytes of data.
- ///
- /// \param[in] src_len
- /// A number of bytes to append to the stream.
- ///
- /// \return
- /// The number of bytes that were appended to the stream.
- size_t Write(const void *src, size_t src_len) {
- size_t appended_byte_count = WriteImpl(src, src_len);
- m_bytes_written += appended_byte_count;
- return appended_byte_count;
- }
- size_t GetWrittenBytes() const { return m_bytes_written; }
- // Member functions
- size_t PutChar(char ch);
- /// Set the byte_order value.
- ///
- /// Sets the byte order of the data to extract. Extracted values will be
- /// swapped if necessary when decoding.
- ///
- /// \param[in] byte_order
- /// The byte order value to use when extracting data.
- ///
- /// \return
- /// The old byte order value.
- lldb::ByteOrder SetByteOrder(lldb::ByteOrder byte_order);
- /// Format a C string from a printf style format and variable arguments and
- /// encode and append the resulting C string as hex bytes.
- ///
- /// \param[in] format
- /// A printf style format string.
- ///
- /// \param[in] ...
- /// Any additional arguments needed for the printf format string.
- ///
- /// \return
- /// The number of bytes that were appended to the stream.
- size_t PrintfAsRawHex8(const char *format, ...)
- __attribute__((__format__(__printf__, 2, 3)));
- /// Append an uint8_t value in the hexadecimal format to the stream.
- ///
- /// \param[in] uvalue
- /// The value to append.
- ///
- /// \return
- /// The number of bytes that were appended to the stream.
- size_t PutHex8(uint8_t uvalue);
- size_t PutNHex8(size_t n, uint8_t uvalue);
- size_t PutHex16(uint16_t uvalue,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutHex32(uint32_t uvalue,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutHex64(uint64_t uvalue,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutMaxHex64(uint64_t uvalue, size_t byte_size,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutFloat(float f,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutDouble(double d,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutLongDouble(long double ld,
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- size_t PutPointer(void *ptr);
- // Append \a src_len bytes from \a src to the stream as hex characters (two
- // ascii characters per byte of input data)
- size_t
- PutBytesAsRawHex8(const void *src, size_t src_len,
- lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
- lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
- // Append \a src_len bytes from \a s to the stream as binary data.
- size_t PutRawBytes(const void *s, size_t src_len,
- lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
- lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
- size_t PutStringAsRawHex8(llvm::StringRef s);
- /// Output a NULL terminated C string \a cstr to the stream \a s.
- ///
- /// \param[in] cstr
- /// A NULL terminated C string.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(const char *cstr);
- Stream &operator<<(llvm::StringRef str);
- /// Output a pointer value \a p to the stream \a s.
- ///
- /// \param[in] p
- /// A void pointer.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(const void *p);
- /// Output a character \a ch to the stream \a s.
- ///
- /// \param[in] ch
- /// A printable character value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(char ch);
- Stream &operator<<(uint8_t uval) = delete;
- Stream &operator<<(uint16_t uval) = delete;
- Stream &operator<<(uint32_t uval) = delete;
- Stream &operator<<(uint64_t uval) = delete;
- Stream &operator<<(int8_t sval) = delete;
- Stream &operator<<(int16_t sval) = delete;
- Stream &operator<<(int32_t sval) = delete;
- Stream &operator<<(int64_t sval) = delete;
- /// Output a C string to the stream.
- ///
- /// Print a C string \a cstr to the stream.
- ///
- /// \param[in] cstr
- /// The string to be output to the stream.
- size_t PutCString(llvm::StringRef cstr);
- /// Output and End of Line character to the stream.
- size_t EOL();
- /// Get the address size in bytes.
- ///
- /// \return
- /// The size of an address in bytes that is used when outputting
- /// address and pointer values to the stream.
- uint32_t GetAddressByteSize() const;
- /// The flags accessor.
- ///
- /// \return
- /// A reference to the Flags member variable.
- Flags &GetFlags();
- /// The flags const accessor.
- ///
- /// \return
- /// A const reference to the Flags member variable.
- const Flags &GetFlags() const;
- //// The byte order accessor.
- ////
- //// \return
- //// The byte order.
- lldb::ByteOrder GetByteOrder() const;
- /// Get the current indentation level.
- ///
- /// \return
- /// The current indentation level.
- unsigned GetIndentLevel() const;
- /// Indent the current line in the stream.
- ///
- /// Indent the current line using the current indentation level and print an
- /// optional string following the indentation spaces.
- ///
- /// \param[in] s
- /// A string to print following the indentation.
- size_t Indent(llvm::StringRef s = "");
- /// Decrement the current indentation level.
- void IndentLess(unsigned amount = 2);
- /// Increment the current indentation level.
- void IndentMore(unsigned amount = 2);
- /// Output an offset value.
- ///
- /// Put an offset \a uval out to the stream using the printf format in \a
- /// format.
- ///
- /// \param[in] offset
- /// The offset value.
- ///
- /// \param[in] format
- /// The printf style format to use when outputting the offset.
- void Offset(uint32_t offset, const char *format = "0x%8.8x: ");
- /// Output printf formatted output to the stream.
- ///
- /// Print some formatted output to the stream.
- ///
- /// \param[in] format
- /// A printf style format string.
- ///
- /// \param[in] ...
- /// Variable arguments that are needed for the printf style
- /// format string \a format.
- size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
- size_t PrintfVarArg(const char *format, va_list args);
- template <typename... Args> void Format(const char *format, Args &&... args) {
- PutCString(llvm::formatv(format, std::forward<Args>(args)...).str());
- }
- /// Output a quoted C string value to the stream.
- ///
- /// Print a double quoted NULL terminated C string to the stream using the
- /// printf format in \a format.
- ///
- /// \param[in] cstr
- /// A NULL terminated C string value.
- ///
- /// \param[in] format
- /// The optional C string format that can be overridden.
- void QuotedCString(const char *cstr, const char *format = "\"%s\"");
- /// Set the address size in bytes.
- ///
- /// \param[in] addr_size
- /// The new size in bytes of an address to use when outputting
- /// address and pointer values.
- void SetAddressByteSize(uint32_t addr_size);
- /// Set the current indentation level.
- ///
- /// \param[in] level
- /// The new indentation level.
- void SetIndentLevel(unsigned level);
- /// Output a SLEB128 number to the stream.
- ///
- /// Put an SLEB128 \a uval out to the stream using the printf format in \a
- /// format.
- ///
- /// \param[in] uval
- /// A uint64_t value that was extracted as a SLEB128 value.
- size_t PutSLEB128(int64_t uval);
- /// Output a ULEB128 number to the stream.
- ///
- /// Put an ULEB128 \a uval out to the stream using the printf format in \a
- /// format.
- ///
- /// \param[in] uval
- /// A uint64_t value that was extracted as a ULEB128 value.
- size_t PutULEB128(uint64_t uval);
- /// Returns a raw_ostream that forwards the data to this Stream object.
- llvm::raw_ostream &AsRawOstream() {
- return m_forwarder;
- }
- protected:
- // Member variables
- Flags m_flags; ///< Dump flags.
- uint32_t m_addr_size; ///< Size of an address in bytes.
- lldb::ByteOrder
- m_byte_order; ///< Byte order to use when encoding scalar types.
- unsigned m_indent_level; ///< Indention level.
- std::size_t m_bytes_written = 0; ///< Number of bytes written so far.
- void _PutHex8(uint8_t uvalue, bool add_prefix);
- /// Output character bytes to the stream.
- ///
- /// Appends \a src_len characters from the buffer \a src to the stream.
- ///
- /// \param[in] src
- /// A buffer containing at least \a src_len bytes of data.
- ///
- /// \param[in] src_len
- /// A number of bytes to append to the stream.
- ///
- /// \return
- /// The number of bytes that were appended to the stream.
- virtual size_t WriteImpl(const void *src, size_t src_len) = 0;
- /// \class RawOstreamForward Stream.h "lldb/Utility/Stream.h"
- /// This is a wrapper class that exposes a raw_ostream interface that just
- /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take
- /// a raw_ostream within the LLDB code base.
- class RawOstreamForward : public llvm::raw_ostream {
- // Note: This stream must *not* maintain its own buffer, but instead
- // directly write everything to the internal Stream class. Without this,
- // we would run into the problem that the Stream written byte count would
- // differ from the actually written bytes by the size of the internal
- // raw_ostream buffer.
- Stream &m_target;
- void write_impl(const char *Ptr, size_t Size) override {
- m_target.Write(Ptr, Size);
- }
- uint64_t current_pos() const override {
- return m_target.GetWrittenBytes();
- }
- public:
- RawOstreamForward(Stream &target, bool colors = false)
- : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {
- enable_colors(colors);
- }
- };
- RawOstreamForward m_forwarder;
- };
- /// Output an address value to this stream.
- ///
- /// Put an address \a addr out to the stream with optional \a prefix and \a
- /// suffix strings.
- ///
- /// \param[in] s
- /// The output stream.
- ///
- /// \param[in] addr
- /// An address value.
- ///
- /// \param[in] addr_size
- /// Size in bytes of the address, used for formatting.
- ///
- /// \param[in] prefix
- /// A prefix C string. If nullptr, no prefix will be output.
- ///
- /// \param[in] suffix
- /// A suffix C string. If nullptr, no suffix will be output.
- void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size,
- const char *prefix = nullptr, const char *suffix = nullptr);
- /// Output an address range to this stream.
- ///
- /// Put an address range \a lo_addr - \a hi_addr out to the stream with
- /// optional \a prefix and \a suffix strings.
- ///
- /// \param[in] s
- /// The output stream.
- ///
- /// \param[in] lo_addr
- /// The start address of the address range.
- ///
- /// \param[in] hi_addr
- /// The end address of the address range.
- ///
- /// \param[in] addr_size
- /// Size in bytes of the address, used for formatting.
- ///
- /// \param[in] prefix
- /// A prefix C string. If nullptr, no prefix will be output.
- ///
- /// \param[in] suffix
- /// A suffix C string. If nullptr, no suffix will be output.
- void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr,
- uint32_t addr_size, const char *prefix = nullptr,
- const char *suffix = nullptr);
- } // namespace lldb_private
- #endif // LLDB_UTILITY_STREAM_H
|