2a4d74fc83f935457a792cd229d720aab7ac911e
[oota-llvm.git] / include / llvm / Support / raw_ostream.h
1 //===--- raw_ostream.h - Raw output stream ---------------------------------===//
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 LLVM_SUPPORT_RAW_OSTREAM_H
15 #define LLVM_SUPPORT_RAW_OSTREAM_H
16
17 #include <string>
18
19 namespace llvm {
20
21 /// raw_ostream - This class implements an extremely fast bulk output stream
22 /// that can *only* output to a stream.  It does not support seeking, reopening,
23 /// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
24 /// a chunk at a time.
25 class raw_ostream {
26 protected:
27   char *OutBufStart, *OutBufEnd, *OutBufCur;
28 public:
29   raw_ostream() {
30     // Start out ready to flush.
31     OutBufStart = OutBufEnd = OutBufCur = 0;
32   }
33   virtual ~raw_ostream() {}
34   
35   //===--------------------------------------------------------------------===//
36   // Configuration Interface
37   //===--------------------------------------------------------------------===//
38   
39   /// SetBufferSize - Set the internal buffer size to the specified amount
40   /// instead of the default.
41   void SetBufferSize(unsigned Size) {
42     assert(Size >= 64 &&
43            "Buffer size must be somewhat large for invariants to hold");
44     flush();
45     
46     delete [] OutBufStart;
47     OutBufStart = new char[Size];
48     OutBufEnd = OutBufStart+Size;
49     OutBufCur = OutBufStart;
50   }
51   
52   //===--------------------------------------------------------------------===//
53   // Data Output Interface
54   //===--------------------------------------------------------------------===//
55   
56   void flush() {
57     if (OutBufCur != OutBufStart)
58       flush_impl();
59   }
60   
61   raw_ostream &operator<<(char C) {
62     if (OutBufCur >= OutBufEnd)
63       flush_impl();
64     *OutBufCur++ = C;
65     return *this;
66   }
67   
68   raw_ostream &operator<<(const char *Str) {
69     return OutputData(Str, strlen(Str));
70   }
71   
72   raw_ostream &OutputData(const char *Ptr, unsigned Size) {
73     if (OutBufCur+Size > OutBufEnd)
74       flush_impl();
75     
76     // Handle short strings specially, memcpy isn't very good at very short
77     // strings.
78     switch (Size) {
79 //    case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH
80     case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH
81     case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH
82     case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
83     case 0: break;
84     default:
85       // Normally the string to emit is shorter than the buffer.
86       if (Size <= unsigned(OutBufEnd-OutBufStart)) {
87         memcpy(OutBufCur, Ptr, Size);
88         break;
89       }
90
91       // If emitting a string larger than our buffer, emit in chunks.  In this
92       // case we know that we just flushed the buffer.
93       while (Size) {
94         unsigned NumToEmit = OutBufEnd-OutBufStart;
95         if (Size < NumToEmit) NumToEmit = Size;
96         assert(OutBufCur == OutBufStart);
97         memcpy(OutBufStart, Ptr, NumToEmit);
98         Ptr += NumToEmit;
99         OutBufCur = OutBufStart + NumToEmit;
100         flush_impl();
101       }
102       break;
103     }
104     OutBufCur += Size;
105     return *this;
106   }
107   
108   //===--------------------------------------------------------------------===//
109   // Subclass Interface
110   //===--------------------------------------------------------------------===//
111
112 protected:
113   
114   /// flush_impl - The is the piece of the class that is implemented by
115   /// subclasses.  This outputs the currently buffered data and resets the
116   /// buffer to empty.
117   virtual void flush_impl() = 0;
118   
119   /// HandleFlush - A stream's implementation of flush should call this after
120   /// emitting the bytes to the data sink.
121   void HandleFlush() {
122     if (OutBufStart == 0)
123       SetBufferSize(4096);
124     OutBufCur = OutBufStart;
125   }
126 private:
127   // An out of line virtual method to provide a home for the class vtable.
128   virtual void handle();
129 };
130   
131 /// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
132 ///
133 class raw_fd_ostream : public raw_ostream {
134   int FD;
135   bool ShouldClose;
136 public:
137   /// raw_fd_ostream - Open the specified file for writing.  If an error occurs,
138   /// information about the error is put into ErrorInfo, and the stream should
139   /// be immediately destroyed.
140   raw_fd_ostream(const char *Filename, std::string &ErrorInfo);
141   
142   /// raw_fd_ostream ctor - FD is the file descriptor that this writes to.  If
143   /// ShouldClose is true, this closes the file when 
144   raw_fd_ostream(int fd, bool shouldClose) : FD(fd), ShouldClose(shouldClose) {}
145   
146   ~raw_fd_ostream();
147     
148   /// flush_impl - The is the piece of the class that is implemented by
149   /// subclasses.  This outputs the currently buffered data and resets the
150   /// buffer to empty.
151   virtual void flush_impl();
152 };
153   
154 class raw_stdout_ostream : public raw_fd_ostream {
155   // An out of line virtual method to provide a home for the class vtable.
156   virtual void handle();
157 public:
158   raw_stdout_ostream();
159 };
160
161 class raw_stderr_ostream : public raw_fd_ostream {
162   // An out of line virtual method to provide a home for the class vtable.
163   virtual void handle();
164 public:
165   raw_stderr_ostream();
166 };
167   
168 } // end llvm namespace
169
170 #endif