/root/projects/repository/source/cpp/CAlfrescoApp/source/util/String.cpp

https://github.com/deas/alfresco · C++ · 885 lines · 321 code · 152 blank · 412 comment · 74 complexity · 3be5b7460d654c8bd0d0527087bd34ad MD5 · raw file

  1. /*
  2. * Copyright (C) 2005-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "util\String.h"
  20. using namespace Alfresco;
  21. using namespace std;
  22. /**
  23. * Default constructor
  24. */
  25. String::String() {
  26. m_string = std::wstring();
  27. }
  28. /**
  29. * Class constructor
  30. *
  31. * @param alloc const unsigned int
  32. */
  33. String::String(const unsigned int alloc) {
  34. m_string = std::wstring();
  35. m_string.reserve( alloc);
  36. }
  37. /**
  38. * Class constructor
  39. *
  40. * @param str const char*
  41. */
  42. String::String(const char* str) {
  43. // Expand the characters to wide characters and append to the string
  44. wchar_t wch;
  45. while ( *str != '\0') {
  46. wch = (wchar_t) *str++;
  47. m_string += wch;
  48. }
  49. }
  50. /**
  51. * Class constructor
  52. *
  53. * @param str const unsigned char*
  54. */
  55. String::String(const unsigned char* str) {
  56. // Expand the characters to wide characters and append to the string
  57. wchar_t wch;
  58. while ( *str != '\0') {
  59. wch = (wchar_t) *str++;
  60. m_string += wch;
  61. }
  62. }
  63. /**
  64. * Class constructor
  65. *
  66. * @param buf const char*
  67. * @param offset const unsigned int
  68. * @param len const unsigned int
  69. */
  70. String::String(const char* buf, const unsigned int offset, const unsigned int len) {
  71. // Expand the characters to wide characters and append to the string
  72. wchar_t wch;
  73. const char* str = buf + offset;
  74. unsigned int sLen = len;
  75. while ( sLen--) {
  76. wch = (wchar_t) *str++;
  77. m_string += wch;
  78. }
  79. }
  80. /**
  81. * Class constructor
  82. *
  83. * @param str const wchar_t*
  84. */
  85. String::String(const wchar_t* str) {
  86. m_string = std::wstring( str);
  87. }
  88. /**
  89. * Class constructor
  90. *
  91. * @param buf const wchar_t*
  92. * @param offset const unsigned int
  93. * @param len const unsigned int
  94. */
  95. String::String(const wchar_t* buf, const unsigned int offset, const unsigned int len) {
  96. m_string = std::wstring(buf + offset, len);
  97. }
  98. /**
  99. * Class constructor
  100. *
  101. * @param str const std::wstring&
  102. */
  103. String::String(const std::wstring& str) {
  104. m_string = str;
  105. }
  106. /**
  107. * Copy constructor
  108. *
  109. * @param str const String&
  110. */
  111. String::String(const String& str) {
  112. m_string = std::wstring(str.data());
  113. }
  114. /**
  115. * Class constructor
  116. *
  117. * @param byts ByteArray&
  118. */
  119. String::String( ByteArray& byts) {
  120. // Expand the characters to wide characters and append to the string
  121. wchar_t wch;
  122. for ( unsigned int idx = 0; idx < byts.getLength(); idx++) {
  123. wch = (wchar_t) byts[idx];
  124. m_string += wch;
  125. }
  126. }
  127. /**
  128. * Compare strings for equality
  129. *
  130. * @param str const wchar_t*
  131. * @return bool
  132. */
  133. bool String::equals(const wchar_t* str) const {
  134. // Check that the string is valid
  135. if ( str == NULL)
  136. return false;
  137. // Compare the strings
  138. if ( m_string.compare(str) == 0)
  139. return true;
  140. return false;
  141. }
  142. /**
  143. * Compare strings for equality
  144. *
  145. * @param str const String&
  146. * @return bool
  147. */
  148. bool String::equals(const String& str) const {
  149. // Compare the strings
  150. if ( m_string.compare(str.data()) == 0)
  151. return true;
  152. return false;
  153. }
  154. /**
  155. * Compare strings for equality ignoring case
  156. *
  157. * @param str const wchar_t*
  158. * @return bool
  159. */
  160. bool String::equalsIgnoreCase(const wchar_t* str) const {
  161. return _wcsicmp( str, data()) == 0 ? true : false;
  162. }
  163. /**
  164. * Compare strings for equality ignoring case
  165. *
  166. * @param str const String&
  167. * @return bool
  168. */
  169. bool String::equalsIgnoreCase(const String& str) const {
  170. return _wcsicmp( str.data(), data()) == 0 ? true : false;
  171. }
  172. /**
  173. * Compare strings
  174. *
  175. * @param str const String&
  176. * @return int
  177. */
  178. int String::compareTo( const String& str) const {
  179. return m_string.compare( str.getString());
  180. }
  181. /**
  182. * Compare strings
  183. *
  184. * @param pStr const wchar_t*
  185. * @return int
  186. */
  187. int String::compareTo( const wchar_t* pStr) const {
  188. return m_string.compare( pStr);
  189. }
  190. /**
  191. * Convert the string to lower case returning the resulting String
  192. *
  193. * @return String
  194. */
  195. String String::toLowerCase() const {
  196. // Create a copy of the string then convert to lowercase
  197. std::wstring lstr(m_string);
  198. for ( unsigned int i = 0; i < lstr.length(); i++)
  199. lstr[i] = tolower(lstr[i]);
  200. return String(lstr);
  201. }
  202. /**
  203. * Convert the string to upper case returning the resulting String
  204. *
  205. * @return String
  206. */
  207. String String::toUpperCase() const {
  208. // Create a copy of the string then convert to uppercase
  209. std::wstring ustr(m_string);
  210. for ( unsigned int i = 0; i < ustr.length(); i++)
  211. ustr[i] = toupper(ustr[i]);
  212. return String(ustr);
  213. }
  214. /**
  215. * Return the index of the specified character, or -1 if not found
  216. *
  217. * @param ch const wchar_t
  218. * @param startIndex int
  219. * @return int
  220. */
  221. int String::indexOf(const wchar_t ch, int startIndex) const {
  222. return (int) m_string.find_first_of( ch, startIndex);
  223. }
  224. /**
  225. * Return the index of the specified string, or -1 if not found
  226. *
  227. * @param str const wchar_t*
  228. * @param startIndex int
  229. * @return int
  230. */
  231. int String::indexOf(const wchar_t* str, int startIndex) const {
  232. return (int) m_string.find_first_of( str, startIndex);
  233. }
  234. /**
  235. * Return the index of the specified string, or -1 if not found
  236. *
  237. * @param str const String&
  238. * @param startIndex int
  239. * @return int
  240. */
  241. int String::indexOf(const String& str, int startIndex) const {
  242. return (int) m_string.find_first_of( str, startIndex);
  243. }
  244. /**
  245. * Return the last index of the specified character, or -1 if not found
  246. *
  247. * @param ch const wchar_t
  248. * @param startIndex int
  249. * @return int
  250. */
  251. int String::lastIndexOf(const wchar_t ch, int startIndex) const {
  252. return (int) m_string.find_last_of( ch, startIndex);
  253. }
  254. /**
  255. * Return the last index of the specified string, or -1 if not found
  256. *
  257. * @param str const wchar_t*
  258. * @param startIndex int
  259. * @return int
  260. */
  261. int String::lastIndexOf(const wchar_t* str, int startIndex) const {
  262. return (int) m_string.find_last_of( str, startIndex);
  263. }
  264. /**
  265. * Return the last index of the specified string, or -1 if not found
  266. *
  267. * @param str const String&
  268. * @param startIndex int
  269. * @return int
  270. */
  271. int String::lastIndexOf(const String& str, int startIndex) const {
  272. return (int) m_string.find_last_of( str, startIndex);
  273. }
  274. /**
  275. * Check if this string starts with the specified string.
  276. *
  277. * @param str const wchar_t*
  278. * @return bool
  279. */
  280. bool String::startsWith(const wchar_t* str) const {
  281. // Check if the string to check is valid
  282. if ( str == NULL)
  283. return false;
  284. // Get the string length, if the comparison string is longer than this string
  285. // then there is no match.
  286. size_t len = wcslen(str);
  287. if ( str == NULL || wcslen(str) > m_string.length())
  288. return false;
  289. // Check if this string starts with the specified string
  290. if ( m_string.compare(0, len, str) == 0)
  291. return true;
  292. return false;
  293. }
  294. /**
  295. * Check if this string starts with the specified string.
  296. *
  297. * @param str const String&
  298. * @return bool
  299. */
  300. bool String::startsWith(const String& str) const {
  301. // Get the string length, if the comparison string is longer than this string
  302. // then there is no match.
  303. if ( str.length() > m_string.length())
  304. return false;
  305. // Check if this string starts with the specified string
  306. if ( m_string.compare(0, str.length(), str.data()) == 0)
  307. return true;
  308. return false;
  309. }
  310. /**
  311. * Check if this string starts with the specified string, ignoring case.
  312. *
  313. * @param str const wchar_t*
  314. * @return bool
  315. */
  316. bool String::startsWithIgnoreCase(const wchar_t* str) const {
  317. // Check if the string to check is valid
  318. if ( str == NULL)
  319. return false;
  320. // Get the string length, if the comparison string is longer than this string
  321. // then there is no match.
  322. size_t len = wcslen(str);
  323. if ( str == NULL || wcslen(str) > m_string.length())
  324. return false;
  325. // Check if this string starts with the specified string
  326. if ( _wcsnicmp(str, data(), len) == 0)
  327. return true;
  328. return false;
  329. }
  330. /**
  331. * Check if this string starts with the specified string, ignoring case.
  332. *
  333. * @param str const String&
  334. * @return bool
  335. */
  336. bool String::startsWithIgnoreCase(const String& str) const {
  337. // Get the string length, if the comparison string is longer than this string
  338. // then there is no match.
  339. if ( str.length() > m_string.length())
  340. return false;
  341. // Check if this string starts with the specified string
  342. if ( _wcsnicmp( str.data(), data(), str.length()) == 0)
  343. return true;
  344. return false;
  345. }
  346. /**
  347. * Check if this string ends with the specified string.
  348. *
  349. * @param str const wchar_t*
  350. * @return bool
  351. */
  352. bool String::endsWith(const wchar_t* str) const {
  353. // Check if the string to check is valid
  354. if ( str == NULL)
  355. return false;
  356. // Get the string length, if the comparison string is longer than this string
  357. // then there is no match.
  358. size_t len = wcslen(str);
  359. if ( str == NULL || wcslen(str) > m_string.length())
  360. return false;
  361. // Check if this string ends with the specified string
  362. if ( m_string.compare(m_string.length() - len, len, str) == 0)
  363. return true;
  364. return false;
  365. }
  366. /**
  367. * Check if this string ends with the specified string.
  368. *
  369. * @param str const String&
  370. * @return bool
  371. */
  372. bool String::endsWith(const String& str) const {
  373. // Get the string length, if the comparison string is longer than this string
  374. // then there is no match.
  375. if ( str.length() > m_string.length())
  376. return false;
  377. // Check if this string ends with the specified string
  378. if ( m_string.compare(m_string.length() - str.length(), str.length(), str.data()) == 0)
  379. return true;
  380. return false;
  381. }
  382. /**
  383. * Trim leading and trailing whitespace from the string returning the resulting String
  384. *
  385. * @return String
  386. */
  387. String String::trim( void) const {
  388. std::wstring str = m_string;
  389. str.erase( str.find_last_not_of( L" ") + 1);
  390. return String( str);
  391. }
  392. /**
  393. * Return a substring of this string
  394. *
  395. * @param beginIndex unsigned int
  396. * @return String
  397. */
  398. String String::substring( unsigned int beginIndex) const {
  399. std::wstring str = m_string.substr( beginIndex);
  400. return String(str);
  401. }
  402. /**
  403. * Return a substring of this string
  404. *
  405. * @param beginIndex unsigned int
  406. * @param endIndex unsigned int
  407. * @return String
  408. */
  409. String String::substring( unsigned int beginIndex, unsigned int endIndex) const {
  410. std::wstring str = m_string.substr( beginIndex, (endIndex - beginIndex));
  411. return String(str);
  412. }
  413. /**
  414. * Assignment operator
  415. *
  416. * @param str const wchar_t*
  417. * @return String&
  418. */
  419. String& String::operator=(const wchar_t* str) {
  420. m_string = str;
  421. return *this;
  422. }
  423. /**
  424. * Assignment operator
  425. *
  426. * @param str const String&
  427. * @return String&
  428. */
  429. String& String::operator=(const String& str) {
  430. m_string = str.data();
  431. return *this;
  432. }
  433. /**
  434. * Return the string as an array of 8 bit bytes.
  435. *
  436. * @param byts ByteArray&
  437. * @return ByteArray
  438. */
  439. ByteArray String::getBytes( ByteArray& byts) const {
  440. // Create a byte array to hold the byte data
  441. byts.setLength( length());
  442. // Convert the wide characters to ASCII characters
  443. for ( unsigned int i = 0; i < length(); i++)
  444. byts[ i] = (char) (charAt(i) & 0xFF);
  445. return byts;
  446. }
  447. /**
  448. * Return the string as an array of 8 bit bytes.
  449. *
  450. * @return ByteArray
  451. */
  452. ByteArray String::getBytes( void) const {
  453. // Create a byte array to hold the byte data
  454. ByteArray byts;
  455. byts.setLength( length());
  456. // Convert the wide characters to ASCII characters
  457. for ( unsigned int i = 0; i < length(); i++)
  458. byts[ i] = (char) (charAt(i) & 0xFF);
  459. return byts;
  460. }
  461. /**
  462. * Equality operator
  463. *
  464. * @param str const String&
  465. * @return bool
  466. */
  467. bool String::operator== ( const String& str) const {
  468. return equals( str);
  469. }
  470. /**
  471. * Equality operator
  472. *
  473. * @param str const wchar_t*
  474. * @return bool
  475. */
  476. bool String::operator== ( const wchar_t* str) const {
  477. return equals( str);
  478. }
  479. /**
  480. * Equality operator
  481. *
  482. * @param str const char*
  483. * @return bool
  484. */
  485. bool String::operator== ( const char* str) const {
  486. return equals( String( str));
  487. }
  488. /**
  489. * Wide character output stream operator
  490. *
  491. * @param out wostream&
  492. * @param str const String&
  493. * @return wostream&
  494. */
  495. std::wostream& Alfresco::operator<< ( std::wostream& out, const Alfresco::String& str) {
  496. return out << str.data();
  497. }
  498. /**
  499. * Less than operator
  500. *
  501. * @param str const String&
  502. * @return bool
  503. */
  504. bool String::operator<( const String& str) const {
  505. return getString().compare( str.getString()) < 0 ? true : false;
  506. }
  507. /**
  508. * ASCII character output stream operator
  509. *
  510. * @param out ostream&
  511. * @param str const String&
  512. * @return ostream&
  513. */
  514. std::ostream& Alfresco::operator<< ( std::ostream& out, const Alfresco::String& str) {
  515. std::string ascStr;
  516. ascStr.reserve( str.length());
  517. for ( unsigned int i = 0; i < str.length(); i++)
  518. ascStr += (char) ( str.charAt( i) & 0xFF);
  519. return out << ascStr.c_str();
  520. }
  521. /**
  522. * Replace occurrences of the character oldCh with newCh
  523. *
  524. * @param oldCh wchar_t
  525. * @param newCh wchar_t
  526. */
  527. void String::replace( wchar_t oldCh, wchar_t newCh) {
  528. if ( m_string.size() == 0)
  529. return;
  530. for ( unsigned int i = 0; i < m_string.size(); i++) {
  531. if ( m_string.at( i) == oldCh)
  532. m_string[i] = newCh;
  533. }
  534. }
  535. /**
  536. * Append a character to this string
  537. *
  538. * @param ch wchar_t
  539. */
  540. void String::append( wchar_t ch) {
  541. m_string += ch;
  542. }
  543. /**
  544. * Append a string to this string
  545. *
  546. * @param str const char*
  547. */
  548. void String::append ( const char* str) {
  549. // Expand the characters to wide characters and append to the string
  550. wchar_t wch;
  551. while ( *str != '\0') {
  552. wch = (wchar_t) *str++;
  553. m_string += wch;
  554. }
  555. }
  556. /**
  557. * Append a string to this string
  558. *
  559. * @param str const wchar_t*
  560. */
  561. void String::append (const wchar_t* str) {
  562. while ( *str != 0)
  563. m_string += *str++;
  564. }
  565. /**
  566. * Append a string to this string
  567. *
  568. * @param str const String&
  569. */
  570. void String::append (const String& str) {
  571. m_string += str.getString();
  572. }
  573. /**
  574. * Append an integer value to this string
  575. *
  576. * @param ival const unsigned int
  577. */
  578. void String::append (const unsigned int ival) {
  579. wchar_t buf[32];
  580. swprintf( buf, 32, L"%u", ival);
  581. m_string += buf;
  582. }
  583. /**
  584. * Append a long value to this string
  585. *
  586. * @param lval const unsigned long
  587. */
  588. void String::append (const unsigned long lval) {
  589. wchar_t buf[32];
  590. swprintf( buf, 32, L"%lu", lval);
  591. m_string += buf;
  592. }
  593. /**
  594. * Append a long/64 bit value to this string
  595. *
  596. * @param l64val const unsigned long
  597. */
  598. void String::append (const LONG64 l64val) {
  599. wchar_t buf[32];
  600. swprintf( buf, 32, L"%I64u", l64val);
  601. m_string += buf;
  602. }
  603. /**
  604. * Split a string into tokens
  605. *
  606. * @param delims const String&
  607. * @return StringList
  608. */
  609. StringList String::tokenize( const String& delims) const {
  610. // Skip leading delimiters
  611. StringList tokens;
  612. string::size_type lastPos = m_string.find_first_not_of( delims, 0);
  613. // Find a non-delimiter character
  614. string::size_type pos = m_string.find_first_of( delims, lastPos);
  615. while ( pos != string::npos || lastPos != string::npos) {
  616. // Add the current token to the list
  617. tokens.addString( m_string.substr( lastPos, pos - lastPos));
  618. // Skip delimiter(s)
  619. lastPos = m_string.find_first_not_of( delims, pos);
  620. // Find next token
  621. pos = m_string.find_first_of( delims, lastPos);
  622. }
  623. // Return the token list
  624. return tokens;
  625. }
  626. /**
  627. * Default constructor
  628. */
  629. StringList::StringList( void) {
  630. }
  631. /**
  632. * Class constructor
  633. *
  634. * @param reserve unsigned int
  635. */
  636. StringList::StringList( unsigned int reserve) {
  637. m_list.reserve( reserve);
  638. }
  639. /**
  640. * Copy constructor
  641. *
  642. * @param strList const StringList&
  643. */
  644. StringList::StringList( const StringList& strList) {
  645. copyFrom( strList);
  646. }
  647. /**
  648. * Copy strings from the specified list
  649. *
  650. * @param strList const StringList&
  651. */
  652. void StringList::copyFrom( const StringList& strList) {
  653. for ( unsigned int idx = 0; idx < strList.numberOfStrings(); idx++)
  654. addString( strList.getStringAt( idx));
  655. }
  656. /**
  657. * Check if the list contains the string
  658. *
  659. * @param str const String&
  660. * @return bool
  661. */
  662. bool StringList::containsString ( const String& str) {
  663. for ( std::vector<String>::iterator pos = m_list.begin(); pos < m_list.end(); pos++) {
  664. if ( str.equals( *pos))
  665. return true;
  666. }
  667. return false;
  668. }
  669. /**
  670. * Check if the list contains the string, ignoring case
  671. *
  672. * @param str const String&
  673. * @return bool
  674. */
  675. bool StringList::containsStringCaseless ( const String& str) {
  676. for ( std::vector<String>::iterator pos = m_list.begin(); pos < m_list.end(); pos++) {
  677. if ( str.equalsIgnoreCase( *pos))
  678. return true;
  679. }
  680. return false;
  681. }
  682. /**
  683. * Find the specified string and return the position within the list, or -1 if not found
  684. *
  685. * @param str const String&
  686. * @return int
  687. */
  688. int StringList::indexOf( const String& str) const {
  689. for ( unsigned int i = 0; i < m_list.size(); i++) {
  690. if ( m_list[i].equals( str))
  691. return (int) i;
  692. }
  693. return -1;
  694. }
  695. /**
  696. * Remove the specified string from the list
  697. *
  698. * @param str const String&
  699. */
  700. void StringList::removeString ( const String& str) {
  701. for ( std::vector<String>::iterator pos = m_list.begin(); pos < m_list.end(); pos++) {
  702. if ( str.equals( *pos)) {
  703. m_list.erase( pos);
  704. return;
  705. }
  706. }
  707. }
  708. /**
  709. * Remove the specified string from the list, ignoring case
  710. *
  711. * @param str const String&
  712. */
  713. void StringList::removeStringCaseless ( const String& str) {
  714. for ( std::vector<String>::iterator pos = m_list.begin(); pos < m_list.end(); pos++) {
  715. if ( str.equalsIgnoreCase( *pos)) {
  716. m_list.erase( pos);
  717. return;
  718. }
  719. }
  720. }
  721. /**
  722. * Return the string list as a comma separated string
  723. *
  724. * @return String
  725. */
  726. String StringList::toString( void) const {
  727. String ret;
  728. for ( unsigned int i = 0; i < numberOfStrings(); i++) {
  729. ret += getStringAt( i);
  730. ret += ",";
  731. }
  732. return ret;
  733. }