str.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * Additionally this file is based on the ScummVM source code.
  8. * Copyright information for the ScummVM source code is
  9. * available in the COPYRIGHT file of the ScummVM source
  10. * distribution.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  25. */
  26. #include "common/str.h"
  27. #include "common/util.h"
  28. #include <stdarg.h>
  29. #if !defined(__SYMBIAN32__)
  30. #include <new>
  31. #endif
  32. namespace Common {
  33. String::String(const char *str) {
  34. initWithCStr(str, strlen(str));
  35. }
  36. String::String(const char *str, uint32 len) {
  37. initWithCStr(str, len);
  38. }
  39. String::String(const char *beginP, const char *endP) {
  40. assert(endP >= beginP);
  41. initWithCStr(beginP, endP - beginP);
  42. }
  43. void String::initWithCStr(const char *str, uint32 len) {
  44. assert(str);
  45. _str = std::string(str, len);
  46. }
  47. String::String(const String &str)
  48. {
  49. _str = str._str;
  50. }
  51. String::String(char c)
  52. {
  53. _str += c;
  54. }
  55. String::~String()
  56. {
  57. }
  58. String& String::operator =(const char *str) {
  59. _str = std::string(str);
  60. return *this;
  61. }
  62. String &String::operator =(const String &str) {
  63. if (&str == this)
  64. return *this;
  65. _str = str._str;
  66. return *this;
  67. }
  68. String& String::operator =(char c) {
  69. _str.clear();
  70. _str += c;
  71. return *this;
  72. }
  73. String &String::operator +=(const char *str) {
  74. _str += std::string(str);
  75. return *this;
  76. }
  77. String &String::operator +=(const String &str) {
  78. if (&str == this)
  79. return operator+=(Common::String(str));
  80. _str += str._str;
  81. return *this;
  82. }
  83. String &String::operator +=(char c) {
  84. _str += c;
  85. return *this;
  86. }
  87. bool String::hasPrefix(const String &x) const {
  88. return hasPrefix(x.c_str());
  89. }
  90. bool String::hasPrefix(const char *x) const {
  91. assert(x != 0);
  92. // Compare x with the start of _str.
  93. const char *y = c_str();
  94. while (*x && *x == *y) {
  95. ++x;
  96. ++y;
  97. }
  98. // It's a prefix, if and only if all letters in x are 'used up' before
  99. // _str ends.
  100. return *x == 0;
  101. }
  102. bool String::hasSuffix(const String &x) const {
  103. return hasSuffix(x.c_str());
  104. }
  105. bool String::hasSuffix(const char *x) const {
  106. assert(x != 0);
  107. // Compare x with the end of _str.
  108. const uint32 x_size = strlen(x);
  109. if (x_size > _str.size())
  110. return false;
  111. const char *y = c_str() + _str.size() - x_size;
  112. while (*x && *x == *y) {
  113. ++x;
  114. ++y;
  115. }
  116. // It's a suffix, if and only if all letters in x are 'used up' before
  117. // _str ends.
  118. return *x == 0;
  119. }
  120. bool String::contains(const String &x) const {
  121. return strstr(c_str(), x.c_str()) != NULL;
  122. }
  123. bool String::contains(const char *x) const {
  124. assert(x != 0);
  125. return strstr(c_str(), x) != NULL;
  126. }
  127. bool String::contains(char x) const {
  128. return strchr(c_str(), x) != NULL;
  129. }
  130. bool String::matchString(const char *pat, bool ignoreCase, bool pathMode) const {
  131. return Common::matchString(c_str(), pat, ignoreCase, pathMode);
  132. }
  133. bool String::matchString(const String &pat, bool ignoreCase, bool pathMode) const {
  134. return Common::matchString(c_str(), pat.c_str(), ignoreCase, pathMode);
  135. }
  136. void String::clear() {
  137. _str.clear();
  138. }
  139. void String::setChar(char c, uint32 p) {
  140. assert(p <= _str.size());
  141. _str[p] = c;
  142. }
  143. void String::insertChar(char c, uint32 p) {
  144. assert(p <= _str.size());
  145. _str += c;
  146. for (auto i = _str.size(); i > p; --i)
  147. _str[i] = _str[i-1];
  148. _str[p] = c;
  149. }
  150. void String::toLowercase() {
  151. for (auto i = 0u; i < _str.size(); ++i)
  152. _str[i] = static_cast<char>(tolower(_str[i]));
  153. }
  154. void String::toUppercase() {
  155. for (auto i = 0u; i < _str.size(); ++i)
  156. _str[i] = static_cast<char>(toupper(_str[i]));
  157. }
  158. bool String::operator ==(const String &x) const {
  159. return equals(x);
  160. }
  161. bool String::operator ==(const char *x) const {
  162. assert(x != 0);
  163. return equals(x);
  164. }
  165. bool String::operator !=(const String &x) const {
  166. return !equals(x);
  167. }
  168. bool String::operator !=(const char *x) const {
  169. assert(x != 0);
  170. return !equals(x);
  171. }
  172. bool String::operator < (const String &x) const {
  173. return compareTo(x) < 0;
  174. }
  175. bool String::operator <= (const String &x) const {
  176. return compareTo(x) <= 0;
  177. }
  178. bool String::operator > (const String &x) const {
  179. return compareTo(x) > 0;
  180. }
  181. bool String::operator >= (const String &x) const {
  182. return compareTo(x) >= 0;
  183. }
  184. bool operator == (const char* y, const String &x) {
  185. return (x == y);
  186. }
  187. bool operator != (const char* y, const String &x) {
  188. return x != y;
  189. }
  190. bool String::equals(const String &x) const {
  191. return (0 == compareTo(x));
  192. }
  193. bool String::equals(const char *x) const {
  194. assert(x != 0);
  195. return (0 == compareTo(x));
  196. }
  197. bool String::equalsIgnoreCase(const String &x) const {
  198. return (0 == compareToIgnoreCase(x));
  199. }
  200. bool String::equalsIgnoreCase(const char *x) const {
  201. assert(x != 0);
  202. return (0 == compareToIgnoreCase(x));
  203. }
  204. int String::compareTo(const String &x) const {
  205. return compareTo(x.c_str());
  206. }
  207. int String::compareTo(const char *x) const {
  208. assert(x != 0);
  209. return strcmp(c_str(), x);
  210. }
  211. int String::compareToIgnoreCase(const String &x) const {
  212. return compareToIgnoreCase(x.c_str());
  213. }
  214. int String::compareToIgnoreCase(const char *x) const {
  215. assert(x != 0);
  216. return scumm_stricmp(c_str(), x);
  217. }
  218. String operator +(const String &x, const String &y) {
  219. String temp(x);
  220. temp += y;
  221. return temp;
  222. }
  223. String operator +(const char *x, const String &y) {
  224. String temp(x);
  225. temp += y;
  226. return temp;
  227. }
  228. String operator +(const String &x, const char *y) {
  229. String temp(x);
  230. temp += y;
  231. return temp;
  232. }
  233. String operator +(char x, const String &y) {
  234. String temp(x);
  235. temp += y;
  236. return temp;
  237. }
  238. String operator +(const String &x, char y) {
  239. String temp(x);
  240. temp += y;
  241. return temp;
  242. }
  243. char *ltrim(char *t) {
  244. while (isspace(*t))
  245. t++;
  246. return t;
  247. }
  248. char *rtrim(char *t) {
  249. int l = strlen(t) - 1;
  250. while (l >= 0 && isspace(t[l]))
  251. t[l--] = 0;
  252. return t;
  253. }
  254. char *trim(char *t) {
  255. return rtrim(ltrim(t));
  256. }
  257. Common::String lastPathComponent(const Common::String &path, const char sep) {
  258. const char *str = path.c_str();
  259. const char *last = str + path.size();
  260. // Skip over trailing slashes
  261. while (last > str && *(last-1) == sep)
  262. --last;
  263. // Path consisted of only slashes -> return empty string
  264. if (last == str)
  265. return Common::String();
  266. // Now scan the whole component
  267. const char *first = last - 1;
  268. while (first >= str && *first != sep)
  269. --first;
  270. if (*first == sep)
  271. first++;
  272. return Common::String(first, last);
  273. }
  274. Common::String normalizePath(const Common::String &path, const char sep) {
  275. if (path.empty())
  276. return path;
  277. const char *cur = path.c_str();
  278. Common::String result;
  279. // If there is a leading slash, preserve that:
  280. if (*cur == sep) {
  281. result += sep;
  282. while (*cur == sep)
  283. ++cur;
  284. }
  285. // Scan till the end of the String
  286. while (*cur != 0) {
  287. const char *start = cur;
  288. // Scan till the next path separator resp. the end of the string
  289. while (*cur != sep && *cur != 0)
  290. cur++;
  291. const Common::String component(start, cur);
  292. // Skip empty components and dot components, add all others
  293. if (!component.empty() && component != ".") {
  294. // Add a separator before the component, unless the result
  295. // string already ends with one (which happens only if the
  296. // path *starts* with a separator).
  297. if (!result.empty() && result.lastChar() != sep)
  298. result += sep;
  299. // Add the component
  300. result += component;
  301. }
  302. // Skip over separator chars
  303. while (*cur == sep)
  304. cur++;
  305. }
  306. return result;
  307. }
  308. bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMode) {
  309. assert(str);
  310. assert(pat);
  311. const char *p = 0;
  312. const char *q = 0;
  313. for (;;) {
  314. if (pathMode && *str == '/') {
  315. p = 0;
  316. q = 0;
  317. if (*pat == '?')
  318. return false;
  319. }
  320. switch (*pat) {
  321. case '*':
  322. // Record pattern / string position for backtracking
  323. p = ++pat;
  324. q = str;
  325. // If pattern ended with * -> match
  326. if (!*pat)
  327. return true;
  328. break;
  329. default:
  330. if ((!ignoreCase && *pat != *str) ||
  331. (ignoreCase && tolower(*pat) != tolower(*str))) {
  332. if (p) {
  333. // No match, oops -> try to backtrack
  334. pat = p;
  335. str = ++q;
  336. if (!*str)
  337. return !*pat;
  338. break;
  339. }
  340. else
  341. return false;
  342. }
  343. // fallthrough
  344. case '?':
  345. if (!*str)
  346. return !*pat;
  347. pat++;
  348. str++;
  349. }
  350. }
  351. }
  352. } // End of namespace Common