summaryrefslogtreecommitdiff
path: root/include/llvm/Support/raw_ostream.h
blob: 5ab0988d3eea107831ca562a44e95fb862132fb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
//===--- raw_ostream.h - Raw output stream --------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the raw_ostream class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
#define LLVM_SUPPORT_RAW_OSTREAM_H

#include "llvm/ADT/StringExtras.h"
#include <cassert>
#include <cstring>
#include <string>
#include <iosfwd>

namespace llvm {
  class format_object_base;
  template <typename T>
  class SmallVectorImpl;
  
/// raw_ostream - This class implements an extremely fast bulk output stream
/// that can *only* output to a stream.  It does not support seeking, reopening,
/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {
protected:
  char *OutBufStart, *OutBufEnd, *OutBufCur;
public:
  raw_ostream() {
    // Start out ready to flush.
    OutBufStart = OutBufEnd = OutBufCur = 0;
  }

  virtual ~raw_ostream() {
    delete [] OutBufStart;
  }
  
  //===--------------------------------------------------------------------===//
  // Configuration Interface
  //===--------------------------------------------------------------------===//
  
  /// SetBufferSize - Set the internal buffer size to the specified amount
  /// instead of the default.
  void SetBufferSize(unsigned Size) {
    assert(Size >= 64 &&
           "Buffer size must be somewhat large for invariants to hold");
    flush();
    
    delete [] OutBufStart;
    OutBufStart = new char[Size];
    OutBufEnd = OutBufStart+Size;
    OutBufCur = OutBufStart;
  }
  
  //===--------------------------------------------------------------------===//
  // Data Output Interface
  //===--------------------------------------------------------------------===//
  
  void flush() {
    if (OutBufCur != OutBufStart)
      flush_impl();
  }
  
  raw_ostream &operator<<(char C) {
    if (OutBufCur >= OutBufEnd)
      flush_impl();
    *OutBufCur++ = C;
    return *this;
  }
  
  raw_ostream &operator<<(unsigned char C) {
    if (OutBufCur >= OutBufEnd)
      flush_impl();
    *OutBufCur++ = C;
    return *this;
  }
  
  raw_ostream &operator<<(signed char C) {
    if (OutBufCur >= OutBufEnd)
      flush_impl();
    *OutBufCur++ = C;
    return *this;
  }
  
  raw_ostream &operator<<(const char *Str) {
    return write(Str, strlen(Str));
  }
  
  raw_ostream &operator<<(const std::string& Str) {
    return write(Str.data(), Str.length());
  }
  
  raw_ostream &operator<<(unsigned long N);
  raw_ostream &operator<<(long N);
  raw_ostream &operator<<(unsigned long long N);
  raw_ostream &operator<<(long long N);
  raw_ostream &operator<<(const void *P);
  raw_ostream &operator<<(unsigned int N) {
    return this->operator<<(static_cast<unsigned long>(N));
  }
  
  raw_ostream &operator<<(int N) {
    return this->operator<<(static_cast<long>(N));
  }

  raw_ostream &operator<<(double N) {
    return this->operator<<(ftostr(N));
  }
  
  raw_ostream &write(const char *Ptr, unsigned Size);
  
  // Formatted output, see the format() function in Support/Format.h.
  raw_ostream &operator<<(const format_object_base &Fmt);
  
  //===--------------------------------------------------------------------===//
  // Subclass Interface
  //===--------------------------------------------------------------------===//

protected:
  
  /// flush_impl - The is the piece of the class that is implemented by
  /// subclasses.  This outputs the currently buffered data and resets the
  /// buffer to empty.
  virtual void flush_impl() = 0;
  
  /// HandleFlush - A stream's implementation of flush should call this after
  /// emitting the bytes to the data sink.
  void HandleFlush() {
    if (OutBufStart == 0)
      SetBufferSize(4096);
    OutBufCur = OutBufStart;
  }
private:
  // An out of line virtual method to provide a home for the class vtable.
  virtual void handle();
};
  
//===----------------------------------------------------------------------===//
// File Output Streams
//===----------------------------------------------------------------------===//
  
/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
///
class raw_fd_ostream : public raw_ostream {
  int FD;
  bool ShouldClose;
public:
  /// raw_fd_ostream - Open the specified file for writing.  If an error occurs,
  /// information about the error is put into ErrorInfo, and the stream should
  /// be immediately destroyed.
  raw_fd_ostream(const char *Filename, std::string &ErrorInfo);
  
  /// raw_fd_ostream ctor - FD is the file descriptor that this writes to.  If
  /// ShouldClose is true, this closes the file when 
  raw_fd_ostream(int fd, bool shouldClose) : FD(fd), ShouldClose(shouldClose) {}
  
  ~raw_fd_ostream();
    
  /// flush_impl - The is the piece of the class that is implemented by
  /// subclasses.  This outputs the currently buffered data and resets the
  /// buffer to empty.
  virtual void flush_impl();
};
  
/// raw_stdout_ostream - This is a stream that always prints to stdout.
///
class raw_stdout_ostream : public raw_fd_ostream {
  // An out of line virtual method to provide a home for the class vtable.
  virtual void handle();
public:
  raw_stdout_ostream();
};

/// raw_stderr_ostream - This is a stream that always prints to stderr.
///
class raw_stderr_ostream : public raw_fd_ostream {
  // An out of line virtual method to provide a home for the class vtable.
  virtual void handle();
public:
  raw_stderr_ostream();
};
  
/// outs() - This returns a reference to a raw_ostream for standard output.
/// Use it like: outs() << "foo" << "bar";
raw_ostream &outs();

/// errs() - This returns a reference to a raw_ostream for standard error.
/// Use it like: errs() << "foo" << "bar";
raw_ostream &errs();
  
  
//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//
  
/// raw_os_ostream - A raw_ostream that writes to an std::ostream.  This is a
/// simple adaptor class.
class raw_os_ostream : public raw_ostream {
  std::ostream &OS;
public:
  raw_os_ostream(std::ostream &O) : OS(O) {}
  ~raw_os_ostream();

  /// flush_impl - The is the piece of the class that is implemented by
  /// subclasses.  This outputs the currently buffered data and resets the
  /// buffer to empty.
  virtual void flush_impl();
};

/// raw_string_ostream - A raw_ostream that writes to an std::string.  This is a
/// simple adaptor class.
class raw_string_ostream : public raw_ostream {
  std::string &OS;
public:
  raw_string_ostream(std::string &O) : OS(O) {}
  ~raw_string_ostream();
  
  /// str - Flushes the stream contents to the target string and returns
  ///  the string's reference.
  std::string& str() {
    flush();
    return OS;
  }
  
  /// flush_impl - The is the piece of the class that is implemented by
  /// subclasses.  This outputs the currently buffered data and resets the
  /// buffer to empty.
  virtual void flush_impl();
};
  
/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
/// SmallString.  This is a simple adaptor class.
class raw_svector_ostream : public raw_ostream {
  SmallVectorImpl<char> &OS;
public:
  raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {}
  ~raw_svector_ostream();
  
  /// flush_impl - The is the piece of the class that is implemented by
  /// subclasses.  This outputs the currently buffered data and resets the
  /// buffer to empty.
  virtual void flush_impl();
};
  
} // end llvm namespace

#endif