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 COSV_STRING_HXX 25 #define COSV_STRING_HXX 26 27 // USED SERVICES 28 #include <cosv/stringdata.hxx> 29 #include <cosv/str_types.hxx> 30 #include <string.h> 31 #include <cosv/csv_ostream.hxx> 32 #include <vector> 33 34 35 36 37 namespace csv 38 { 39 40 41 /** The Simple String: 42 It is used to just hold short to middle long texts as 43 data, which are constant at most times. They are reference 44 counted, so they are space efficient and have constant time 45 copy semantics. 46 47 For all compare() functions the return value is like in strcmp(). 48 49 @attention 50 The present version of this class is NOT thread safe. 51 */ 52 53 54 class String 55 { 56 public: 57 typedef String self; 58 59 typedef str::size size_type; 60 typedef str::position position_type; 61 62 typedef const char * const_iterator; 63 64 // LIFECYCLE 65 String(); 66 67 /// Intentionally not explicit, smooth casting is intended. 68 String( 69 const char * i_str ); 70 /// @precond i_nLength <= strlen(i_str) or i_nLength == str::maxsize. 71 String( 72 const char * i_str, 73 size_type i_nLength ); 74 /** @precond i_nLength == str::maxsize 75 || i_nStartPosition+i_nLength <= i_rStr.Size(). 76 */ 77 String( 78 const self & i_rStr, 79 position_type i_nStartPosition, 80 size_type i_nLength ); 81 /** @precond i_itBegin and i_itEnd are in the same valid 82 memory-area, such that zero to finite times repetition of 83 ++i_itBegin leads to i_itBegin == i_itEnd. 84 */ 85 String( 86 const_iterator i_itBegin, 87 const_iterator i_itEnd ); 88 89 String( 90 const self & i_rStr ); 91 92 ~String(); 93 // OPERATORS 94 self & operator=( 95 const self & i_rStr ); 96 self & operator=( 97 const char * i_str ); 98 99 operator const char * () const; 100 101 bool operator==( 102 const self & i_rStr ) const; 103 bool operator!=( 104 const self & i_rStr ) const; 105 bool operator<( 106 const self & i_rStr ) const; 107 bool operator>( 108 const self & i_rStr ) const; 109 bool operator<=( 110 const self & i_rStr ) const; 111 bool operator>=( 112 const self & i_rStr ) const; 113 114 // OPERATIONS 115 void clear(); 116 117 void swap( 118 self & i_rStr ); 119 120 /** @precond i_nLength == str::maxsize 121 || i_nStartPosition+i_nLength <= i_rStr.Size(). 122 */ 123 void assign( 124 const self & i_rStr, 125 position_type i_nStartPosition, 126 size_type i_nLength ); 127 void assign( 128 const char * i_str ); 129 /// @precond i_nLength == str::maxsize OR i_nLength < strlen(i_str) . 130 void assign( 131 const char * i_str, 132 size_type i_nLength ); 133 /// Create a string consisting of a sequence of i_nCount times the same char. 134 void assign( 135 size_type i_nCount, 136 char i_c ); 137 /** @precond i_itBegin and i_itEnd are in the same valid 138 memory-area, such that zero to finite times repetition of 139 ++i_itBegin leads to i_itBegin == i_itEnd. 140 */ 141 void assign( 142 const_iterator i_itBegin, 143 const_iterator i_itEnd ); 144 145 // INQUIRY 146 const char * c_str() const; 147 const char * data() const; 148 149 bool empty() const; 150 size_type size() const; 151 size_type length() const; 152 153 const char & char_at( 154 position_type i_nPosition ) const; 155 156 const_iterator begin() const; 157 158 /// This is inefficient, so shouldn't be used within loops. 159 const_iterator end() const; 160 161 int compare( 162 const self & i_rStr ) const; 163 int compare( 164 const CharOrder_Table & 165 i_rOrder, 166 const self & i_rStr ) const; 167 168 self substr( 169 position_type i_nStartPosition = 0, 170 size_type i_nLength = str::maxsize ) const; 171 172 /** @param i_strToSearch [i_strToSearch != 0] 173 i_strToSearch == "" will return npos. 174 */ 175 position_type find( 176 const char * i_strToSearch, 177 position_type i_nSearchStartPosition = 0 ) const; 178 position_type find( 179 char i_charToSearch, 180 position_type i_nSearchStartPosition = 0 ) const; 181 182 //*********** Not yet implemented *********************// 183 position_type rfind( 184 const char * i_strToSearch, 185 position_type i_nSearchStartPosition = str::npos ) const; 186 position_type rfind( 187 char i_charToSearch, 188 position_type i_nSearchStartPosition = str::npos ) const; 189 190 position_type find_first_not_of( 191 const char * i_strToSearch, 192 position_type i_nSearchStartPosition = 0 ) const; 193 position_type find_first_not_of( 194 char i_charToSearch, 195 position_type i_nSearchStartPosition = 0 ) const; 196 197 position_type find_last_not_of( 198 const char * i_strToSearch, 199 position_type i_nSearchStartPosition = str::npos ) const; 200 position_type find_last_not_of( 201 char i_charToSearch, 202 position_type i_nSearchStartPosition = str::npos ) const; 203 //*********** end - not yet implemented *****************// 204 205 static const self & Null_(); 206 static const char & Nulch_(); 207 208 private: 209 struct S_Data 210 { 211 S_Data(); 212 /// @precond i_nValidLength <= strlen(i_sData) or i_nValidLength == str::maxsize. 213 explicit S_Data( 214 const char * i_sData, 215 size_type i_nValidLength = str::maxsize ); 216 ~S_Data(); 217 218 const S_Data * Acquire() const; 219 220 /// Deletes this, if nCount becomes 0. 221 void Release() const; 222 223 StringData<char> aStr; 224 mutable UINT32 nCount; 225 226 private: 227 // Forbidden functions, because this is a refcounted structure. 228 S_Data(const S_Data&); 229 S_Data & operator=(const S_Data&); 230 }; 231 232 // Locals 233 const StringData<char> & 234 Str() const; 235 236 // DATA 237 const S_Data * pd; 238 }; 239 240 241 //********** Global compare functions ***************// 242 243 //*** Natural order, no substrings 244 245 inline int compare( 246 const String & i_s1, 247 const String & i_s2 ); 248 inline int compare( 249 const String & i_s1, 250 const char * i_s2 ); 251 inline int compare( 252 const char * i_s1, 253 const String & i_s2 ); 254 inline int compare( 255 const char * i_s1, 256 const char * i_s2 ); 257 258 //*** Natural order, substrings 259 260 int compare( 261 const String & i_s1, 262 csv::str::position i_nStartPosition1, 263 const char * i_s2, 264 csv::str::size i_nLength ); 265 int compare( 266 const char * i_s1, 267 const String & i_s2, 268 csv::str::position i_nStartPosition2, 269 csv::str::size i_nLength ); 270 inline int compare( 271 const char * i_s1, 272 const char * i_s2, 273 csv::str::size i_nLength ); 274 275 //*** Defined order, no substrings 276 277 inline int compare( 278 const CharOrder_Table & i_rOrder, 279 const String & i_s1, 280 const char * i_s2 ); 281 inline int compare( 282 const CharOrder_Table & i_rOrder, 283 const char * i_s1, 284 const String & i_s2 ); 285 int compare( 286 const CharOrder_Table & i_rOrder, 287 const char * i_s1, 288 const char * i_s2 ); 289 290 //*** Defined order, substrings 291 292 int compare( 293 const CharOrder_Table & i_rOrder, 294 const String & i_s1, 295 csv::str::position i_nStartPosition1, 296 const char * i_s2, 297 csv::str::size i_nLength2 ); 298 int compare( 299 const CharOrder_Table & i_rOrder, 300 const char * i_s1, 301 const String & i_s2, 302 csv::str::position i_nStartPosition2, 303 csv::str::size i_nLength ); 304 int compare( 305 const CharOrder_Table & i_rOrder, 306 const char * i_s1, 307 const char * i_s2, 308 csv::str::size i_nLength ); 309 310 311 } // namespace csv 312 313 314 315 316 //****************** global comparation operators *********************// 317 318 inline bool operator==( 319 const csv::String & i_s1, 320 const char * i_s2 ); 321 inline bool operator!=( 322 const csv::String & i_s1, 323 const char * i_s2 ); 324 inline bool operator<( 325 const csv::String & i_s1, 326 const char * i_s2 ); 327 inline bool operator>( 328 const csv::String & i_s1, 329 const char * i_s2 ); 330 inline bool operator<=( 331 const csv::String & i_s1, 332 const char * i_s2 ); 333 inline bool operator>=( 334 const csv::String & i_s1, 335 const char * i_s2 ); 336 337 inline bool operator==( 338 const char * i_s1, 339 const csv::String & i_s2 ); 340 inline bool operator!=( 341 const char * i_s1, 342 const csv::String & i_s2 ); 343 inline bool operator<( 344 const char * i_s1, 345 const csv::String & i_s2 ); 346 inline bool operator>( 347 const char * i_s1, 348 const csv::String & i_s2 ); 349 inline bool operator<=( 350 const char * i_s1, 351 const csv::String & i_s2 ); 352 inline bool operator>=( 353 const char * i_s1, 354 const csv::String & i_s2 ); 355 356 357 //****************** global stream operators *********************// 358 359 360 inline csv::ostream & 361 operator<<( csv::ostream & o_rOut, 362 const csv::String & i_rSrc ); 363 364 365 366 367 // IMPLEMENTATION 368 namespace csv 369 { 370 371 372 inline const StringData<char> & 373 String::Str() const 374 { return pd->aStr; } 375 376 377 inline const char & 378 String::char_at( position_type i_nPosition ) const 379 { if ( i_nPosition < Str().Size() ) 380 return Str().Data()[i_nPosition]; 381 return Nulch_(); 382 } 383 384 inline bool 385 String::operator==( const self & i_rStr ) const 386 { return compare(i_rStr) == 0; } 387 388 inline bool 389 String::operator!=( const self & i_rStr ) const 390 { return compare(i_rStr) != 0; } 391 392 inline bool 393 String::operator<( const self & i_rStr ) const 394 { return compare(i_rStr) < 0; } 395 396 inline bool 397 String::operator>( const self & i_rStr ) const 398 { return compare(i_rStr) > 0; } 399 400 inline bool 401 String::operator<=( const self & i_rStr ) const 402 { return compare(i_rStr) <= 0; } 403 404 inline bool 405 String::operator>=( const self & i_rStr ) const 406 { return compare(i_rStr) >= 0; } 407 408 inline void 409 String::clear() 410 { operator=( String::Null_() ); } 411 412 inline const char * 413 String::c_str() const 414 { return Str().Data(); } 415 416 inline 417 String::operator const char * () const 418 { return c_str(); } 419 420 inline const char * 421 String::data() const 422 { return c_str(); } 423 424 inline String::size_type 425 String::size() const 426 { return Str().Size(); } 427 428 inline bool 429 String::empty() const 430 { return size() == 0; } 431 432 inline String::size_type 433 String::length() const 434 { return size(); } 435 436 inline String::const_iterator 437 String::begin() const 438 { return data(); } 439 440 inline String::const_iterator 441 String::end() const 442 { return data() + size(); } 443 444 445 446 //****************** global compare-functions ********************// 447 inline int 448 compare( const String & i_s1, 449 const String & i_s2 ) 450 { return i_s1.compare(i_s2); } 451 452 inline int 453 compare( const String & i_s1, 454 const char * i_s2 ) 455 { return strcmp(i_s1.c_str(), i_s2); } 456 457 inline int 458 compare( const char * i_s1, 459 const String & i_s2 ) 460 { return strcmp(i_s1, i_s2.c_str()); } 461 462 inline int 463 compare( const char * i_s1, 464 const char * i_s2 ) 465 { return strcmp(i_s1, i_s2); } 466 467 inline int 468 compare( const char * i_s1, 469 const char * i_s2, 470 str::size i_nLength ) 471 { return strncmp( i_s1, i_s2, i_nLength ); } 472 473 inline int 474 compare( const CharOrder_Table & i_rOrder, 475 const String & i_s1, 476 const char * i_s2 ) 477 { return compare( i_rOrder, i_s1.c_str(), i_s2 ); } 478 479 inline int 480 compare( const CharOrder_Table & i_rOrder, 481 const char * i_s1, 482 const String & i_s2 ) 483 { return compare( i_rOrder, i_s1, i_s2.c_str() ); } 484 485 486 } // namespace csv 487 488 489 inline bool 490 operator==( const csv::String & i_s1, 491 const char * i_s2 ) 492 { return csv::compare( i_s1, i_s2 ) == 0; } 493 494 inline bool 495 operator!=( const csv::String & i_s1, 496 const char * i_s2 ) 497 { return csv::compare( i_s1, i_s2 ) != 0; } 498 499 inline bool 500 operator<( const csv::String & i_s1, 501 const char * i_s2 ) 502 { return csv::compare( i_s1, i_s2 ) < 0; } 503 504 inline bool 505 operator>( const csv::String & i_s1, 506 const char * i_s2 ) 507 { return csv::compare( i_s1, i_s2 ) > 0; } 508 509 inline bool 510 operator<=( const csv::String & i_s1, 511 const char * i_s2 ) 512 { return csv::compare( i_s1, i_s2 ) <= 0; } 513 514 inline bool 515 operator>=( const csv::String & i_s1, 516 const char * i_s2 ) 517 { return csv::compare( i_s1, i_s2 ) >= 0; } 518 519 520 inline bool 521 operator==( const char * i_s1, 522 const csv::String & i_s2 ) 523 { return csv::compare( i_s1, i_s2 ) == 0; } 524 525 inline bool 526 operator!=( const char * i_s1, 527 const csv::String & i_s2 ) 528 { return csv::compare( i_s1, i_s2 ) != 0; } 529 530 inline bool 531 operator<( const char * i_s1, 532 const csv::String & i_s2 ) 533 { return csv::compare( i_s1, i_s2 ) < 0; } 534 535 inline bool 536 operator>( const char * i_s1, 537 const csv::String & i_s2 ) 538 { return csv::compare( i_s1, i_s2 ) > 0; } 539 540 inline bool 541 operator<=( const char * i_s1, 542 const csv::String & i_s2 ) 543 { return csv::compare( i_s1, i_s2 ) <= 0; } 544 545 inline bool 546 operator>=( const char * i_s1, 547 const csv::String & i_s2 ) 548 { return csv::compare( i_s1, i_s2 ) >= 0; } 549 550 551 //************ global stream operators **************// 552 553 554 inline csv::ostream & 555 operator<<( csv::ostream & o_rOut, 556 const csv::String & i_rSrc ) 557 { o_rOut << i_rSrc.c_str(); return o_rOut; } 558 559 560 561 562 563 //****************** typedefs *********************// 564 565 namespace csv 566 { 567 568 typedef std::vector<String> StringVector; 569 570 } 571 572 573 574 575 #endif 576