fix a scanf warning
[divverent/netradiant.git] / include / itextstream.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_ITEXTSTREAM_H)
23 #define INCLUDED_ITEXTSTREAM_H
24
25 /// \file
26 /// \brief Text-stream interfaces.
27
28 #include <cstddef>
29 #include "generic/static.h"
30
31 /// \brief A read-only character-stream.
32 class TextInputStream
33 {
34 public:
35   /// \brief Attempts to read the next \p length characters from the stream to \p buffer.
36   /// Returns the number of characters actually stored in \p buffer.
37   virtual std::size_t read(char* buffer, std::size_t length) = 0;
38 };
39
40 /// \brief A write-only character-stream.
41 class TextOutputStream
42 {
43 public:
44   /// \brief Attempts to write \p length characters to the stream from \p buffer.
45   /// Returns the number of characters actually read from \p buffer.
46   virtual std::size_t write(const char* buffer, std::size_t length) = 0;
47 };
48
49 /// \brief Calls the overloaded function ostream_write() to perform text formatting specific to the type being written.
50 /*! Note that ostream_write() is not globally defined - it must be defined once for each type supported.\n
51 To support writing a custom type MyClass to any kind of text-output-stream with operator<<:
52 \code
53 template<typename TextOutputStreamType>
54 TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const MyClass& myClass)
55 {
56   return ostream << myClass.getName() << ' ' << myClass.getText();
57 }
58 \endcode
59 Expressing this as a template allows it to be used directly with any concrete text-output-stream type, not just the abstract TextOutputStream\n
60 \n
61 This overload writes a single character to any text-output-stream - ostream_write(TextOutputStreamType& ostream, char c).
62 */
63 template<typename T>
64 inline TextOutputStream& operator<<(TextOutputStream& ostream, const T& t)
65 {
66   return ostream_write(ostream, t);
67 }
68
69 class NullOutputStream : public TextOutputStream
70 {
71 public:
72   std::size_t write(const char*, std::size_t length)
73   {
74     return length;
75   }
76 };
77
78 class OutputStreamHolder
79 {
80   NullOutputStream m_nullOutputStream;
81   TextOutputStream* m_outputStream;
82 public:
83   OutputStreamHolder()
84     : m_outputStream(&m_nullOutputStream)
85   {
86   }
87   void setOutputStream(TextOutputStream& outputStream)
88   {
89     m_outputStream = &outputStream;
90   }
91   TextOutputStream& getOutputStream()
92   {
93     return *m_outputStream;
94   }
95 };
96
97 typedef Static<OutputStreamHolder> GlobalOutputStream;
98
99 /// \brief Returns the global output stream. Used to display messages to the user.
100 inline TextOutputStream& globalOutputStream()
101 {
102   return GlobalOutputStream::instance().getOutputStream();
103 }
104
105 class ErrorStreamHolder : public OutputStreamHolder {};
106 typedef Static<ErrorStreamHolder> GlobalErrorStream;
107
108 /// \brief Returns the global error stream. Used to display error messages to the user.
109 inline TextOutputStream& globalErrorStream()
110 {
111   return GlobalErrorStream::instance().getOutputStream();
112 }
113
114 #endif