PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/source/utils/string/string.cpp

https://github.com/grapefrukt/poro
C++ | 553 lines | 333 code | 133 blank | 87 comment | 97 complexity | 9ccae87f99ebc000ceef420ce645193e MD5 | raw file
  1. /***************************************************************************
  2. *
  3. * Copyright (c) 2003 - 2011 Petri Purho
  4. *
  5. * This software is provided 'as-is', without any express or implied
  6. * warranty. In no event will the authors be held liable for any damages
  7. * arising from the use of this software.
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. * 1. The origin of this software must not be misrepresented; you must not
  12. * claim that you wrote the original software. If you use this software
  13. * in a product, an acknowledgment in the product documentation would be
  14. * appreciated but is not required.
  15. * 2. Altered source versions must be plainly marked as such, and must not be
  16. * misrepresented as being the original software.
  17. * 3. This notice may not be removed or altered from any source distribution.
  18. *
  19. ***************************************************************************/
  20. ///////////////////////////////////////////////////////////////////////////////
  21. //
  22. // string.cpp
  23. //
  24. // Writen 10.10.2003
  25. // by Petri Purho ( pete@markkupurho.fi )
  26. //
  27. // You are free to use this as you wish.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. #include "string.h"
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33. // #include "../../config/cengdef.h"
  34. // #include "../../outside resources/memory management/debug_memorymanager.h"
  35. namespace ceng {
  36. ///////////////////////////////////////////////////////////////////////////////
  37. std::vector <std::string> Split( const std::string& _separator, std::string _string )
  38. {
  39. std::vector <std::string> array;
  40. size_t position;
  41. // we will find the position of first of the separators
  42. position = _string.find( _separator );
  43. // We will loop true this until there are no separators left
  44. // in _string
  45. while ( position != _string.npos )
  46. {
  47. // This thing here checks that we dont push empty strings
  48. // to the array
  49. if ( position != 0 )
  50. array.push_back( _string.substr( 0, position ) );
  51. // When the cutted part is pushed into the array we
  52. // remove it and the separator from the _string
  53. _string.erase( 0, position + _separator.length() );
  54. // And the we look for a new place for the _separator
  55. position = _string.find( _separator );
  56. }
  57. // We will push the rest of the stuff in to the array
  58. if ( _string.empty() == false )
  59. array.push_back( _string );
  60. // Then we'll just return the array
  61. return array;
  62. }
  63. //=============================================================================
  64. // Same thing as above but with _limit
  65. std::vector <std::string> Split( const std::string& _separator, std::string _string, int _limit )
  66. {
  67. std::vector <std::string> array;
  68. size_t position;
  69. position = _string.find( _separator );
  70. // The only diffrence is here
  71. int count = 0;
  72. // and in this while loop the count <= _limit
  73. while ( position != _string.npos && count < _limit - 1 )
  74. {
  75. if ( position != 0 )
  76. array.push_back( _string.substr( 0, position ) );
  77. _string.erase( 0, position + _separator.length() );
  78. position = _string.find( _separator );
  79. // And here
  80. count++;
  81. }
  82. if ( _string.empty() == false )
  83. array.push_back( _string );
  84. return array;
  85. }
  86. //=============================================================================
  87. std::vector<std::string> StringSplit( const std::string& _separator, std::string _string )
  88. {
  89. std::vector <std::string> array;
  90. size_t position;
  91. // we will find the position of first of the separators
  92. position = StringFind( _separator, _string );
  93. // We will loop true this until there are no separators left
  94. // in _string
  95. while ( position != _string.npos )
  96. {
  97. // This thing here checks that we dont push empty strings
  98. // to the array
  99. if ( position != 0 )
  100. array.push_back( _string.substr( 0, position ) );
  101. // When the cutted part is pushed into the array we
  102. // remove it and the separator from the _string
  103. _string.erase( 0, position + _separator.length() );
  104. // And the we look for a new place for the _separator
  105. position = StringFind( _separator, _string );
  106. }
  107. // We will push the rest of the stuff in to the array
  108. if ( _string.empty() == false )
  109. array.push_back( _string );
  110. // Then we'll just return the array
  111. return array;
  112. }
  113. //=============================================================================
  114. // Same thing as above but with _limit
  115. std::vector <std::string> StringSplit( const std::string& _separator, std::string _string, int _limit )
  116. {
  117. std::vector <std::string> array;
  118. size_t position;
  119. position = StringFind( _separator, _string );
  120. // The only diffrence is here
  121. int count = 0;
  122. // and in this while loop the count <= _limit
  123. while ( position != _string.npos && count < _limit - 1 )
  124. {
  125. if ( position != 0 )
  126. array.push_back( _string.substr( 0, position ) );
  127. _string.erase( 0, position + _separator.length() );
  128. position = StringFind( _separator, _string );
  129. // And here
  130. count++;
  131. }
  132. if ( _string.empty() == false )
  133. array.push_back( _string );
  134. return array;
  135. }
  136. ///////////////////////////////////////////////////////////////////////////////
  137. size_t StringFind( const std::string& _what, const std::string& _line, size_t _begin )
  138. {
  139. size_t return_value = _line.find( _what, _begin );
  140. if ( return_value == _line.npos )
  141. {
  142. return return_value;
  143. }
  144. // for the very begin we'll first find out
  145. // if there even is a quetemark in the string
  146. size_t quete_begin = _line.find("\"", _begin );
  147. // if there isn't well return the position of _what
  148. if ( quete_begin == _line.npos )
  149. {
  150. return return_value;
  151. }
  152. if ( quete_begin > return_value )
  153. {
  154. return return_value;
  155. }
  156. // Then heres the other vars used here
  157. size_t quete_end = _line.find( "\"", quete_begin+1 );
  158. while ( quete_begin < return_value )
  159. {
  160. if ( quete_end > return_value )
  161. {
  162. return_value = _line.find( _what, return_value+1 );
  163. if ( return_value == _line.npos ) return return_value;
  164. }
  165. if ( quete_end < return_value )
  166. {
  167. quete_begin = _line.find( "\"", quete_end+1 );
  168. quete_end = _line.find( "\"", quete_begin+1 );
  169. }
  170. }
  171. return return_value;
  172. }
  173. ///////////////////////////////////////////////////////////////////////////////
  174. size_t StringFindFirstOf( const std::string& what, const std::string& line, size_t begin )
  175. {
  176. size_t return_value = line.find_first_of( what, begin );
  177. if ( return_value == line.npos )
  178. {
  179. return return_value;
  180. }
  181. // for the very begin we'll first find out
  182. // if there even is a quetemark in the string
  183. size_t quete_begin = line.find("\"", begin );
  184. // if there isn't well return the position of what
  185. if ( quete_begin == line.npos )
  186. {
  187. return return_value;
  188. }
  189. if ( quete_begin > return_value )
  190. {
  191. return return_value;
  192. }
  193. // Then heres the other vars used here
  194. size_t quete_end = line.find( "\"", quete_begin+1 );
  195. while ( quete_begin < return_value )
  196. {
  197. if ( quete_end > return_value )
  198. {
  199. return_value = line.find_first_of( what, return_value+1 );
  200. if ( return_value == line.npos ) return return_value;
  201. }
  202. if ( quete_end < return_value )
  203. {
  204. quete_begin = line.find( "\"", quete_end+1 );
  205. quete_end = line.find( "\"", quete_begin+1 );
  206. }
  207. }
  208. return return_value;
  209. }
  210. ///////////////////////////////////////////////////////////////////////////////
  211. std::string StringReplace( const std::string& what, const std::string& with, const std::string& in_here, int limit )
  212. {
  213. int i = 0;
  214. std::string return_value = in_here;
  215. size_t pos = return_value.find( what, 0 );
  216. while( pos != return_value.npos && ( limit == -1 || i < limit ) )
  217. {
  218. return_value.replace( pos, what.size(), with );
  219. pos = return_value.find( what, pos );
  220. i++;
  221. }
  222. return return_value;
  223. }
  224. ///////////////////////////////////////////////////////////////////////////////
  225. std::string RemoveWhiteSpace( std::string line )
  226. {
  227. // std::string line( _line );
  228. size_t position = line.find_first_not_of(" \t");
  229. if( position != 0 )
  230. line.erase( 0, position );
  231. position = line.find_last_not_of(" \t\r");
  232. if( position != line.size() - 1 )
  233. line.erase( position+1 );
  234. return line;
  235. }
  236. ///////////////////////////////////////////////////////////////////////////////
  237. std::string RemoveQuotes( std::string line )
  238. {
  239. if( line.empty() == false && line[ 0 ] == '"' || line[ 0 ] == '\'' )
  240. line = line.substr( 1, line.size() - 1 );
  241. int end = ((int)line.size()) - 1;
  242. if( end >= 0 && ( line[ end ] == '"' || line[ end ] == '\'' ) )
  243. line = line.substr( 0, end );
  244. return line;
  245. }
  246. ///////////////////////////////////////////////////////////////////////////////
  247. std::string Uppercase( const std::string& _string )
  248. {
  249. std::string return_value;
  250. for ( unsigned int i = 0; i < _string.size(); i++ )
  251. {
  252. return_value += toupper( _string[ i ] );
  253. }
  254. return return_value;
  255. }
  256. //=============================================================================
  257. std::string Lowercase( const std::string& _string )
  258. {
  259. std::string return_value;
  260. for ( unsigned int i = 0; i < _string.size(); i++ )
  261. {
  262. return_value += tolower( _string[ i ] );
  263. }
  264. return return_value;
  265. }
  266. ///////////////////////////////////////////////////////////////////////////////
  267. std::string convertNumberToString( int num )
  268. {
  269. std::string result = "";
  270. while( num >= 94 )
  271. {
  272. result += char( 126 );
  273. num -= 94;
  274. }
  275. result += char( num + 32 );
  276. return result;
  277. }
  278. //=============================================================================
  279. std::string ConvertNumbersToString( const std::vector< int >& array )
  280. {
  281. std::string result;
  282. for( unsigned int i = 0; i < array.size(); i++ )
  283. {
  284. result += convertNumberToString( array[ i ] );
  285. }
  286. return result;
  287. }
  288. //=============================================================================
  289. std::vector< int > ConvertStringToNumbers( const std::string& str )
  290. {
  291. std::vector< int > result;
  292. int vector_pos = 0;
  293. result.push_back( 0 );
  294. for( unsigned int i = 0; i < str.size(); i++ )
  295. {
  296. result[ vector_pos ] += str[ i ] - 32;
  297. if( str[ i ] != char( 126 ) )
  298. {
  299. vector_pos++;
  300. result.push_back( 0 );
  301. }
  302. }
  303. return result;
  304. }
  305. ///////////////////////////////////////////////////////////////////////////////
  306. bool ContainsString( const std::string& what, const std::string& in_where )
  307. {
  308. if( in_where.empty() )
  309. return what.empty();
  310. size_t pos = in_where.find( what );
  311. if( pos == in_where.npos )
  312. return false;
  313. return true;
  314. }
  315. bool ContainsStringChar( const std::string& what, const char* in_where, int length )
  316. {
  317. if( what.empty() )
  318. return ( length == 0 );
  319. const char* pos = in_where;
  320. unsigned int j = 0;
  321. for( int i = 0; i < length; ++i )
  322. {
  323. if( *pos == what[ j ] )
  324. {
  325. j++;
  326. if( j >= what.size() )
  327. return true;
  328. }
  329. else
  330. {
  331. j = 0;
  332. }
  333. pos++;
  334. }
  335. return false;
  336. }
  337. ///////////////////////////////////////////////////////////////////////////////
  338. bool IsNumericString( const std::string& what )
  339. {
  340. return (what.empty() == false && what.find_first_not_of("0123456789.+-") == what.npos );
  341. }
  342. ///////////////////////////////////////////////////////////////////////////////
  343. bool CheckIfTheBeginningIsSame( const std::string& beginning, const std::string& line )
  344. {
  345. if( line.size() > beginning.size() )
  346. {
  347. if( line.substr( 0, beginning.size() ) == beginning )
  348. return true;
  349. }
  350. else if( line == beginning )
  351. {
  352. return true;
  353. }
  354. else
  355. {
  356. return false;
  357. }
  358. return false;
  359. }
  360. std::string RemoveBeginning( const std::string& beginning, const std::string& line )
  361. {
  362. return line.substr( beginning.size() );
  363. }
  364. ///////////////////////////////////////////////////////////////////////////////
  365. namespace {
  366. bool IsAlphaNumeric( char c )
  367. {
  368. if( c >= '0' && c <= '9' )
  369. return true;
  370. if( c >= 'a' && c <= 'z' )
  371. return true;
  372. if( c >= 'A' && c <= 'Z' )
  373. return true;
  374. return false;
  375. }
  376. char ConvertToAlphaNumeric( char what )
  377. {
  378. int randnum = (int)what % 61;
  379. if( randnum < 10 )
  380. {
  381. return char( randnum + 48 );
  382. }
  383. else if( randnum < 36 )
  384. {
  385. return char( randnum + 55 );
  386. }
  387. else
  388. {
  389. return char( randnum + 61 );
  390. }
  391. return 'a';
  392. }
  393. }
  394. std::string MakeAlphaNumeric( const std::string& who )
  395. {
  396. std::string result;
  397. for( unsigned int i = 0; i < who.size(); ++i )
  398. {
  399. char t = who[ i ];
  400. if( IsAlphaNumeric( t ) )
  401. result += t;
  402. }
  403. return result;
  404. }
  405. std::string ConvertToAlphaNumeric( const std::string& who )
  406. {
  407. std::string result;
  408. for( unsigned int i = 0; i < who.size(); ++i )
  409. {
  410. char t = who[ i ];
  411. if( IsAlphaNumeric( t ) )
  412. result += t;
  413. else
  414. result += ConvertToAlphaNumeric( t );
  415. }
  416. return result;
  417. }
  418. ///////////////////////////////////////////////////////////////////////////////
  419. } // end of namespace ceng