00001
00020 #include <algorithm>
00021 #include <iostream>
00022 #include <cstring>
00023 #include <stdio.h>
00024 #include <stdarg.h>
00025 #include <limits.h>
00026 #include <coil/stringutil.h>
00027 #include <string.h>
00028 #include <cctype>
00029 #include <cstdio>
00030
00031 namespace coil
00032 {
00040 std::wstring string2wstring(std::string str)
00041 {
00042 std::wstring wstr(str.length(), L' ');
00043 std::copy(str.begin(),str.end(),wstr.begin());
00044 return wstr;
00045 }
00046
00054 std::string wstring2string(std::wstring wstr)
00055 {
00056 std::string str(wstr.length(), ' ');
00057 std::copy(wstr.begin(), wstr.end(), str.begin());
00058 return str;
00059 }
00060
00068 void toUpper(std::string& str)
00069 {
00070 std::transform(str.begin(), str.end(), str.begin(),
00071 (int (*)(int))std::toupper);
00072 }
00073
00081 void toLower(std::string& str)
00082 {
00083 std::transform(str.begin(), str.end(), str.begin(),
00084 (int (*)(int))std::tolower);
00085 }
00086
00094 int getlinePortable(std::istream& istr, std::string& line)
00095 {
00096 char c;
00097 std::stringstream s;
00098
00099 while (istr.get(c))
00100 {
00101 if (c == '\n')
00102 {
00103 break;
00104 }
00105 else if (c == '\r')
00106 {
00107 if (istr.peek() == '\n')
00108 {
00109 istr.ignore();
00110 }
00111 break;
00112 }
00113 else
00114 {
00115 s << c;
00116 }
00117 }
00118 line = s.str();
00119 return static_cast<int>(line.size());
00120 }
00121
00129 bool isEscaped(const std::string& str, std::string::size_type pos)
00130 {
00131 --pos;
00132 unsigned int i;
00133 for (i = 0; (pos >= 0) && str[pos] == '\\'; --pos, ++i) ;
00134
00135 return (i % 2) == 1;
00136 }
00137
00145 struct escape_functor
00146 {
00147 escape_functor() {};
00148 void operator()(const char c)
00149 {
00150 if (c == '\t') str += "\\t";
00151 else if (c == '\n') str += "\\n";
00152 else if (c == '\f') str += "\\f";
00153 else if (c == '\r') str += "\\r";
00154 else if (c == '\\') str += "\\\\";
00155
00156
00157 else str.push_back(c);
00158 }
00159 std::string str;
00160 };
00161
00169 std::string escape(const std::string str)
00170 {
00171 return for_each(str.begin(), str.end(), escape_functor()).str;
00172 }
00173
00181 struct unescape_functor
00182 {
00183 unescape_functor() : count(0) {};
00184 void operator()(char c)
00185 {
00186 if (c == '\\')
00187 {
00188 ++count;
00189 if (!(count % 2))
00190 {
00191 str.push_back(c);
00192 }
00193 }
00194 else
00195 {
00196 if (count > 0 && (count % 2))
00197 {
00198 count = 0;
00199 if (c == 't') str.push_back('\t');
00200 else if (c == 'n') str.push_back('\n');
00201 else if (c == 'f') str.push_back('\f');
00202 else if (c == 'r') str.push_back('\r');
00203 else if (c == '\"') str.push_back('\"');
00204 else if (c == '\'') str.push_back('\'');
00205 else str.push_back(c);
00206 }
00207 else
00208 {
00209 count = 0;
00210 str.push_back(c);
00211 }
00212 }
00213 }
00214 std::string str;
00215 int count;
00216 };
00217
00225 std::string unescape(const std::string str)
00226 {
00227 return for_each(str.begin(), str.end(), unescape_functor()).str;
00228 }
00229
00237 void eraseBlank(std::string& str)
00238 {
00239 std::string::iterator it(str.begin());
00240
00241 while (it != str.end())
00242 {
00243 if (*it == ' ' || *it == '\t')
00244 {
00245 it = str.erase(it);
00246 }
00247 else
00248 {
00249 ++it;
00250 }
00251 }
00252
00253 }
00254
00262 void eraseHeadBlank(std::string& str)
00263 {
00264 if (str.empty()) return;
00265 while (str[0] == ' ' || str[0] == '\t') str.erase(0, 1);
00266 }
00267
00275 void eraseTailBlank(std::string& str)
00276 {
00277 if (str.empty()) return;
00278 while ((str[str.size() - 1] == ' ' || str[str.size() - 1] == '\t') &&
00279 !isEscaped(str, str.size() - 1))
00280 str.erase(str.size() - 1, 1);
00281 }
00282
00290 void eraseBothEndsBlank(std::string& str)
00291 {
00292 eraseHeadBlank(str);
00293 eraseTailBlank(str);
00294 }
00295
00303 std::string normalize(std::string& str)
00304 {
00305 eraseBothEndsBlank(str);
00306 toLower(str);
00307 return str;
00308 }
00309
00317 unsigned int replaceString(std::string& str, const std::string from,
00318 const std::string to)
00319 {
00320 std::string::size_type pos(0);
00321 unsigned int cnt(0);
00322
00323 while (pos != std::string::npos)
00324 {
00325 pos = str.find(from, pos);
00326 if (pos == std::string::npos) break;
00327 str.replace(pos, from.size(), to);
00328 pos += to.size();
00329 ++cnt;
00330 }
00331 return cnt;
00332 }
00333
00341 vstring split(const std::string& input,
00342 const std::string& delimiter,
00343 bool ignore_empty)
00344 {
00345 typedef std::string::size_type size;
00346 vstring results;
00347 size delim_size = delimiter.size();
00348 size found_pos(0), begin_pos(0), pre_pos(0), substr_size(0);
00349
00350 if (input.empty()) return results;
00351
00352
00353
00354
00355 while (1)
00356 {
00357
00358 found_pos = input.find(delimiter, begin_pos);
00359 if (found_pos == std::string::npos)
00360 {
00361 std::string substr(input.substr(pre_pos));
00362 eraseHeadBlank(substr);
00363 eraseTailBlank(substr);
00364 if (!(substr.empty() && ignore_empty)) results.push_back(substr);
00365 break;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374 substr_size = found_pos - pre_pos;
00375 if (substr_size >= 0)
00376 {
00377 std::string substr(input.substr(pre_pos, substr_size));
00378 eraseHeadBlank(substr);
00379 eraseTailBlank(substr);
00380 if (!(substr.empty() && ignore_empty)) results.push_back(substr);
00381 }
00382 begin_pos = found_pos + delim_size;
00383 pre_pos = found_pos + delim_size;
00384 }
00385 return results;
00386 }
00387
00395 struct Toupper
00396 {
00397 void operator()(char &c)
00398 {
00399 c = toupper(c);
00400 }
00401 };
00402
00410 bool toBool(std::string str, std::string yes, std::string no,
00411 bool default_value)
00412 {
00413 std::for_each(str.begin(), str.end(), Toupper());
00414 std::for_each(yes.begin(), yes.end(), Toupper());
00415 std::for_each(no.begin(), no.end(), Toupper());
00416
00417 if (str.find(yes) != std::string::npos)
00418 return true;
00419 else if (str.find(no) != std::string::npos)
00420 return false;
00421 else
00422 return default_value;
00423 }
00424
00432 bool includes(const vstring& list, std::string value, bool ignore_case)
00433 {
00434 if (ignore_case) { toLower(value); }
00435
00436 for (int i(0), len(static_cast<int>(list.size())); i < len; ++i)
00437 {
00438 std::string str(list[i]);
00439 if (ignore_case) { toLower(str); }
00440 if (str == value) return true;
00441 }
00442 return false;
00443 }
00444
00452 bool includes(const std::string& list, std::string value, bool ignore_case)
00453 {
00454 vstring vlist(split(list, ","));
00455 return includes(vlist, value, ignore_case);
00456 }
00457
00465 bool isAbsolutePath(const std::string& str)
00466 {
00467
00468 if (str[0] == '/') return true;
00469
00470 if (isalpha(str[0]) && (str[1] == ':') && str[2] == '\\') return true;
00471
00472 if (str[0] == '\\' && str[1] == '\\') return true;
00473
00474 return false;
00475 }
00476
00484 bool isURL(const std::string& str)
00485 {
00486 typedef std::string::size_type size;
00487 size pos;
00488 if (str.empty()) return false;
00489 pos = str.find(":");
00490 if ((pos != 0) &&
00491 (pos != std::string::npos) &&
00492 (str[pos + 1] == '/') &&
00493 (str[pos + 2] == '/'))
00494 return true;
00495 return false;
00496 }
00497
00505 struct unique_strvec
00506 {
00507 void operator()(const std::string& s)
00508 {
00509 if (std::find(str.begin(), str.end(), s) == str.end())
00510 return str.push_back(s);
00511 }
00512 vstring str;
00513 };
00514
00522 template<>
00523 bool stringTo<std::string>(std::string& val, const char* str)
00524 {
00525 if (str == 0) { return false; }
00526 val = str;
00527 return true;
00528 }
00529
00537 vstring unique_sv(vstring sv)
00538 {
00539 return std::for_each(sv.begin(), sv.end(), unique_strvec()).str;
00540 }
00541
00549 std::string flatten(vstring sv)
00550 {
00551 if (sv.size() == 0) return "";
00552
00553 std::string str;
00554 for (size_t i(0), len(sv.size() - 1); i < len; ++i)
00555 {
00556 str += sv[i] + ", ";
00557 }
00558 return str + sv.back();
00559 }
00560
00568 char** toArgv(const vstring& args)
00569 {
00570 char** argv;
00571 size_t argc(args.size());
00572
00573 argv = new char*[argc + 1];
00574
00575 for (size_t i(0); i < argc; ++i)
00576 {
00577 size_t sz(args[i].size());
00578 argv[i] = new char[sz + 1];
00579 strncpy(argv[i], args[i].c_str(), sz);
00580 argv[i][sz] = '\0';
00581 }
00582 argv[argc] = NULL;
00583 return argv;
00584 }
00585
00593 std::string sprintf(char const * __restrict fmt, ...)
00594 {
00595 #ifndef LINE_MAX
00596 #define LINE_MAX 1024
00597 #endif
00598 char str[LINE_MAX];
00599 va_list ap;
00600
00601 va_start(ap, fmt);
00602 #ifdef WIN32
00603 _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00604 #else
00605 vsnprintf(str, LINE_MAX - 1, fmt, ap);
00606 #endif
00607 va_end(ap);
00608 return std::string(str);
00609 }
00610
00611 };