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 68 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 operators 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 ); 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 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 * 330 StreamStr::operator<<( F_CSTR ) 331 { return dpData; } 332 inline void 333 StreamStr::clear() 334 { pEnd = pCur = dpData; *pEnd = '\0'; } 335 inline const char * 336 StreamStr::c_str() const 337 { return dpData; } 338 inline const char * 339 StreamStr::data() const 340 { return dpData; } 341 inline bool 342 StreamStr::empty() const 343 { return dpData == pEnd; } 344 inline StreamStr::size_type 345 StreamStr::size() const 346 { return pEnd - dpData; } 347 inline StreamStr::size_type 348 StreamStr::length() const 349 { return size(); } 350 inline StreamStr::size_type 351 StreamStr::capacity() const 352 { return nCapacity1-1; } 353 inline StreamStr::position_type 354 StreamStr::tellp() const 355 { return size_type(pCur-dpData); } 356 inline StreamStr::const_iterator 357 StreamStr::begin() const 358 { return dpData; } 359 inline StreamStr::const_iterator 360 StreamStr::cur() const 361 { return pCur; } 362 inline StreamStr::const_iterator 363 StreamStr::end() const 364 { return pEnd; } 365 inline StreamStr::iterator 366 StreamStr::begin() 367 { return dpData; } 368 inline StreamStr::iterator 369 StreamStr::cur() 370 { return pCur; } 371 inline StreamStr::iterator 372 StreamStr::end() 373 { return pEnd; } 374 375 inline void 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