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> &
Str() const373 String::Str() const
374 { return pd->aStr; }
375
376
377 inline const char &
char_at(position_type i_nPosition) const378 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
operator ==(const self & i_rStr) const385 String::operator==( const self & i_rStr ) const
386 { return compare(i_rStr) == 0; }
387
388 inline bool
operator !=(const self & i_rStr) const389 String::operator!=( const self & i_rStr ) const
390 { return compare(i_rStr) != 0; }
391
392 inline bool
operator <(const self & i_rStr) const393 String::operator<( const self & i_rStr ) const
394 { return compare(i_rStr) < 0; }
395
396 inline bool
operator >(const self & i_rStr) const397 String::operator>( const self & i_rStr ) const
398 { return compare(i_rStr) > 0; }
399
400 inline bool
operator <=(const self & i_rStr) const401 String::operator<=( const self & i_rStr ) const
402 { return compare(i_rStr) <= 0; }
403
404 inline bool
operator >=(const self & i_rStr) const405 String::operator>=( const self & i_rStr ) const
406 { return compare(i_rStr) >= 0; }
407
408 inline void
clear()409 String::clear()
410 { operator=( String::Null_() ); }
411
412 inline const char *
c_str() const413 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 *
data() const421 String::data() const
422 { return c_str(); }
423
424 inline String::size_type
size() const425 String::size() const
426 { return Str().Size(); }
427
428 inline bool
empty() const429 String::empty() const
430 { return size() == 0; }
431
432 inline String::size_type
length() const433 String::length() const
434 { return size(); }
435
436 inline String::const_iterator
begin() const437 String::begin() const
438 { return data(); }
439
440 inline String::const_iterator
end() const441 String::end() const
442 { return data() + size(); }
443
444
445
446 //****************** global compare-functions ********************//
447 inline int
compare(const String & i_s1,const String & i_s2)448 compare( const String & i_s1,
449 const String & i_s2 )
450 { return i_s1.compare(i_s2); }
451
452 inline int
compare(const String & i_s1,const char * i_s2)453 compare( const String & i_s1,
454 const char * i_s2 )
455 { return strcmp(i_s1.c_str(), i_s2); }
456
457 inline int
compare(const char * i_s1,const String & i_s2)458 compare( const char * i_s1,
459 const String & i_s2 )
460 { return strcmp(i_s1, i_s2.c_str()); }
461
462 inline int
compare(const char * i_s1,const char * i_s2)463 compare( const char * i_s1,
464 const char * i_s2 )
465 { return strcmp(i_s1, i_s2); }
466
467 inline int
compare(const char * i_s1,const char * i_s2,str::size i_nLength)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
compare(const CharOrder_Table & i_rOrder,const String & i_s1,const char * i_s2)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
compare(const CharOrder_Table & i_rOrder,const char * i_s1,const String & i_s2)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
operator ==(const csv::String & i_s1,const char * i_s2)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
operator !=(const csv::String & i_s1,const char * i_s2)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
operator <(const csv::String & i_s1,const char * i_s2)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
operator >(const csv::String & i_s1,const char * i_s2)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
operator <=(const csv::String & i_s1,const char * i_s2)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
operator >=(const csv::String & i_s1,const char * i_s2)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
operator ==(const char * i_s1,const csv::String & i_s2)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
operator !=(const char * i_s1,const csv::String & i_s2)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
operator <(const char * i_s1,const csv::String & i_s2)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
operator >(const char * i_s1,const csv::String & i_s2)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
operator <=(const char * i_s1,const csv::String & i_s2)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
operator >=(const char * i_s1,const csv::String & i_s2)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 &
operator <<(csv::ostream & o_rOut,const csv::String & i_rSrc)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