1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef CSV_STREAMSTR_HXX
25 #define CSV_STREAMSTR_HXX
26
27 // BASE CLASSES
28 #include <cosv/bstream.hxx>
29 // USED SERVICES
30 #include <cosv/str_types.hxx>
31 #include <string.h>
32
33
34
35
36 namespace csv
37 {
38 class String;
39
40
41 void c_str(); // Dummy needed for StreamStr::operator<<(StreamStr::F_CSTR);
42
43
44 /** A string buffer class for all kinds of string manipulation.
45 */
46 class StreamStr : public bostream
47 {
48 public:
49 typedef StreamStr self;
50
51 typedef str::size size_type;
52 typedef str::position position_type;
53 typedef intt seek_type;
54 typedef str::insert_mode insert_mode;
55
56 typedef const char * const_iterator;
57 typedef char * iterator;
58
59 typedef void (*F_CSTR)();
60
61
62 /** Represents an area within a string.
63 */
64 struct Area
65 {
66 typedef str::size size_type;
67
Areacsv::StreamStr::Area68 Area(
69 const char * i_str = "",
70 size_type i_nLength = str::maxsize )
71 : sStr(i_str),
72 nLength( i_nLength == str::maxsize
73 ? strlen(i_str)
74 : i_nLength ) {}
75 const char * sStr;
76 size_type nLength;
77 };
78
79 // LIFECYCLE
80 StreamStr(
81 size_type i_nCapacity );
82 StreamStr(
83 const char * i_sInitStr,
84 size_type i_nCapacity ); /// Only used if > strlen(i_sInitStr).
85 StreamStr(
86 size_type i_nGuessedCapacity,
87 const char * str1, // [!= 0]
88 const char * str2, // [!= 0]
89 ... ); // Has to end with NIL .
90 StreamStr(
91 csv::bstream & i_source );
92 /// Copies also insert_mode and current position.
93 StreamStr(
94 const self & i_rOther );
95 ~StreamStr();
96
97 // OPERATORS
98 /// Copies also insert_mode and current position.
99 self & operator=(
100 const self & i_rOther );
101
102 self & operator<<(
103 const char * i_s );
104 self & operator<<(
105 const String & i_s );
106 self & operator<<(
107 char i_c );
108 self & operator<<(
109 unsigned char i_c );
110 self & operator<<(
111 signed char i_c );
112
113 self & operator<<(
114 short i_n );
115 self & operator<<(
116 unsigned short i_n );
117 self & operator<<(
118 int i_n );
119 self & operator<<(
120 unsigned int i_n );
121 self & operator<<(
122 long i_n );
123 self & operator<<(
124 unsigned long i_n );
125
126 self & operator<<(
127 float i_n );
128 self & operator<<(
129 double i_n );
130
131 /** This operator is used to finish a sequence of streaming
132 oeprators by returning the c-string of the complete string.
133
134 @return The same as ->c_str().
135
136 @example
137 csv::StreamStr s(100);
138 const char *
139 fullname = s << qualifier() << "::" << name() << csv::c_str;
140 */
141 const char * operator<<(
142 F_CSTR i_f );
143
144 const char & operator[](
145 position_type i_nPosition ) const;
146 char & operator[](
147 position_type i_nPosition );
148
149 // OPERATIONS
150 void resize(
151 size_type i_nMinimumCapacity );
152
153 void clear();
154 void swap(
155 StreamStr & io_swap );
156
157 /** Sets start point for the next operator<<() call.
158 if the intended position is not reachable, nothing happens.
159 */
160 self & seekp(
161 seek_type i_nCount,
162 seek_dir i_eDirection = ::csv::beg );
reset()163 self & reset() { return seekp(0); }
164 /** Sets the insertion mode of all and only the operator<<() calls.
165
166 Default is str::overwrite:
167 str::overwrite: seekp() always sets the cur end of the string.
168 operator<<() calls push the end of the string forward.
169 str::insert: seekp() only sets the insertion point.
170 operator<<() calls insert their text at the tellp()
171 position and keep the rest of the string. tellp() is
172 then after the inserted text, on the beginning of the
173 rest of the string.
174 */
175 self & set_insert_mode(
176 insert_mode i_eMode );
177
178 void push_front(
179 const char * i_str );
180 void push_front(
181 char i_c );
182 void push_back(
183 const char * i_str );
184 void push_back(
185 char i_c );
186 void pop_front(
187 size_type i_nCount );
188 void pop_back(
189 size_type i_nCount );
190
191 /// Works like operator<<(). Does the same as Perl's join().
192 self & operator_join(
193 std::vector<String>::const_iterator
194 i_rBegin,
195 std::vector<String>::const_iterator
196 i_rEnd,
197 const char * i_sLink );
198 /// Works like operator<<()
199 self & operator_add_substr(
200 const char * i_sText,
201 size_type i_nLength );
202 /// Works like operator<<()
203 self & operator_add_token(
204 const char * i_sText,
205 char i_cDelimiter );
206 /// Works like operator<<()
207 self & operator_read_line(
208 bstream & i_src );
209
210 void strip_front(
211 char i_cToRemove );
212 void strip_back(
213 char i_cToRemove );
214 void strip_frontback(
215 char i_cToRemove );
216 void strip_front_whitespace(); /// removes space, tab and crlf.
217 void strip_back_whitespace();
218 void strip_frontback_whitespace();
219
220 /** @precond i_begin is valid
221 @precond i_end is valid
222 @precond i_end >= i_begin
223 */
224 void remove(
225 iterator i_begin,
226 iterator i_end );
227 void replace(
228 position_type i_nStart,
229 size_type i_nSize,
230 Area i_aReplacement );
231
232 void replace_all(
233 char i_cCarToSearch,
234 char i_cReplacement );
235 void replace_all(
236 Area i_aStrToSearch,
237 Area i_aReplacement );
238
239 StreamStr & to_lower(
240 position_type i_nStart = 0,
241 size_type i_nLength = str::maxsize );
242 StreamStr & to_upper(
243 position_type i_nStart = 0,
244 size_type i_nLength = str::maxsize );
245
246 // INQUIRY
247 const char * c_str() const;
248 const char * data() const;
249
250 bool empty() const;
251 size_type size() const;
252 size_type length() const;
253
254 size_type capacity() const;
255
256 position_type tellp() const;
257
258 const_iterator begin() const;
259 const_iterator cur() const;
260 const_iterator end() const;
261
262 size_type token_count(
263 char i_cSplit ) const;
264 String token(
265 position_type i_nNr, /// Starting with 0.
266 char i_cSpli ) const;
267
268 // ACCESS
269 iterator begin();
270 iterator cur();
271 iterator end();
272
273 private:
274 // Interface bostream
275 virtual UINT32 do_write(
276 const void * i_pSrc,
277 UINT32 i_nNrofBytes);
278 // Locals
279 void ProvideAddingSize(
280 size_type i_nSize2Add );
281 /// Resizes with the factor 2.0 (under 128), 1.5 or until i_nMinimumCapacity, whatever is bigger.
282 void Resize(
283 size_type i_nMinimumCapacity = 0 );
284 void Advance(
285 size_type i_nAddedSize );
286 void MoveData(
287 char * i_pStart,
288 char * i_pEnd,
289 seek_type i_nDiff );
290 // DATA
291 size_type nCapacity1; /// Capacity of characters to contain + 1 for terminating 0.
292 DYN char * dpData;
293 char * pEnd;
294 char * pCur;
295 insert_mode eMode;
296 };
297
298
299
300 class StreamStrLock
301 {
302 public:
303 StreamStrLock(
304 uintt i_nMinimalSize );
305 ~StreamStrLock();
306
operator ()()307 StreamStr & operator()() { return *pStr; }
308
309 private:
310 StreamStr * pStr;
311 };
312
313 /** Splits a string into tokens by whitespace.
314
315 The tokens are added to the end of o_list.
316 */
317 void Split(
318 std::vector<String> &
319 o_list,
320 const char * i_text );
321 inline void Join(
322 StreamStr & o_text,
323 std::vector<String> &
324 i_list,
325 const char * i_sLink = " ");
326
327 // IMPLEMENTATION
328
329 inline const char *
operator <<(F_CSTR)330 StreamStr::operator<<( F_CSTR )
331 { return dpData; }
332 inline void
clear()333 StreamStr::clear()
334 { pEnd = pCur = dpData; *pEnd = '\0'; }
335 inline const char *
c_str() const336 StreamStr::c_str() const
337 { return dpData; }
338 inline const char *
data() const339 StreamStr::data() const
340 { return dpData; }
341 inline bool
empty() const342 StreamStr::empty() const
343 { return dpData == pEnd; }
344 inline StreamStr::size_type
size() const345 StreamStr::size() const
346 { return pEnd - dpData; }
347 inline StreamStr::size_type
length() const348 StreamStr::length() const
349 { return size(); }
350 inline StreamStr::size_type
capacity() const351 StreamStr::capacity() const
352 { return nCapacity1-1; }
353 inline StreamStr::position_type
tellp() const354 StreamStr::tellp() const
355 { return size_type(pCur-dpData); }
356 inline StreamStr::const_iterator
begin() const357 StreamStr::begin() const
358 { return dpData; }
359 inline StreamStr::const_iterator
cur() const360 StreamStr::cur() const
361 { return pCur; }
362 inline StreamStr::const_iterator
end() const363 StreamStr::end() const
364 { return pEnd; }
365 inline StreamStr::iterator
begin()366 StreamStr::begin()
367 { return dpData; }
368 inline StreamStr::iterator
cur()369 StreamStr::cur()
370 { return pCur; }
371 inline StreamStr::iterator
end()372 StreamStr::end()
373 { return pEnd; }
374
375 inline void
Join(StreamStr & o_text,std::vector<String> & i_list,const char * i_sLink)376 Join( StreamStr & o_text,
377 std::vector<String> & i_list,
378 const char * i_sLink )
379 {
380 o_text.operator_join(i_list.begin(),i_list.end(),i_sLink);
381 }
382
383
384
385
386 } // namespace csv
387 #endif
388