3 This file is part of libmspstrings
4 Copyright © 2006-2008 Mikko Rasa
5 Distributed under the LGPL
10 #include <msp/core/except.h>
17 template<bool long_sep, bool allow_empty>
18 vector<string> do_split(const string &str, const string &sep, int max_split)
20 vector<string> result;
23 while(start<str.size())
25 unsigned end=long_sep ? str.find(sep, start) : str.find_first_of(sep, start);
26 if(end!=start || allow_empty)
28 if(max_split>=0 && result.size()==static_cast<unsigned>(max_split))
30 result.push_back(str.substr(start));
34 result.push_back(str.substr(start, end-start));
40 start=end+(long_sep ? sep.size() : 1);
42 if(allow_empty && start==str.size())
43 result.push_back(string());
49 bool check_str(const std::string &str, int (*pred)(int))
51 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
61 int strcasecmp(const string &s1, const string &s2)
63 string::const_iterator i1=s1.begin();
64 string::const_iterator i2=s2.begin();
65 for(; (i1!=s1.end() && i2!=s2.end()); ++i1, ++i2)
67 const char c1=::tolower(*i1);
68 const char c2=::tolower(*i2);
69 if(c1!=c2) return c1-c2;
71 if(i1!=s1.end()) return *i1;
72 if(i2!=s2.end()) return -*i2;
76 string tolower(const string &str)
79 transform(result.begin(), result.end(), result.begin(), ::tolower);
83 string toupper(const string &str)
86 transform(result.begin(), result.end(), result.begin(), ::toupper);
90 bool isnumrc(const string &str)
92 return check_str(str, isdigit);
95 bool isalpha(const string &str)
97 return check_str(str, isalpha);
100 bool isalnum(const string &str)
102 return check_str(str, isalnum);
105 vector<string> split(const string &str, const string &sep, int max_split)
107 return do_split<false, false>(str, sep, max_split);
110 vector<string> split(const string &str, char sep, int max_split)
112 return split(str, string(1, sep), max_split);
115 vector<string> split_long(const string &str, const string &sep, int max_split)
117 return do_split<true, false>(str, sep, max_split);
120 vector<string> split_fields(const string &str, const string &sep, int max_split)
122 return do_split<true, true>(str, sep, max_split);
125 vector<string> split_fields(const string &str, char sep, int max_split)
127 return split_fields(str, string(1, sep), max_split);
131 Splits a string to parts.
133 @param str String to be split
134 @param sep A set of separator characters
135 @param allow_empty Whether or not to produce empty parts for sequences of
136 more than one separator character
138 vector<string> split(const string &str, const string &sep, bool allow_empty)
140 vector<string> result;
144 start=str.find_first_not_of(sep);
146 while(start<str.size())
148 unsigned end=str.find_first_of(sep, start);
149 result.push_back(str.substr(start, end-start));
151 if(end==string::npos)
157 if(start==str.size())
158 result.push_back(string());
161 start=str.find_first_not_of(sep, end);
167 vector<string> split(const string &str, char sep, bool allow_empty)
169 return split(str, string(1, sep), allow_empty);
172 string strip(const string &s)
175 if(!result.erase(0, result.find_first_not_of(" \t\r\n")).empty())
176 result.erase(result.find_last_not_of(" \t\r\n")+1);
180 string c_unescape(const std::string &str)
183 unsigned numeric_type=0;
184 unsigned numeric_pos=0;
185 unsigned numeric_value=0;
187 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
192 if(*i>='0' && *i<='9')
194 else if(*i>='a' && *i<='f')
196 else if(*i>='A' && *i<='F')
199 throw InvalidParameterValue("Invalid hexadecimal digit");
201 numeric_value=(numeric_value<<4 | digit);
205 result+=numeric_value;
209 else if(numeric_type==8)
212 if(*i>='0' && *i<='7')
215 throw InvalidParameterValue("Invalid octal digit");
217 numeric_value=(numeric_value<<3 | digit);
221 result+=numeric_value;
233 else if(*i>='0' && *i<='3')
237 numeric_value=*i-'0';
260 throw InvalidParameterValue("Invalid escape sequence");
271 throw InvalidParameterValue("Stray backslash at end of string");
276 string c_escape(const string &str, bool escape_8bit)
280 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
302 else if(static_cast<unsigned char>(*i)<' ' || (escape_8bit && (*i&0x80)))
304 char buf[4]={'\\', '0'+((*i>>6)&3), '0'+((*i>>3)&7), '0'+(*i&7)};
305 result.append(buf, 4);