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:
StringBuffer()37 StringBuffer(){
38 	m_string.push_back( '\0' );
39 }
StringBuffer(std::size_t capacity)40 explicit StringBuffer( std::size_t capacity ){
41 	m_string.reserve( capacity );
42 	m_string.push_back( '\0' );
43 }
StringBuffer(const char * string)44 explicit StringBuffer( const char* string ) : m_string( string, string + string_length( string ) + 1 ){
45 }
46 
47 typedef std::vector<char>::iterator iterator;
48 typedef std::vector<char>::const_iterator const_iterator;
49 
begin()50 iterator begin(){
51 	return m_string.begin();
52 }
begin()53 const_iterator begin() const {
54 	return m_string.begin();
55 }
end()56 iterator end(){
57 	return m_string.end() - 1;
58 }
end()59 const_iterator end() const {
60 	return m_string.end() - 1;
61 }
62 
push_back(char c)63 void push_back( char c ){
64 	m_string.insert( end(), c );
65 }
pop_back()66 void pop_back(){
67 	m_string.erase( end() - 1 );
68 }
push_range(const char * first,const char * last)69 void push_range( const char* first, const char* last ){
70 	m_string.insert( end(), first, last );
71 }
push_string(const char * string)72 void push_string( const char* string ){
73 	push_range( string, string + string_length( string ) );
74 }
c_str()75 char* c_str(){
76 	return &( *m_string.begin() );
77 }
c_str()78 const char* c_str() const {
79 	return &( *m_string.begin() );
80 }
81 
back()82 char& back(){
83 	return *( end() - 1 );
84 }
back()85 const char& back() const {
86 	return *( end() - 1 );
87 }
empty()88 bool empty() const {
89 	return m_string.size() == 1;
90 }
clear()91 void clear(){
92 	m_string.clear();
93 	m_string.push_back( '\0' );
94 }
95 };
96 
97 /// \brief A TextOutputStream which writes to a StringBuffer.
98 /// Similar to std::stringstream.
99 class StringOutputStream : public TextOutputStream
100 {
101 StringBuffer m_string;
102 public:
103 typedef StringBuffer::iterator iterator;
104 typedef StringBuffer::const_iterator const_iterator;
105 
StringOutputStream()106 StringOutputStream(){
107 }
StringOutputStream(std::size_t capacity)108 StringOutputStream( std::size_t capacity ) : m_string( capacity ){
109 }
write(const char * buffer,std::size_t length)110 std::size_t write( const char* buffer, std::size_t length ){
111 	m_string.push_range( buffer, buffer + length );
112 	return length;
113 }
114 
begin()115 iterator begin(){
116 	return m_string.begin();
117 }
begin()118 const_iterator begin() const {
119 	return m_string.begin();
120 }
end()121 iterator end(){
122 	return m_string.end();
123 }
end()124 const_iterator end() const {
125 	return m_string.end();
126 }
127 
empty()128 bool empty() const {
129 	return m_string.empty();
130 }
c_str()131 char* c_str(){
132 	return m_string.c_str();
133 }
c_str()134 const char* c_str() const {
135 	return m_string.c_str();
136 }
clear()137 void clear(){
138 	m_string.clear();
139 }
140 };
141 
142 template<typename T>
143 inline StringOutputStream& operator<<( StringOutputStream& ostream, const T& t ){
144 	return ostream_write( ostream, t );
145 }
146 
147 
148 #endif
149