1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #ifndef ICE_UTIL_OUTPUT_UTIL_H
6 #define ICE_UTIL_OUTPUT_UTIL_H
7 
8 #include <IceUtil/Config.h>
9 #include <fstream>
10 #include <stack>
11 #include <vector>
12 
13 namespace IceUtilInternal
14 {
15 
16 ICE_API std::string int64ToString(IceUtil::Int64);
17 
18 // ----------------------------------------------------------------------
19 // OutputBase
20 // ----------------------------------------------------------------------
21 
22 //
23 // Technically it's not necessary to have print() & newline() as virtual
24 // since the opeator<< functions are specific to each OutputBase
25 // derivative. However, since it's possible to call print() & newline()
26 // manually I've decided to leave them as virtual.
27 //
28 
29 class ICE_API OutputBase : private ::IceUtil::noncopyable
30 {
31 public:
32 
33     OutputBase();
34     OutputBase(std::ostream&);
35     OutputBase(const std::string&);
36     virtual ~OutputBase();
37 
38     void setIndent(int); // What is the indent level?
39     void setUseTab(bool); // Should we output tabs?
40 
41     void open(const std::string&); // Open output stream.
42     void close(); // Close output stream.
43     bool isOpen(); // Is a file stream open?
44 
45     virtual void print(const std::string&); // Print a string.
46 
47     void inc(); // Increment indentation level.
48     void dec(); // Decrement indentation level.
49 
50     void useCurrentPosAsIndent(); // Save the current position as indentation.
51     void zeroIndent(); // Use zero identation.
52     void restoreIndent(); // Restore indentation.
53     int currIndent(); // Return current indent value.
54 
55     virtual void newline(); // Print newline.
56     void separator(); // Print separator.
57 
58     bool operator!() const; // Check whether the output state is ok.
59 
60 protected:
61 
62     std::ofstream _fout;
63     std::ostream& _out;
64     int _pos;
65     int _indent;
66     int _indentSize;
67     std::stack<int> _indentSave;
68     bool _useTab;
69     bool _separator;
70 };
71 
72 class ICE_API NextLine
73 {
74 };
75 extern ICE_API NextLine nl;
76 
77 class ICE_API Separator
78 {
79 };
80 extern ICE_API Separator sp;
81 
82 // ----------------------------------------------------------------------
83 // Output
84 // ----------------------------------------------------------------------
85 
86 class ICE_API Output : public OutputBase
87 {
88 public:
89 
90     Output();
91     Output(std::ostream&);
92     Output(const char*);
93 
94     virtual void print(const std::string&); // Print a string.
95 
96     void sb(); // Start a block.
97     void eb(); // End a block.
98 
99     void spar(char = '('); // Start a paramater list.
100     void epar(char = ')'); // End a paramater list.
101 
102 private:
103 
104     std::string _blockStart;
105     std::string _blockEnd;
106     int _par; // If >= 0, we are writing a parameter list.
107 };
108 
109 template<typename T>
110 inline Output&
111 operator<<(Output& out, const T& val)
112 {
113     std::ostringstream s;
114     s << val;
115     out.print(s.str());
116     return out;
117 }
118 
119 template<typename T>
120 inline Output&
121 operator<<(Output& out, const std::vector<T>& val)
122 {
123     for(typename std::vector<T>::const_iterator p = val.begin(); p != val.end(); ++p)
124     {
125         out << *p;
126     }
127     return out;
128 }
129 
130 template<>
131 inline Output&
132 operator<<(Output& o, const NextLine&)
133 {
134     o.newline();
135     return o;
136 }
137 
138 template<>
139 inline Output&
140 operator<<(Output& o, const Separator&)
141 {
142     o.separator();
143     return o;
144 }
145 
146 class ICE_API StartBlock
147 {
148 };
149 extern ICE_API StartBlock sb;
150 
151 template<>
152 inline Output&
153 operator<<(Output& o, const StartBlock&)
154 {
155     o.sb();
156     return o;
157 }
158 
159 class ICE_API EndBlock
160 {
161 };
162 extern ICE_API EndBlock eb;
163 
164 template<>
165 inline Output&
166 operator<<(Output& o, const EndBlock&)
167 {
168     o.eb();
169     return o;
170 }
171 
172 class ICE_API StartPar
173 {
174 };
175 extern ICE_API StartPar spar;
176 
177 template<>
178 inline Output&
179 operator<<(Output& o, const StartPar&)
180 {
181     o.spar();
182     return o;
183 }
184 
185 class ICE_API EndPar
186 {
187 };
188 extern ICE_API EndPar epar;
189 
190 template<>
191 inline Output&
192 operator<<(Output& o, const EndPar&)
193 {
194     o.epar();
195     return o;
196 }
197 
198 class ICE_API StartAbrk
199 {
200 };
201 extern ICE_API StartAbrk sabrk;
202 
203 template<>
204 inline Output&
205 operator<<(Output& o, const StartAbrk&)
206 {
207     o.spar('<');
208     return o;
209 }
210 
211 class ICE_API EndAbrk
212 {
213 };
214 extern ICE_API EndAbrk eabrk;
215 
216 template<>
217 inline Output&
218 operator<<(Output& o, const EndAbrk&)
219 {
220     o.epar('>');
221     return o;
222 }
223 
224 ICE_API Output& operator<<(Output&, std::ios_base& (*)(std::ios_base&));
225 
226 // ----------------------------------------------------------------------
227 // XMLOutput
228 // ----------------------------------------------------------------------
229 
230 class ICE_API XMLOutput : public OutputBase
231 {
232 public:
233 
234     XMLOutput();
235     XMLOutput(std::ostream&);
236     XMLOutput(const char*);
237 
238     virtual void print(const std::string&); // Print a string.
239 
240     virtual void newline(); // Print newline.
241 
242     void startElement(const std::string&); // Start an element.
243     void endElement(); // End an element.
244     void attr(const std::string&, const std::string&); // Add an attribute to an element.
245 
246     void startEscapes();
247     void endEscapes();
248 
249     std::string currentElement() const;
250 
251 private:
252 
253     ::std::string escape(const ::std::string&) const;
254 
255     std::stack<std::string> _elementStack;
256 
257     bool _se;
258     bool _text;
259 
260     bool _escape;
261 };
262 
263 template<typename T>
264 inline XMLOutput&
265 operator<<(XMLOutput& out, const T& val)
266 {
267     std::ostringstream s;
268     s << val;
269     out.print(s.str());
270     return out;
271 }
272 
273 template<>
274 inline XMLOutput&
275 operator<<(XMLOutput& o, const NextLine&)
276 {
277     o.newline();
278     return o;
279 }
280 
281 template<>
282 inline XMLOutput&
283 operator<<(XMLOutput& o, const Separator&)
284 {
285     o.separator();
286     return o;
287 }
288 
289 class ICE_API EndElement
290 {
291 };
292 extern ICE_API EndElement ee;
293 
294 template<>
295 inline XMLOutput&
296 operator<<(XMLOutput& o, const EndElement&)
297 {
298     o.endElement();
299     return o;
300 }
301 
302 class ICE_API StartElement
303 {
304 public:
305 
306     StartElement(const std::string&);
307 
308     const std::string& getName() const;
309 
310 private:
311 
312     const std::string _name;
313 };
314 
315 typedef StartElement se;
316 
317 template<>
318 inline XMLOutput&
319 operator<<(XMLOutput& o, const StartElement& e)
320 {
321     o.startElement(e.getName());
322     return o;
323 }
324 
325 class ICE_API Attribute
326 {
327 public:
328 
329     Attribute(const ::std::string&, const ::std::string&);
330 
331     const ::std::string& getName() const;
332     const ::std::string& getValue() const;
333 
334 private:
335 
336     const ::std::string _name;
337     const ::std::string _value;
338 };
339 
340 typedef Attribute attr;
341 
342 template<>
343 inline XMLOutput&
344 operator<<(XMLOutput& o, const Attribute& e)
345 {
346     o.attr(e.getName(), e.getValue());
347     return o;
348 }
349 
350 class ICE_API StartEscapes
351 {
352 };
353 extern ICE_API StartEscapes startEscapes;
354 
355 class ICE_API EndEscapes
356 {
357 };
358 extern ICE_API EndEscapes endEscapes;
359 
360 template<>
361 inline XMLOutput&
362 operator<<(XMLOutput& o, const StartEscapes&)
363 {
364     o.startEscapes();
365     return o;
366 }
367 
368 template<>
369 inline XMLOutput&
370 operator<<(XMLOutput& o, const EndEscapes&)
371 {
372     o.endEscapes();
373     return o;
374 }
375 
376 ICE_API XMLOutput& operator<<(XMLOutput&, std::ios_base& (*)(std::ios_base&));
377 
378 }
379 
380 #endif
381