1//===-- Stream.h ------------------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_UTILITY_STREAM_H
10#define LLDB_UTILITY_STREAM_H
11
12#include "lldb/Utility/Flags.h"
13#include "lldb/lldb-defines.h"
14#include "lldb/lldb-enumerations.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/FormatVariadic.h"
17#include "llvm/Support/raw_ostream.h"
18
19#include <cstdarg>
20#include <cstddef>
21#include <cstdint>
22#include <type_traits>
23
24namespace lldb_private {
25
26/// \class Stream Stream.h "lldb/Utility/Stream.h"
27/// A stream class that can stream formatted output to a file.
28class Stream {
29public:
30  /// \a m_flags bit values.
31  enum {
32    eBinary = (1 << 0) ///< Get and put data as binary instead of as the default
33                       /// string mode.
34  };
35
36  /// Struct to store information for color highlighting in the stream.
37  struct HighlightSettings {
38    llvm::StringRef pattern; ///< Regex pattern for highlighting.
39    llvm::StringRef prefix;  ///< ANSI color code to start colorization.
40    llvm::StringRef suffix;  ///< ANSI color code to end colorization.
41
42    HighlightSettings(llvm::StringRef p, llvm::StringRef pre,
43                      llvm::StringRef suf)
44        : pattern(p), prefix(pre), suffix(suf) {}
45  };
46
47  /// Utility class for counting the bytes that were written to a stream in a
48  /// certain time span.
49  ///
50  /// \example
51  ///   ByteDelta delta(*this);
52  ///   WriteDataToStream("foo");
53  ///   return *delta;
54  class ByteDelta {
55    Stream *m_stream;
56    /// Bytes we have written so far when ByteDelta was created.
57    size_t m_start;
58
59  public:
60    ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {}
61    /// Returns the number of bytes written to the given Stream since this
62    /// ByteDelta object was created.
63    size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; }
64  };
65
66  /// Construct with flags and address size and byte order.
67  ///
68  /// Construct with dump flags \a flags and the default address size. \a
69  /// flags can be any of the above enumeration logical OR'ed together.
70  Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order,
71         bool colors = false);
72
73  /// Construct a default Stream, not binary, host byte order and host addr
74  /// size.
75  ///
76  Stream(bool colors = false);
77
78  // FIXME: Streams should not be copyable.
79  Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; }
80
81  Stream &operator=(const Stream &rhs) {
82    m_flags = rhs.m_flags;
83    m_addr_size = rhs.m_addr_size;
84    m_byte_order = rhs.m_byte_order;
85    m_indent_level = rhs.m_indent_level;
86    return *this;
87  }
88
89  /// Destructor
90  virtual ~Stream();
91
92  // Subclasses must override these methods
93
94  /// Flush the stream.
95  ///
96  /// Subclasses should flush the stream to make any output appear if the
97  /// stream has any buffering.
98  virtual void Flush() = 0;
99
100  /// Output character bytes to the stream.
101  ///
102  /// Appends \a src_len characters from the buffer \a src to the stream.
103  ///
104  /// \param[in] src
105  ///     A buffer containing at least \a src_len bytes of data.
106  ///
107  /// \param[in] src_len
108  ///     A number of bytes to append to the stream.
109  ///
110  /// \return
111  ///     The number of bytes that were appended to the stream.
112  size_t Write(const void *src, size_t src_len) {
113    size_t appended_byte_count = WriteImpl(src, src_len);
114    m_bytes_written += appended_byte_count;
115    return appended_byte_count;
116  }
117
118  size_t GetWrittenBytes() const { return m_bytes_written; }
119
120  // Member functions
121  size_t PutChar(char ch);
122
123  /// Set the byte_order value.
124  ///
125  /// Sets the byte order of the data to extract. Extracted values will be
126  /// swapped if necessary when decoding.
127  ///
128  /// \param[in] byte_order
129  ///     The byte order value to use when extracting data.
130  ///
131  /// \return
132  ///     The old byte order value.
133  lldb::ByteOrder SetByteOrder(lldb::ByteOrder byte_order);
134
135  /// Format a C string from a printf style format and variable arguments and
136  /// encode and append the resulting C string as hex bytes.
137  ///
138  /// \param[in] format
139  ///     A printf style format string.
140  ///
141  /// \param[in] ...
142  ///     Any additional arguments needed for the printf format string.
143  ///
144  /// \return
145  ///     The number of bytes that were appended to the stream.
146  size_t PrintfAsRawHex8(const char *format, ...)
147      __attribute__((__format__(__printf__, 2, 3)));
148
149  /// Append an uint8_t value in the hexadecimal format to the stream.
150  ///
151  /// \param[in] uvalue
152  ///     The value to append.
153  ///
154  /// \return
155  ///     The number of bytes that were appended to the stream.
156  size_t PutHex8(uint8_t uvalue);
157
158  size_t PutNHex8(size_t n, uint8_t uvalue);
159
160  size_t PutHex16(uint16_t uvalue,
161                  lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
162
163  size_t PutHex32(uint32_t uvalue,
164                  lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
165
166  size_t PutHex64(uint64_t uvalue,
167                  lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
168
169  size_t PutMaxHex64(uint64_t uvalue, size_t byte_size,
170                     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
171  size_t PutFloat(float f,
172                  lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
173
174  size_t PutDouble(double d,
175                   lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
176
177  size_t PutLongDouble(long double ld,
178                       lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
179
180  size_t PutPointer(void *ptr);
181
182  // Append \a src_len bytes from \a src to the stream as hex characters (two
183  // ascii characters per byte of input data)
184  size_t
185  PutBytesAsRawHex8(const void *src, size_t src_len,
186                    lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
187                    lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
188
189  // Append \a src_len bytes from \a s to the stream as binary data.
190  size_t PutRawBytes(const void *s, size_t src_len,
191                     lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
192                     lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
193
194  size_t PutStringAsRawHex8(llvm::StringRef s);
195
196  /// Output a NULL terminated C string \a cstr to the stream \a s.
197  ///
198  /// \param[in] cstr
199  ///     A NULL terminated C string.
200  ///
201  /// \return
202  ///     A reference to this class so multiple things can be streamed
203  ///     in one statement.
204  Stream &operator<<(const char *cstr);
205
206  Stream &operator<<(llvm::StringRef str);
207
208  /// Output a pointer value \a p to the stream \a s.
209  ///
210  /// \param[in] p
211  ///     A void pointer.
212  ///
213  /// \return
214  ///     A reference to this class so multiple things can be streamed
215  ///     in one statement.
216  Stream &operator<<(const void *p);
217
218  /// Output a character \a ch to the stream \a s.
219  ///
220  /// \param[in] ch
221  ///     A printable character value.
222  ///
223  /// \return
224  ///     A reference to this class so multiple things can be streamed
225  ///     in one statement.
226  Stream &operator<<(char ch);
227
228  Stream &operator<<(uint8_t uval) = delete;
229  Stream &operator<<(uint16_t uval) = delete;
230  Stream &operator<<(uint32_t uval) = delete;
231  Stream &operator<<(uint64_t uval) = delete;
232  Stream &operator<<(int8_t sval) = delete;
233  Stream &operator<<(int16_t sval) = delete;
234  Stream &operator<<(int32_t sval) = delete;
235  Stream &operator<<(int64_t sval) = delete;
236
237  /// Output a C string to the stream.
238  ///
239  /// Print a C string \a cstr to the stream.
240  ///
241  /// \param[in] cstr
242  ///     The string to be output to the stream.
243  size_t PutCString(llvm::StringRef cstr);
244
245  /// Output a C string to the stream with color highlighting.
246  ///
247  /// Print a C string \a text to the stream, applying color highlighting to
248  /// the portions of the string that match the regex pattern \a pattern. The
249  /// pattern is matched as many times as possible throughout the string. If \a
250  /// pattern is nullptr, then no highlighting is applied.
251  ///
252  /// The highlighting is applied by enclosing the matching text in ANSI color
253  /// codes. The \a prefix parameter specifies the ANSI code to start the color
254  /// (the standard value is assumed to be 'ansi.fg.red', representing red
255  /// foreground), and the \a suffix parameter specifies the ANSI code to end
256  /// the color (the standard value is assumed to be 'ansi.normal', resetting to
257  /// default text style). These constants should be defined appropriately in
258  /// your environment.
259  ///
260  /// \param[in] text
261  ///     The string to be output to the stream.
262  ///
263  /// \param[in] pattern
264  ///     The regex pattern to match against the \a text string. Portions of \a
265  ///     text matching this pattern will be colorized. If this parameter is
266  ///     nullptr, highlighting is not performed.
267  /// \param[in] prefix
268  ///     The ANSI color code to start colorization. This is
269  ///     environment-dependent.
270  /// \param[in] suffix
271  ///     The ANSI color code to end colorization. This is
272  ///     environment-dependent.
273
274  void PutCStringColorHighlighted(
275      llvm::StringRef text,
276      std::optional<HighlightSettings> settings = std::nullopt);
277
278  /// Output and End of Line character to the stream.
279  size_t EOL();
280
281  /// Get the address size in bytes.
282  ///
283  /// \return
284  ///     The size of an address in bytes that is used when outputting
285  ///     address and pointer values to the stream.
286  uint32_t GetAddressByteSize() const;
287
288  /// The flags accessor.
289  ///
290  /// \return
291  ///     A reference to the Flags member variable.
292  Flags &GetFlags();
293
294  /// The flags const accessor.
295  ///
296  /// \return
297  ///     A const reference to the Flags member variable.
298  const Flags &GetFlags() const;
299
300  //// The byte order accessor.
301  ////
302  //// \return
303  ////     The byte order.
304  lldb::ByteOrder GetByteOrder() const;
305
306  /// Get the current indentation level.
307  ///
308  /// \return
309  ///     The current indentation level.
310  unsigned GetIndentLevel() const;
311
312  /// Indent the current line in the stream.
313  ///
314  /// Indent the current line using the current indentation level and print an
315  /// optional string following the indentation spaces.
316  ///
317  /// \param[in] s
318  ///     A string to print following the indentation.
319  size_t Indent(llvm::StringRef s = "");
320
321  /// Decrement the current indentation level.
322  void IndentLess(unsigned amount = 2);
323
324  /// Increment the current indentation level.
325  void IndentMore(unsigned amount = 2);
326
327  /// Output an offset value.
328  ///
329  /// Put an offset \a uval out to the stream using the printf format in \a
330  /// format.
331  ///
332  /// \param[in] offset
333  ///     The offset value.
334  ///
335  /// \param[in] format
336  ///     The printf style format to use when outputting the offset.
337  void Offset(uint32_t offset, const char *format = "0x%8.8x: ");
338
339  /// Output printf formatted output to the stream.
340  ///
341  /// Print some formatted output to the stream.
342  ///
343  /// \param[in] format
344  ///     A printf style format string.
345  ///
346  /// \param[in] ...
347  ///     Variable arguments that are needed for the printf style
348  ///     format string \a format.
349  size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
350
351  size_t PrintfVarArg(const char *format, va_list args);
352
353  template <typename... Args> void Format(const char *format, Args &&... args) {
354    PutCString(llvm::formatv(format, std::forward<Args>(args)...).str());
355  }
356
357  /// Output a quoted C string value to the stream.
358  ///
359  /// Print a double quoted NULL terminated C string to the stream using the
360  /// printf format in \a format.
361  ///
362  /// \param[in] cstr
363  ///     A NULL terminated C string value.
364  ///
365  /// \param[in] format
366  ///     The optional C string format that can be overridden.
367  void QuotedCString(const char *cstr, const char *format = "\"%s\"");
368
369  /// Set the address size in bytes.
370  ///
371  /// \param[in] addr_size
372  ///     The new size in bytes of an address to use when outputting
373  ///     address and pointer values.
374  void SetAddressByteSize(uint32_t addr_size);
375
376  /// Set the current indentation level.
377  ///
378  /// \param[in] level
379  ///     The new indentation level.
380  void SetIndentLevel(unsigned level);
381
382  /// Output a SLEB128 number to the stream.
383  ///
384  /// Put an SLEB128 \a uval out to the stream using the printf format in \a
385  /// format.
386  ///
387  /// \param[in] uval
388  ///     A uint64_t value that was extracted as a SLEB128 value.
389  size_t PutSLEB128(int64_t uval);
390
391  /// Output a ULEB128 number to the stream.
392  ///
393  /// Put an ULEB128 \a uval out to the stream using the printf format in \a
394  /// format.
395  ///
396  /// \param[in] uval
397  ///     A uint64_t value that was extracted as a ULEB128 value.
398  size_t PutULEB128(uint64_t uval);
399
400  /// Returns a raw_ostream that forwards the data to this Stream object.
401  llvm::raw_ostream &AsRawOstream() {
402    return m_forwarder;
403  }
404
405protected:
406  // Member variables
407  Flags m_flags;        ///< Dump flags.
408  uint32_t m_addr_size = 4; ///< Size of an address in bytes.
409  lldb::ByteOrder
410      m_byte_order;   ///< Byte order to use when encoding scalar types.
411  unsigned m_indent_level = 0;     ///< Indention level.
412  std::size_t m_bytes_written = 0; ///< Number of bytes written so far.
413
414  void _PutHex8(uint8_t uvalue, bool add_prefix);
415
416  /// Output character bytes to the stream.
417  ///
418  /// Appends \a src_len characters from the buffer \a src to the stream.
419  ///
420  /// \param[in] src
421  ///     A buffer containing at least \a src_len bytes of data.
422  ///
423  /// \param[in] src_len
424  ///     A number of bytes to append to the stream.
425  ///
426  /// \return
427  ///     The number of bytes that were appended to the stream.
428  virtual size_t WriteImpl(const void *src, size_t src_len) = 0;
429
430  /// \class RawOstreamForward Stream.h "lldb/Utility/Stream.h"
431  /// This is a wrapper class that exposes a raw_ostream interface that just
432  /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take
433  /// a raw_ostream within the LLDB code base.
434  class RawOstreamForward : public llvm::raw_ostream {
435    // Note: This stream must *not* maintain its own buffer, but instead
436    // directly write everything to the internal Stream class. Without this,
437    // we would run into the problem that the Stream written byte count would
438    // differ from the actually written bytes by the size of the internal
439    // raw_ostream buffer.
440
441    Stream &m_target;
442    void write_impl(const char *Ptr, size_t Size) override {
443      m_target.Write(Ptr, Size);
444    }
445
446    uint64_t current_pos() const override {
447      return m_target.GetWrittenBytes();
448    }
449
450  public:
451    RawOstreamForward(Stream &target, bool colors = false)
452        : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {
453      enable_colors(colors);
454    }
455  };
456  RawOstreamForward m_forwarder;
457};
458
459/// Output an address value to this stream.
460///
461/// Put an address \a addr out to the stream with optional \a prefix and \a
462/// suffix strings.
463///
464/// \param[in] s
465///     The output stream.
466///
467/// \param[in] addr
468///     An address value.
469///
470/// \param[in] addr_size
471///     Size in bytes of the address, used for formatting.
472///
473/// \param[in] prefix
474///     A prefix C string. If nullptr, no prefix will be output.
475///
476/// \param[in] suffix
477///     A suffix C string. If nullptr, no suffix will be output.
478void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size,
479                 const char *prefix = nullptr, const char *suffix = nullptr);
480
481/// Output an address range to this stream.
482///
483/// Put an address range \a lo_addr - \a hi_addr out to the stream with
484/// optional \a prefix and \a suffix strings.
485///
486/// \param[in] s
487///     The output stream.
488///
489/// \param[in] lo_addr
490///     The start address of the address range.
491///
492/// \param[in] hi_addr
493///     The end address of the address range.
494///
495/// \param[in] addr_size
496///     Size in bytes of the address, used for formatting.
497///
498/// \param[in] prefix
499///     A prefix C string. If nullptr, no prefix will be output.
500///
501/// \param[in] suffix
502///     A suffix C string. If nullptr, no suffix will be output.
503void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr,
504                      uint32_t addr_size, const char *prefix = nullptr,
505                      const char *suffix = nullptr);
506
507} // namespace lldb_private
508
509#endif // LLDB_UTILITY_STREAM_H
510