Merge commit '48410b113dd2036e69dbf723a39ec9af02fc9b12'
[xonotic/netradiant.git] / libs / stream / stringstream.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_STREAM_STRINGSTREAM_H)
23 #define INCLUDED_STREAM_STRINGSTREAM_H
24
25 #include "itextstream.h"
26 #include "string/string.h"
27 #include <vector>
28
29
30 /// \brief A wrapper around a STL vector of char.
31 /// Maintains a null-terminated array of char.
32 /// Provides a limited STL-style interface to push and pop characters at the end of the string.
33 class StringBuffer
34 {
35   std::vector<char> m_string;
36 public:
37   StringBuffer()
38   {
39     m_string.push_back('\0');
40   }
41   explicit StringBuffer(std::size_t capacity)
42   {
43     m_string.reserve(capacity);
44     m_string.push_back('\0');
45   }
46   explicit StringBuffer(const char* string) : m_string(string, string + string_length(string) + 1)
47   {
48   }
49
50   typedef std::vector<char>::iterator iterator;
51   typedef std::vector<char>::const_iterator const_iterator;
52
53   iterator begin()
54   {
55     return m_string.begin();
56   }
57   const_iterator begin() const
58   {
59     return m_string.begin();
60   }
61   iterator end()
62   {
63     return m_string.end() - 1;
64   }
65   const_iterator end() const
66   {
67     return m_string.end() - 1;
68   }
69
70   void push_back(char c)
71   {
72     m_string.insert(end(), c);
73   }
74   void pop_back()
75   {
76     m_string.erase(end() - 1);
77   }
78   void push_range(const char* first, const char* last)
79   {
80     m_string.insert(end(), first, last);
81   }
82   void push_string(const char* string)
83   {
84     push_range(string, string + string_length(string));
85   }
86   char* c_str()
87   {
88     return &(*m_string.begin());
89   }
90   const char* c_str() const
91   {
92     return &(*m_string.begin());
93   }
94
95   char& back()
96   {
97     return *(end() - 1);
98   }
99   const char& back() const
100   {
101     return *(end() - 1);
102   }
103   bool empty() const
104   {
105     return m_string.size() == 1;
106   }
107   void clear()
108   {
109     m_string.clear();
110     m_string.push_back('\0');
111   }
112 };
113
114 /// \brief A TextOutputStream which writes to a StringBuffer.
115 /// Similar to std::stringstream.
116 class StringOutputStream : public TextOutputStream
117 {
118   StringBuffer m_string;
119 public:
120   typedef StringBuffer::iterator iterator;
121   typedef StringBuffer::const_iterator const_iterator;
122
123   StringOutputStream()
124   {
125   }
126   StringOutputStream(std::size_t capacity) : m_string(capacity)
127   {
128   }
129   std::size_t write(const char* buffer, std::size_t length)
130   {
131     m_string.push_range(buffer, buffer + length);
132     return length;
133   }
134
135   iterator begin()
136   {
137     return m_string.begin();
138   }
139   const_iterator begin() const
140   {
141     return m_string.begin();
142   }
143   iterator end()
144   {
145     return m_string.end();
146   }
147   const_iterator end() const
148   {
149     return m_string.end();
150   }
151
152   bool empty() const
153   {
154     return m_string.empty();
155   }
156   char* c_str()
157   {
158     return m_string.c_str();
159   }
160   const char* c_str() const
161   {
162     return m_string.c_str();
163   }
164   void clear()
165   {
166     m_string.clear();
167   }
168 };
169
170 template<typename T>
171 inline StringOutputStream& operator<<(StringOutputStream& ostream, const T& t)
172 {
173   return ostream_write(ostream, t);
174 }
175
176
177 #endif