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