xref: /aoo4110/main/cosv/inc/cosv/string.hxx (revision b1cdbd2c)
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