Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/util/String.cc @ 1020

Last change on this file since 1020 was 1020, checked in by landauf, 16 years ago

changed ConfigValueContainer to use ConfigFileManager, but there is still an error

File size: 10.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program 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
15 *   GNU 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 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      Benjamin Grauer
25 *
26 */
27
28#include <cctype>
29
30#include "String.h"
31
32/**
33    @brief Removes all whitespaces from a string.
34    @param str The string to strip
35*/
36void strip(std::string* str)
37{
38    unsigned int pos;
39    while ((pos = (*str).find(" ")) < (*str).length())
40        (*str).erase(pos, 1);
41    while ((pos = (*str).find("\t")) < (*str).length())
42        (*str).erase(pos, 1);
43}
44
45/**
46    @brief Returns a copy of a string without whitespaces.
47    @param str The string to strip
48    @return The stripped line
49*/
50std::string getStripped(const std::string& str)
51{
52    std::string output = std::string(str);
53    strip(&output);
54    return output;
55}
56
57/**
58    @brief Returns a copy of a string without trailing whitespaces.
59    @param str The string
60    @return The modified copy
61*/
62std::string removeTrailingWhitespaces(const std::string& str)
63{
64    unsigned int pos1 = 0;
65    unsigned int pos2 = str.size() - 1;
66    for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);
67    for (; pos2 >= 0         && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);
68    return str.substr(pos1, pos2 - pos1 + 1);
69}
70
71/**
72    @brief Returns the position of the next quote in the string, starting with start.
73    @param str The string
74    @param start The startposition
75    @return The position of the next quote (std::string::npos if there is no next quote)
76*/
77unsigned int getNextQuote(const std::string& str, unsigned int start)
78{
79    unsigned int quote = start - 1;
80
81    while ((quote = str.find('\"', quote + 1)) != std::string::npos)
82    {
83        unsigned int backslash = quote;
84        unsigned int numbackslashes = 0;
85        for (; backslash > 0; backslash--, numbackslashes++)
86            if (str[backslash - 1] != '\\')
87                break;
88
89        if (numbackslashes % 2 == 0)
90            break;
91    }
92
93    return quote;
94}
95
96/**
97    @brief Returns true if the string contains something like '..."between quotes"...'
98    @param The string
99    @return True if there is something between quotes
100*/
101bool hasStringBetweenQuotes(const std::string& str)
102{
103    unsigned int pos1 = getNextQuote(str, 0);
104    unsigned int pos2 = getNextQuote(str, pos1 + 1);
105    return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);
106}
107
108/**
109    @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).
110    @param The string
111    @param The string between the quotes
112*/
113std::string getStringBetweenQuotes(const std::string& str)
114{
115    unsigned int pos1 = getNextQuote(str, 0);
116    unsigned int pos2 = getNextQuote(str, pos1 + 1);
117    if (pos1 != std::string::npos && pos2 != std::string::npos)
118        return str.substr(pos1, pos2 - pos1 + 1);
119    else
120        return "";
121}
122
123/**
124    @brief Removes enclosing quotes if available.
125    @brief str The string to strip
126*/
127void stripEnclosingQuotes(std::string* str)
128{
129    unsigned int start = std::string::npos;
130    unsigned int end = 0;
131
132    for (unsigned int pos = 0; (pos < (*str).size()) && (pos < std::string::npos); pos++)
133    {
134        if ((*str)[pos] == '"')
135        {
136            start = pos;
137            break;
138        }
139
140        if (((*str)[pos] != ' ') && ((*str)[pos] != '\t') && ((*str)[pos] != '\n'))
141            return;
142    }
143
144    for (unsigned int pos = (*str).size() - 1; pos < std::string::npos; pos--)
145    {
146        if ((*str)[pos] == '"')
147        {
148            end = pos;
149            break;
150        }
151
152        if (((*str)[pos] != ' ') && ((*str)[pos] != '\t') && ((*str)[pos] != '\n'))
153            return;
154    }
155
156    if ((start != std::string::npos) && (end != 0))
157        (*str) = (*str).substr(start + 1, end - start - 1);
158}
159
160/**
161    @brief Returns a copy of the string with removed enclosing quotes (if available).
162    @brief str The string to strip
163    @return The striped copy of the string
164*/
165std::string getStrippedEnclosingQuotes(const std::string& str)
166{
167    std::string output = std::string(str);
168    stripEnclosingQuotes(&output);
169    return output;
170}
171
172/**
173    @brief Determines if a string in is a comment.
174    @param str The string to check
175    @return True = it's a comment
176
177    A comment is defined by a leading '#', '%', ';' or '//'.
178*/
179bool isComment(const std::string& str)
180{
181    // Strip the line, whitespaces are disturbing
182    std::string teststring = getStripped(str);
183
184    // There are four possible comment-symbols:
185    //  1) #comment in script-language style
186    //  2) %comment in matlab style
187    //  3) ;comment in unreal tournament config-file style
188    //  4) //comment in code style
189    if (teststring.size() >= 2)
190    {
191        if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))
192            return true;
193    }
194    else if (teststring.size() == 1)
195    {
196        if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')
197            return true;
198    }
199
200    return false;
201}
202
203/**
204    @brief Determines if a string is empty (contains only whitespaces).
205    @param str The string to check
206    @return True = it's empty
207*/
208bool isEmpty(const std::string& str)
209{
210    std::string temp = getStripped(str);
211    return ((temp == "") || (temp.size() == 0));
212}
213
214/**
215    @brief Determines if a string contains only numbers and maximal one '.'.
216    @param str The string to check
217    @return True = it's a number
218*/
219bool isNumeric(const std::string& str)
220{
221    bool foundPoint = false;
222
223    for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
224    {
225        if (((*it) < '0' || (*it) > '9'))
226        {
227            if ((*it) != '.' && !foundPoint)
228                foundPoint = true;
229            else
230                return false;
231        }
232    }
233
234    return true;
235}
236
237/**
238    @brief Replaces each char between A and Z with its lowercase equivalent.
239    @param str The string to convert
240*/
241void lowercase(std::string* str)
242{
243    for (unsigned int i = 0; i < str->size(); ++i)
244    {
245        (*str)[i] = tolower((*str)[i]);
246    }
247}
248
249/**
250    @brief Returns a copy of the given string without uppercase chars.
251    @param str The string
252    @return The copy
253*/
254std::string getLowercase(const std::string& str)
255{
256    std::string output = std::string(str);
257    lowercase(&output);
258    return output;
259}
260
261/**
262    @brief Replaces each char between a and z with its uppercase equivalent.
263    @param str The string to convert
264*/
265void uppercase(std::string* str)
266{
267    for (unsigned int i = 0; i < str->size(); ++i)
268    {
269        (*str)[i] = toupper((*str)[i]);
270    }
271}
272
273/**
274    @brief Returns a copy of the given string without lowercase chars.
275    @param str The string
276    @return The copy
277*/
278std::string getUppercase(const std::string& str)
279{
280    std::string output = std::string(str);
281    uppercase(&output);
282    return output;
283}
284
285/**
286    @brief compares two strings without ignoring the case
287    @param s1 first string
288    @param s2 second string
289*/
290int nocaseCmp(const std::string& s1, const std::string& s2)
291{
292    std::string::const_iterator it1=s1.begin();
293    std::string::const_iterator it2=s2.begin();
294
295    //stop when either string's end has been reached
296    while ( (it1!=s1.end()) && (it2!=s2.end()) )
297    {
298        if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
299            // return -1 to indicate smaller than, 1 otherwise
300            return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
301        //proceed to the next character in each string
302        ++it1;
303        ++it2;
304    }
305    size_t size1=s1.size(), size2=s2.size();// cache lengths
306    //return -1,0 or 1 according to strings' lengths
307    if (size1==size2)
308        return 0;
309    return (size1<size2) ? -1 : 1;
310}
311
312
313/**
314    @brief compares two strings without ignoring the case
315    @param s1 first string
316    @param s2 second string
317    @param len how far from the beginning to start.
318*/
319int nocaseCmp(const std::string& s1, const std::string& s2, unsigned int len)
320{
321    if (len == 0)
322        return 0;
323    std::string::const_iterator it1=s1.begin();
324    std::string::const_iterator it2=s2.begin();
325
326    //stop when either string's end has been reached
327    while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)
328    {
329        if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
330            // return -1 to indicate smaller than, 1 otherwise
331            return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
332        //proceed to the next character in each string
333        ++it1;
334        ++it2;
335    }
336    return 0;
337}
338
339/**
340    @brief Returns true if the string contains a comment, introduced by #, %, ; or //.
341    @param str The string
342    @return True if the string contains a comment
343*/
344bool hasComment(const std::string& str)
345{
346    return (getCommentPosition(str) != std::string::npos);
347}
348
349/**
350    @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.
351    @param str The string
352    @return The comment
353*/
354std::string getComment(const std::string& str)
355{
356    return str.substr(getCommentPosition(str));
357}
358
359/**
360    @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.
361    @param str The string
362    @return The position
363*/
364unsigned int getCommentPosition(const std::string& str)
365{
366    for (unsigned int i = 0; i < str.size(); i++)
367        if (isComment(str.substr(i)))
368            return i;
369
370    return std::string::npos;
371}
Note: See TracBrowser for help on using the repository browser.