WPILibC++  2020.3.2
raw_ostream.h
1 //===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the raw_ostream class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef WPIUTIL_WPI_RAW_OSTREAM_H
15 #define WPIUTIL_WPI_RAW_OSTREAM_H
16 
17 #include "wpi/ArrayRef.h"
18 #include "wpi/SmallVector.h"
19 #include "wpi/StringRef.h"
20 #include <cassert>
21 #include <cstddef>
22 #include <cstdint>
23 #include <cstring>
24 #include <string>
25 #include <vector>
26 #include <system_error>
27 
28 namespace wpi {
29 
30 class format_object_base;
31 class FormattedString;
32 class FormattedNumber;
33 class FormattedBytes;
34 
35 namespace sys {
36 namespace fs {
37 enum FileAccess : unsigned;
38 enum OpenFlags : unsigned;
39 enum CreationDisposition : unsigned;
40 } // end namespace fs
41 } // end namespace sys
42 
47 class raw_ostream {
48 private:
67  char *OutBufStart, *OutBufEnd, *OutBufCur;
68 
69  enum BufferKind {
70  Unbuffered = 0,
71  InternalBuffer,
72  ExternalBuffer
73  } BufferMode;
74 
75 public:
76  // color order matches ANSI escape sequence, don't change
77  enum Colors {
78  BLACK = 0,
79  RED,
80  GREEN,
81  YELLOW,
82  BLUE,
83  MAGENTA,
84  CYAN,
85  WHITE,
86  SAVEDCOLOR
87  };
88 
89  explicit raw_ostream(bool unbuffered = false)
90  : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
91  // Start out ready to flush.
92  OutBufStart = OutBufEnd = OutBufCur = nullptr;
93  }
94 
95  raw_ostream(const raw_ostream &) = delete;
96  void operator=(const raw_ostream &) = delete;
97 
98  virtual ~raw_ostream();
99 
101  uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
102 
103  //===--------------------------------------------------------------------===//
104  // Configuration Interface
105  //===--------------------------------------------------------------------===//
106 
109  void SetBuffered();
110 
112  void SetBufferSize(size_t Size) {
113  flush();
114  SetBufferAndMode(new char[Size], Size, InternalBuffer);
115  }
116 
117  size_t GetBufferSize() const {
118  // If we're supposed to be buffered but haven't actually gotten around
119  // to allocating the buffer yet, return the value that would be used.
120  if (BufferMode != Unbuffered && OutBufStart == nullptr)
121  return preferred_buffer_size();
122 
123  // Otherwise just return the size of the allocated buffer.
124  return OutBufEnd - OutBufStart;
125  }
126 
130  void SetUnbuffered() {
131  flush();
132  SetBufferAndMode(nullptr, 0, Unbuffered);
133  }
134 
135  size_t GetNumBytesInBuffer() const {
136  return OutBufCur - OutBufStart;
137  }
138 
139  //===--------------------------------------------------------------------===//
140  // Data Output Interface
141  //===--------------------------------------------------------------------===//
142 
143  void flush() {
144  if (OutBufCur != OutBufStart)
145  flush_nonempty();
146  }
147 
148  raw_ostream &operator<<(char C) {
149  if (OutBufCur >= OutBufEnd)
150  return write(C);
151  *OutBufCur++ = C;
152  return *this;
153  }
154 
155  raw_ostream &operator<<(unsigned char C) {
156  if (OutBufCur >= OutBufEnd)
157  return write(C);
158  *OutBufCur++ = C;
159  return *this;
160  }
161 
162  raw_ostream &operator<<(signed char C) {
163  if (OutBufCur >= OutBufEnd)
164  return write(C);
165  *OutBufCur++ = C;
166  return *this;
167  }
168 
169  raw_ostream &operator<<(ArrayRef<uint8_t> Arr) {
170  // Inline fast path, particularly for arrays with a known length.
171  size_t Size = Arr.size();
172 
173  // Make sure we can use the fast path.
174  if (Size > (size_t)(OutBufEnd - OutBufCur))
175  return write(Arr.data(), Size);
176 
177  if (Size) {
178  memcpy(OutBufCur, Arr.data(), Size);
179  OutBufCur += Size;
180  }
181  return *this;
182  }
183 
184  raw_ostream &operator<<(StringRef Str) {
185  // Inline fast path, particularly for strings with a known length.
186  size_t Size = Str.size();
187 
188  // Make sure we can use the fast path.
189  if (Size > (size_t)(OutBufEnd - OutBufCur))
190  return write(Str.data(), Size);
191 
192  if (Size) {
193  memcpy(OutBufCur, Str.data(), Size);
194  OutBufCur += Size;
195  }
196  return *this;
197  }
198 
199  raw_ostream &operator<<(const char *Str) {
200  // Inline fast path, particularly for constant strings where a sufficiently
201  // smart compiler will simplify strlen.
202 
203  return this->operator<<(StringRef(Str));
204  }
205 
206  raw_ostream &operator<<(const std::string &Str) {
207  // Avoid the fast path, it would only increase code size for a marginal win.
208  return write(Str.data(), Str.length());
209  }
210 
211  raw_ostream &operator<<(const SmallVectorImpl<char> &Str) {
212  return write(Str.data(), Str.size());
213  }
214 
215  raw_ostream &operator<<(const std::vector<uint8_t> &Arr) {
216  // Avoid the fast path, it would only increase code size for a marginal win.
217  return write(Arr.data(), Arr.size());
218  }
219 
220  raw_ostream &operator<<(const SmallVectorImpl<uint8_t> &Arr) {
221  return write(Arr.data(), Arr.size());
222  }
223 
224  raw_ostream &operator<<(unsigned long N);
225  raw_ostream &operator<<(long N);
226  raw_ostream &operator<<(unsigned long long N);
227  raw_ostream &operator<<(long long N);
228  raw_ostream &operator<<(const void *P);
229 
230  raw_ostream &operator<<(unsigned int N) {
231  return this->operator<<(static_cast<unsigned long>(N));
232  }
233 
234  raw_ostream &operator<<(int N) {
235  return this->operator<<(static_cast<long>(N));
236  }
237 
238  raw_ostream &operator<<(double N);
239 
241  raw_ostream &write_hex(unsigned long long N);
242 
245  raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
246 
247  raw_ostream &write(unsigned char C);
248  raw_ostream &write(const char *Ptr, size_t Size);
249  raw_ostream &write(const uint8_t *Ptr, size_t Size) {
250  return write(reinterpret_cast<const char *>(Ptr), Size);
251  }
252 
253  // Formatted output, see the format() function in Support/Format.h.
254  raw_ostream &operator<<(const format_object_base &Fmt);
255 
256  // Formatted output, see the leftJustify() function in Support/Format.h.
257  raw_ostream &operator<<(const FormattedString &);
258 
259  // Formatted output, see the formatHex() function in Support/Format.h.
260  raw_ostream &operator<<(const FormattedNumber &);
261 
262  // Formatted output, see the format_bytes() function in Support/Format.h.
263  raw_ostream &operator<<(const FormattedBytes &);
264 
266  raw_ostream &indent(unsigned NumSpaces);
267 
269  raw_ostream &write_zeros(unsigned NumZeros);
270 
278  virtual raw_ostream &changeColor(enum Colors Color,
279  bool Bold = false,
280  bool BG = false) {
281  (void)Color;
282  (void)Bold;
283  (void)BG;
284  return *this;
285  }
286 
289  virtual raw_ostream &resetColor() { return *this; }
290 
292  virtual raw_ostream &reverseColor() { return *this; }
293 
297  virtual bool is_displayed() const { return false; }
298 
300  virtual bool has_colors() const { return is_displayed(); }
301 
302  //===--------------------------------------------------------------------===//
303  // Subclass Interface
304  //===--------------------------------------------------------------------===//
305 
306 private:
320  virtual void write_impl(const char *Ptr, size_t Size) = 0;
321 
322  // An out of line virtual method to provide a home for the class vtable.
323  virtual void handle();
324 
327  virtual uint64_t current_pos() const = 0;
328 
329 protected:
333  void SetBuffer(char *BufferStart, size_t Size) {
334  SetBufferAndMode(BufferStart, Size, ExternalBuffer);
335  }
336 
338  virtual size_t preferred_buffer_size() const;
339 
342  const char *getBufferStart() const { return OutBufStart; }
343 
344  //===--------------------------------------------------------------------===//
345  // Private Interface
346  //===--------------------------------------------------------------------===//
347 private:
349  void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
350 
353  void flush_nonempty();
354 
357  void copy_to_buffer(const char *Ptr, size_t Size);
358 
359  virtual void anchor();
360 };
361 
366  virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0;
367  void anchor() override;
368 
369 public:
370  explicit raw_pwrite_stream(bool Unbuffered = false)
371  : raw_ostream(Unbuffered) {}
372  void pwrite(const char *Ptr, size_t Size, uint64_t Offset) {
373 #ifndef NDBEBUG
374  uint64_t Pos = tell();
375  // /dev/null always reports a pos of 0, so we cannot perform this check
376  // in that case.
377  if (Pos)
378  assert(Size + Offset <= Pos && "We don't support extending the stream");
379 #endif
380  pwrite_impl(Ptr, Size, Offset);
381  }
382 };
383 
384 //===----------------------------------------------------------------------===//
385 // File Output Streams
386 //===----------------------------------------------------------------------===//
387 
391  int FD;
392  bool ShouldClose;
393 
394  bool SupportsSeeking;
395 
396 #ifdef _WIN32
397  bool IsWindowsConsole = false;
400 #endif
401 
402  std::error_code EC;
403 
404  uint64_t pos;
405 
407  void write_impl(const char *Ptr, size_t Size) override;
408 
409  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
410 
413  uint64_t current_pos() const override { return pos; }
414 
416  size_t preferred_buffer_size() const override;
417 
419  void error_detected(std::error_code EC) { this->EC = EC; }
420 
421  void anchor() override;
422 
423 public:
432  raw_fd_ostream(StringRef Filename, std::error_code &EC);
433  raw_fd_ostream(StringRef Filename, std::error_code &EC,
434  sys::fs::CreationDisposition Disp);
435  raw_fd_ostream(StringRef Filename, std::error_code &EC,
436  sys::fs::FileAccess Access);
437  raw_fd_ostream(StringRef Filename, std::error_code &EC,
438  sys::fs::OpenFlags Flags);
439  raw_fd_ostream(StringRef Filename, std::error_code &EC,
440  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
441  sys::fs::OpenFlags Flags);
442 
446  raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
447 
448  ~raw_fd_ostream() override;
449 
452  void close();
453 
454  bool supportsSeeking() { return SupportsSeeking; }
455 
458  uint64_t seek(uint64_t off);
459 
460  std::error_code error() const { return EC; }
461 
466  bool has_error() const { return bool(EC); }
467 
477  void clear_error() { EC = std::error_code(); }
478 };
479 
482 raw_ostream &outs();
483 
486 raw_ostream &errs();
487 
489 raw_ostream &nulls();
490 
491 //===----------------------------------------------------------------------===//
492 // Output Stream Adaptors
493 //===----------------------------------------------------------------------===//
494 
498  std::string &OS;
499 
501  void write_impl(const char *Ptr, size_t Size) override;
502 
505  uint64_t current_pos() const override { return OS.size(); }
506 
507 public:
508  explicit raw_string_ostream(std::string &O) : OS(O) {}
509  ~raw_string_ostream() override;
510 
513  std::string& str() {
514  flush();
515  return OS;
516  }
517 };
518 
526 
528  void write_impl(const char *Ptr, size_t Size) override;
529 
530  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
531 
533  uint64_t current_pos() const override;
534 
535 public:
541  SetUnbuffered();
542  }
543 
544  ~raw_svector_ostream() override = default;
545 
546  void flush() = delete;
547 
549  StringRef str() { return StringRef(OS.data(), OS.size()); }
550 };
551 
558  std::vector<char> &OS;
559 
561  void write_impl(const char *Ptr, size_t Size) override;
562 
563  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
564 
566  uint64_t current_pos() const override;
567 
568 public:
573  explicit raw_vector_ostream(std::vector<char> &O) : OS(O) {
574  SetUnbuffered();
575  }
576 
577  ~raw_vector_ostream() override = default;
578 
579  void flush() = delete;
580 
582  StringRef str() { return StringRef(OS.data(), OS.size()); }
583 };
584 
592 
594  void write_impl(const char *Ptr, size_t Size) override;
595 
596  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
597 
599  uint64_t current_pos() const override;
600 
601 public:
607  SetUnbuffered();
608  }
609 
610  ~raw_usvector_ostream() override = default;
611 
612  void flush() = delete;
613 
615  ArrayRef<uint8_t> array() { return ArrayRef<uint8_t>(OS.data(), OS.size()); }
616 };
617 
624  std::vector<uint8_t> &OS;
625 
627  void write_impl(const char *Ptr, size_t Size) override;
628 
629  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
630 
632  uint64_t current_pos() const override;
633 
634 public:
639  explicit raw_uvector_ostream(std::vector<uint8_t> &O) : OS(O) {
640  SetUnbuffered();
641  }
642 
643  ~raw_uvector_ostream() override = default;
644 
645  void flush() = delete;
646 
648  ArrayRef<uint8_t> array() { return ArrayRef<uint8_t>(OS.data(), OS.size()); }
649 };
650 
651 
655  void write_impl(const char *Ptr, size_t size) override;
656  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
657 
660  uint64_t current_pos() const override;
661 
662 public:
663  explicit raw_null_ostream() = default;
664  ~raw_null_ostream() override;
665 };
666 
668  raw_ostream &OS;
669  SmallVector<char, 0> Buffer;
670 
671  virtual void anchor() override;
672 
673 public:
674  buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {}
675  ~buffer_ostream() override { OS << str(); }
676 };
677 
678 } // end namespace wpi
679 
680 #endif // LLVM_SUPPORT_RAW_OSTREAM_H
wpi::raw_vector_ostream::str
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:582
wpi::raw_ostream::reverseColor
virtual raw_ostream & reverseColor()
Reverses the foreground and background colors.
Definition: raw_ostream.h:292
wpi::raw_fd_ostream::clear_error
void clear_error()
Set the flag read by has_error() to false.
Definition: raw_ostream.h:477
wpi::raw_fd_ostream::seek
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
wpi::raw_ostream::getBufferStart
const char * getBufferStart() const
Return the beginning of the current stream buffer, or 0 if the stream is unbuffered.
Definition: raw_ostream.h:342
wpi::raw_ostream::write_hex
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
wpi::raw_ostream::write_zeros
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
wpi::raw_svector_ostream::str
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:549
wpi::raw_uvector_ostream::array
ArrayRef< uint8_t > array()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:648
wpi::nulls
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
wpi::ArrayRef< uint8_t >
wpi::SmallVectorImpl< char >
wpi::raw_string_ostream::str
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:513
wpi::raw_usvector_ostream::array
ArrayRef< uint8_t > array()
Return an ArrayRef for the vector contents.
Definition: raw_ostream.h:615
wpi::raw_ostream::SetBufferSize
void SetBufferSize(size_t Size)
Set the stream to be buffered, using the specified buffer size.
Definition: raw_ostream.h:112
wpi::raw_ostream::changeColor
virtual raw_ostream & changeColor(enum Colors Color, bool Bold=false, bool BG=false)
Changes the foreground color of text that will be output from this point forward.
Definition: raw_ostream.h:278
wpi::raw_ostream::SetBuffer
void SetBuffer(char *BufferStart, size_t Size)
Use the provided buffer as the raw_ostream buffer.
Definition: raw_ostream.h:333
wpi::raw_pwrite_stream
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:365
wpi::raw_ostream::write_escaped
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy wpi::isPrint into an escap...
wpi::outs
raw_ostream & outs()
This returns a reference to a raw_ostream for standard output.
wpi::raw_ostream::preferred_buffer_size
virtual size_t preferred_buffer_size() const
Return an efficient buffer size for the underlying output mechanism.
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: EventLoopRunner.h:17
wpi::raw_uvector_ostream
A raw_ostream that writes to a vector.
Definition: raw_ostream.h:623
wpi::raw_ostream::SetUnbuffered
void SetUnbuffered()
Set the stream to be unbuffered.
Definition: raw_ostream.h:130
wpi::SmallVectorTemplateCommon::data
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:158
wpi::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:497
wpi::raw_null_ostream
A raw_ostream that discards all output.
Definition: raw_ostream.h:653
wpi::raw_usvector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:590
wpi::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
wpi::raw_fd_ostream::has_error
bool has_error() const
Return the value of the flag in this raw_fd_ostream indicating whether an output error has been encou...
Definition: raw_ostream.h:466
wpi::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:524
wpi::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
wpi::raw_uvector_ostream::raw_uvector_ostream
raw_uvector_ostream(std::vector< uint8_t > &O)
Construct a new raw_svector_ostream.
Definition: raw_ostream.h:639
wpi::errs
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
wpi::raw_ostream::has_colors
virtual bool has_colors() const
This function determines if this stream is displayed and supports colors.
Definition: raw_ostream.h:300
wpi::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:390
wpi::size
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1007
wpi::raw_ostream::resetColor
virtual raw_ostream & resetColor()
Resets the colors to terminal defaults.
Definition: raw_ostream.h:289
wpi::raw_ostream::SetBuffered
void SetBuffered()
Set the stream to be buffered, with an automatically determined buffer size.
wpi::raw_vector_ostream
A raw_ostream that writes to a vector.
Definition: raw_ostream.h:557
wpi::SmallVector< char, 0 >
wpi::raw_fd_ostream::raw_fd_ostream
raw_fd_ostream(StringRef Filename, std::error_code &EC)
Open the specified file for writing.
wpi::raw_svector_ostream::raw_svector_ostream
raw_svector_ostream(SmallVectorImpl< char > &O)
Construct a new raw_svector_ostream.
Definition: raw_ostream.h:540
wpi::raw_fd_ostream::close
void close()
Manually flush the stream and close the file.
wpi::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:47
wpi::raw_vector_ostream::raw_vector_ostream
raw_vector_ostream(std::vector< char > &O)
Construct a new raw_svector_ostream.
Definition: raw_ostream.h:573
wpi::raw_ostream::is_displayed
virtual bool is_displayed() const
This function determines if this stream is connected to a "tty" or "console" window.
Definition: raw_ostream.h:297
wpi::raw_ostream::tell
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:101
wpi::buffer_ostream
Definition: raw_ostream.h:667
wpi::raw_usvector_ostream::raw_usvector_ostream
raw_usvector_ostream(SmallVectorImpl< uint8_t > &O)
Construct a new raw_svector_ostream.
Definition: raw_ostream.h:606