]> git.mxchange.org Git - simgear.git/blob - simgear/misc/strutils.cxx
d33b0a9dcdbd3a72febcf0cf965b4ef46938c2f6
[simgear.git] / simgear / misc / strutils.cxx
1 // String utilities.
2 //
3 // Written by Bernie Bright, started 1998
4 //
5 // Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #include <ctype.h>
24 #include <cstring>
25
26 #include "strutils.hxx"
27
28 using std::string;
29 using std::vector;
30
31 namespace simgear {
32     namespace strutils {
33
34         /**
35          * 
36          */
37         static vector<string>
38         split_whitespace( const string& str, int maxsplit )
39         {
40             vector<string> result;
41             string::size_type len = str.length();
42             string::size_type i = 0;
43             string::size_type j;
44             int countsplit = 0;
45
46             while (i < len)
47             {
48                 while (i < len && isspace((unsigned char)str[i]))
49                 {
50                     ++i;
51                 }
52
53                 j = i;
54
55                 while (i < len && !isspace((unsigned char)str[i]))
56                 {
57                     ++i;
58                 }
59
60                 if (j < i)
61                 {
62                     result.push_back( str.substr(j, i-j) );
63                     ++countsplit;
64                     while (i < len && isspace((unsigned char)str[i]))
65                     {
66                         ++i;
67                     }
68
69                     if (maxsplit && (countsplit >= maxsplit) && i < len)
70                     {
71                         result.push_back( str.substr( i, len-i ) );
72                         i = len;
73                     }
74                 }
75             }
76
77             return result;
78         }
79
80         /**
81          * 
82          */
83         vector<string>
84         split( const string& str, const char* sep, int maxsplit )
85         {
86             if (sep == 0)
87                 return split_whitespace( str, maxsplit );
88
89             vector<string> result;
90             int n = std::strlen( sep );
91             if (n == 0)
92             {
93                 // Error: empty separator string
94                 return result;
95             }
96             const char* s = str.c_str();
97             string::size_type len = str.length();
98             string::size_type i = 0;
99             string::size_type j = 0;
100             int splitcount = 0;
101
102             while (i+n <= len)
103             {
104                 if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0))
105                 {
106                     result.push_back( str.substr(j,i-j) );
107                     i = j = i + n;
108                     ++splitcount;
109                     if (maxsplit && (splitcount >= maxsplit))
110                         break;
111                 }
112                 else
113                 {
114                     ++i;
115                 }
116             }
117
118             result.push_back( str.substr(j,len-j) );
119             return result;
120         }
121
122         /**
123          * The lstrip(), rstrip() and strip() functions are implemented
124          * in do_strip() which uses an additional parameter to indicate what
125          * type of strip should occur.
126          */
127         const int LEFTSTRIP = 0;
128         const int RIGHTSTRIP = 1;
129         const int BOTHSTRIP = 2;
130
131         static string
132         do_strip( const string& s, int striptype )
133         {
134             //     if (s.empty())
135             //      return s;
136
137             string::size_type len = s.length();
138             string::size_type i = 0;
139             if (striptype != RIGHTSTRIP)
140             {
141                 while (i < len && isspace(s[i]))
142                 {
143                     ++i;
144                 }
145             }
146
147             string::size_type j = len;
148             if (striptype != LEFTSTRIP)
149             {
150                 do
151                 {
152                     --j;
153                 }
154                 while (j >= 1 && isspace(s[j]));
155                 ++j;
156             }
157
158             if (i == 0 && j == len)
159             {
160                 return s;
161             }
162             else
163             {
164                 return s.substr( i, j - i );
165             }
166         }
167
168         string
169         lstrip( const string& s )
170         {
171             return do_strip( s, LEFTSTRIP );
172         }
173
174         string
175         rstrip( const string& s )
176         {
177             return do_strip( s, RIGHTSTRIP );
178         }
179
180         string
181         strip( const string& s )
182         {
183             return do_strip( s, BOTHSTRIP );
184         }
185
186     } // end namespace strutils
187 } // end namespace simgear