/** @file stringutils.cpp @maintainer Morgan McGuire, http://graphics.cs.williams.edu @created 2000-09-09 @edited 2008-01-10 */ #include "G3D/platform.h" #include "G3D/stringutils.h" #include "G3D/BinaryInput.h" #include namespace G3D { #ifdef _MSC_VER // disable: "C++ exception handler used" # pragma warning (push) # pragma warning (disable : 4530) #endif #ifdef G3D_WIN32 const char* NEWLINE = "\r\n"; #else const char* NEWLINE = "\n"; static bool iswspace(int ch) { return (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'); } #endif void parseCommaSeparated(const std::string s, Array& array, bool stripQuotes) { array.fastClear(); if (s == "") { return; } size_t begin = 0; const char delimiter = ','; const char quote = '\"'; do { size_t end = begin; // Find the next comma, or the end of the string bool inQuotes = false; while ((end < s.length()) && (inQuotes || (s[end] != delimiter))) { if (s[end] == quote) { if ((end < s.length() - 2) && (s[end + 1] == quote) && (s[end + 2]) == quote) { // Skip over the superquote end += 2; } inQuotes = ! inQuotes; } ++end; } array.append(s.substr(begin, end - begin)); begin = end + 1; } while (begin < s.length()); if (stripQuotes) { for (int i = 0; i < array.length(); ++i) { std::string& t = array[i]; int L = t.length(); if ((L > 1) && (t[0] == quote) && (t[L - 1] == quote)) { if ((L > 6) && (t[1] == quote) && (t[2] == quote) && (t[L - 3] == quote) && (t[L - 2] == quote)) { // Triple-quote t = t.substr(3, L - 6); } else { // Double-quote t = t.substr(1, L - 2); } } } } } bool beginsWith( const std::string& test, const std::string& pattern) { if (test.size() >= pattern.size()) { for (int i = 0; i < (int)pattern.size(); ++i) { if (pattern[i] != test[i]) { return false; } } return true; } else { return false; } } bool endsWith( const std::string& test, const std::string& pattern) { if (test.size() >= pattern.size()) { int te = test.size() - 1; int pe = pattern.size() - 1; for (int i = pattern.size() - 1; i >= 0; --i) { if (pattern[pe - i] != test[te - i]) { return false; } } return true; } else { return false; } } std::string wordWrap( const std::string& input, int numCols) { std::string output; size_t c = 0; int len; // Don't make lines less than this length int minLength = numCols / 4; size_t inLen = input.size(); bool first = true; while (c < inLen) { if (first) { first = false; } else { output += NEWLINE; } if ((int)inLen - (int)c - 1 < numCols) { // The end output += input.substr(c, inLen - c); break; } len = numCols; // Look at character c + numCols, see if it is a space. while ((len > minLength) && (input[c + len] != ' ')) { len--; } if (len == minLength) { // Just crop len = numCols; } output += input.substr(c, len); c += len; if (c < input.size()) { // Collapse multiple spaces. while ((input[c] == ' ') && (c < input.size())) { c++; } } } return output; } int stringCompare( const std::string& s1, const std::string& s2) { return stringPtrCompare(&s1, &s2); } int stringPtrCompare( const std::string* s1, const std::string* s2) { return s1->compare(*s2); } std::string toUpper(const std::string& x) { std::string result = x; std::transform(result.begin(), result.end(), result.begin(), toupper); return result; } std::string toLower(const std::string& x) { std::string result = x; std::transform(result.begin(), result.end(), result.begin(), tolower); return result; } Array stringSplit( const std::string& x, char splitChar) { Array out; // Pointers to the beginning and end of the substring const char* start = x.c_str(); const char* stop = start; while ((stop = strchr(start, splitChar))) { out.append(std::string(start, stop - start)); start = stop + 1; } // Append the last one out.append(std::string(start)); return out; } std::string stringJoin( const Array& a, char joinChar) { std::string out; for (int i = 0; i < (int)a.size() - 1; ++i) { out += a[i] + joinChar; } if (a.size() > 0) { return out + a.last(); } else { return out; } } std::string stringJoin( const Array& a, const std::string& joinStr) { std::string out; for (int i = 0; i < (int)a.size() - 1; ++i) { out += a[i] + joinStr; } if (a.size() > 0) { return out + a.last(); } else { return out; } } std::string trimWhitespace( const std::string& s) { size_t left = 0; // Trim from left while ((left < s.length()) && iswspace(s[left])) { ++left; } int right = s.length() - 1; // Trim from right while ((right > (int)left) && iswspace(s[right])) { --right; } return s.substr(left, right - left + 1); } }; // namespace #undef NEWLINE #ifdef _MSC_VER # pragma warning (pop) #endif