/src/api/zorba_string.cpp

https://github.com/cezarfx/zorba · C++ · 721 lines · 521 code · 163 blank · 37 comment · 3 complexity · 93bfbd465baabdc3c75cd524f926f584 MD5 · raw file

  1. /*
  2. * Copyright 2006-2008 The FLWOR Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "stdafx.h"
  17. #include <zorba/internal/cxx_util.h>
  18. #include <zorba/zorba_string.h>
  19. #include "api/unmarshaller.h"
  20. #include "util/ascii_util.h"
  21. #include "util/regex.h"
  22. #include "util/string_util.h"
  23. #include "util/uri_util.h"
  24. #include "util/utf8_util.h"
  25. #include "util/xml_util.h"
  26. #include "diagnostics/xquery_diagnostics.h"
  27. #include "zorbatypes/zstring.h"
  28. using namespace std;
  29. namespace zorba {
  30. /**
  31. * The string type we're actually using.
  32. */
  33. typedef zstring string_type;
  34. // This is not an inline function since string_storage_ is private.
  35. #define STRING_OF(STRING_OBJ) \
  36. const_cast<string_type*>( \
  37. reinterpret_cast<string_type const*>( &(STRING_OBJ).string_storage_ ) \
  38. )
  39. #define THIS_STRING STRING_OF( *this )
  40. void String::size_check() {
  41. static_assert(
  42. sizeof( string_storage_type ) >= sizeof( string_type ),
  43. "storage for zstring is too small"
  44. );
  45. }
  46. ////////// constructors & destructor //////////////////////////////////////////
  47. String::String() {
  48. new( THIS_STRING ) string_type;
  49. }
  50. String::String( String const &s ) {
  51. new( THIS_STRING ) string_type( *STRING_OF( s ) );
  52. }
  53. String::String( string const &s ) {
  54. new( THIS_STRING ) string_type( s );
  55. }
  56. String::String( const_pointer s ) {
  57. new( THIS_STRING ) string_type( s );
  58. }
  59. String::String( String const &s, size_type pos, size_type n ) {
  60. new( THIS_STRING ) string_type( *STRING_OF( s ), pos, n );
  61. }
  62. String::String( string const &s, size_type pos, size_type n ) {
  63. new( THIS_STRING ) string_type( s, pos, n );
  64. }
  65. String::String( const_pointer s, size_type n ) {
  66. new( THIS_STRING) string_type( s, n );
  67. }
  68. String::String( size_type n, value_type c ) {
  69. new( THIS_STRING ) string_type( n, c );
  70. }
  71. String::String( const_iterator i, const_iterator j ) {
  72. new( THIS_STRING ) string_type( i, j );
  73. }
  74. String::String( zstring_ptr zp ) {
  75. new( THIS_STRING ) string_type(
  76. *reinterpret_cast<string_type const*>( zp.ptr )
  77. );
  78. }
  79. String::~String() {
  80. THIS_STRING->~string_type();
  81. }
  82. ////////// assignment /////////////////////////////////////////////////////////
  83. String& String::operator=( String const &s ) {
  84. *THIS_STRING = *STRING_OF( s );
  85. return *this;
  86. }
  87. String& String::operator=( string const &s ) {
  88. *THIS_STRING = s;
  89. return *this;
  90. }
  91. String& String::operator=( const_pointer s ) {
  92. *THIS_STRING = s;
  93. return *this;
  94. }
  95. String& String::operator=( value_type c ) {
  96. *THIS_STRING = c;
  97. return *this;
  98. }
  99. String& String::operator=( zstring_ptr zp ) {
  100. *THIS_STRING = *reinterpret_cast<string_type const*>( zp.ptr );
  101. return *this;
  102. }
  103. ////////// properties /////////////////////////////////////////////////////////
  104. String::size_type String::capacity() const {
  105. return THIS_STRING->capacity();
  106. }
  107. String::size_type String::length() const {
  108. return THIS_STRING->length();
  109. }
  110. ////////// character access ///////////////////////////////////////////////////
  111. String::reference String::at( size_type pos ) {
  112. return THIS_STRING->at( pos );
  113. }
  114. String::value_type String::at( size_type pos ) const {
  115. return THIS_STRING->at( pos );
  116. }
  117. String::const_reference String::operator[]( size_type pos ) const {
  118. return (*THIS_STRING)[ pos ];
  119. }
  120. ////////// append /////////////////////////////////////////////////////////////
  121. String& String::append( String const &s ) {
  122. THIS_STRING->append( *STRING_OF( s ) );
  123. return *this;
  124. }
  125. String& String::append( string const &s ) {
  126. THIS_STRING->append( s );
  127. return *this;
  128. }
  129. String& String::append( const_pointer s ) {
  130. THIS_STRING->append( s );
  131. return *this;
  132. }
  133. String& String::append( String const &s, size_type s_pos, size_type s_n ) {
  134. THIS_STRING->append( *STRING_OF( s ), s_pos, s_n );
  135. return *this;
  136. }
  137. String& String::append( string const &s, size_type s_pos, size_type s_n ) {
  138. THIS_STRING->append( s, s_pos, s_n );
  139. return *this;
  140. }
  141. String& String::append( const_pointer s, size_type s_n ) {
  142. THIS_STRING->append( s, s_n );
  143. return *this;
  144. }
  145. String& String::append( size_type n, value_type c ) {
  146. THIS_STRING->append( n, c );
  147. return *this;
  148. }
  149. void String::push_back( value_type c ) {
  150. THIS_STRING->push_back( c );
  151. }
  152. ////////// assign /////////////////////////////////////////////////////////////
  153. String& String::assign( String const &s ) {
  154. THIS_STRING->assign( *STRING_OF( s ) );
  155. return *this;
  156. }
  157. String& String::assign( string const &s ) {
  158. THIS_STRING->assign( s );
  159. return *this;
  160. }
  161. String& String::assign( const_pointer s ) {
  162. THIS_STRING->assign( s );
  163. return *this;
  164. }
  165. String& String::assign( String const &s, size_type pos, size_type n ) {
  166. THIS_STRING->assign( *STRING_OF( s ), pos, n );
  167. return *this;
  168. }
  169. String& String::assign( string const &s, size_type pos, size_type n ) {
  170. THIS_STRING->assign( s, pos, n );
  171. return *this;
  172. }
  173. String& String::assign( const_pointer s, size_type n ) {
  174. THIS_STRING->assign( s, n );
  175. return *this;
  176. }
  177. String& String::assign( size_type n, value_type c ) {
  178. THIS_STRING->assign( n, c );
  179. return *this;
  180. }
  181. String& String::assign( const_iterator i, const_iterator j ) {
  182. THIS_STRING->assign( i, j );
  183. return *this;
  184. }
  185. ////////// compare ////////////////////////////////////////////////////////////
  186. int String::compare( String const &s ) const {
  187. return THIS_STRING->compare( *STRING_OF( s ) );
  188. }
  189. int String::compare( string const &s ) const {
  190. return THIS_STRING->compare( s );
  191. }
  192. int String::compare( const_pointer s ) const {
  193. return THIS_STRING->compare( s );
  194. }
  195. int String::compare( size_type pos, size_type n, String const &s ) const {
  196. return THIS_STRING->compare( pos, n, *STRING_OF( s ) );
  197. }
  198. int String::compare( size_type pos, size_type n, string const &s ) const {
  199. return THIS_STRING->compare( pos, n, s );
  200. }
  201. int String::compare( size_type pos, size_type n, const_pointer s ) const {
  202. return THIS_STRING->compare( pos, n, s );
  203. }
  204. int String::compare( size_type pos, size_type n, String const &s,
  205. size_type s_pos, size_type s_n ) const {
  206. return THIS_STRING->compare( pos, n, *STRING_OF( s ), s_pos, s_n );
  207. }
  208. int String::compare( size_type pos, size_type n, string const &s,
  209. size_type s_pos, size_type s_n ) const {
  210. return THIS_STRING->compare( pos, n, s, s_pos, s_n );
  211. }
  212. int String::compare( size_type pos, size_type n, const_pointer s,
  213. size_type s_n ) const {
  214. return THIS_STRING->compare( pos, n, s, s_n );
  215. }
  216. ////////// clear/erase ////////////////////////////////////////////////////////
  217. void String::clear() {
  218. THIS_STRING->clear();
  219. }
  220. String& String::erase( size_type pos, size_type n ) {
  221. THIS_STRING->erase( pos, n );
  222. return *this;
  223. }
  224. String::iterator String::erase( iterator i ) {
  225. return THIS_STRING->erase( i );
  226. }
  227. String::iterator String::erase( iterator i, iterator j ) {
  228. return THIS_STRING->erase( i, j );
  229. }
  230. ////////// find ///////////////////////////////////////////////////////////////
  231. String::size_type String::find( String const &s, size_type pos ) const {
  232. return THIS_STRING->find( *STRING_OF( s ), pos );
  233. }
  234. String::size_type String::find( string const &s, size_type pos ) const {
  235. return THIS_STRING->find( s, pos );
  236. }
  237. String::size_type String::find( const_pointer s, size_type pos ) const {
  238. return THIS_STRING->find( s, pos );
  239. }
  240. String::size_type String::find( const_pointer s, size_type pos,
  241. size_type n ) const {
  242. return THIS_STRING->find( s, pos, n );
  243. }
  244. String::size_type String::find( value_type c, size_type pos ) const {
  245. return THIS_STRING->find( c, pos );
  246. }
  247. String::size_type String::find_first_of( String const &s,
  248. size_type pos ) const {
  249. return THIS_STRING->find_first_of( *STRING_OF( s ), pos );
  250. }
  251. String::size_type String::find_first_of( string const &s,
  252. size_type pos ) const {
  253. return THIS_STRING->find_first_of( s, pos );
  254. }
  255. String::size_type String::find_first_of( const_pointer s,
  256. size_type pos ) const {
  257. return THIS_STRING->find_first_of( s, pos );
  258. }
  259. String::size_type String::find_first_of( const_pointer s, size_type pos,
  260. size_type n ) const {
  261. return THIS_STRING->find_first_of( s, pos, n );
  262. }
  263. String::size_type String::find_first_of( value_type c, size_type pos ) const {
  264. return THIS_STRING->find_first_of( c, pos );
  265. }
  266. String::size_type String::find_first_not_of( String const &s,
  267. size_type pos ) const {
  268. return THIS_STRING->find_first_not_of( *STRING_OF( s ), pos );
  269. }
  270. String::size_type String::find_first_not_of( string const &s,
  271. size_type pos ) const {
  272. return THIS_STRING->find_first_not_of( s, pos );
  273. }
  274. String::size_type String::find_first_not_of( const_pointer s,
  275. size_type pos ) const {
  276. return THIS_STRING->find_first_not_of( s, pos );
  277. }
  278. String::size_type String::find_first_not_of( const_pointer s, size_type pos,
  279. size_type n ) const {
  280. return THIS_STRING->find_first_not_of( s, pos, n );
  281. }
  282. String::size_type String::find_first_not_of( value_type c,
  283. size_type pos ) const {
  284. return THIS_STRING->find_first_not_of( c, pos );
  285. }
  286. String::size_type String::find_last_of( String const &s, size_type pos ) const {
  287. return THIS_STRING->find_last_of( *STRING_OF( s ), pos );
  288. }
  289. String::size_type String::find_last_of( string const &s, size_type pos ) const {
  290. return THIS_STRING->find_last_of( s, pos );
  291. }
  292. String::size_type String::find_last_of( const_pointer s, size_type pos ) const {
  293. return THIS_STRING->find_last_of( s, pos );
  294. }
  295. String::size_type String::find_last_of( const_pointer s, size_type pos,
  296. size_type n ) const {
  297. return THIS_STRING->find_last_of( s, pos, n );
  298. }
  299. String::size_type String::find_last_of( value_type c, size_type pos ) const {
  300. return THIS_STRING->find_last_of( c, pos );
  301. }
  302. String::size_type String::find_last_not_of( String const &s,
  303. size_type pos ) const {
  304. return THIS_STRING->find_last_not_of( *STRING_OF( s ), pos );
  305. }
  306. String::size_type String::find_last_not_of( string const &s,
  307. size_type pos ) const {
  308. return THIS_STRING->find_last_not_of( s, pos );
  309. }
  310. String::size_type String::find_last_not_of( const_pointer s,
  311. size_type pos ) const {
  312. return THIS_STRING->find_last_not_of( s, pos );
  313. }
  314. String::size_type String::find_last_not_of( const_pointer s, size_type pos,
  315. size_type n ) const {
  316. return THIS_STRING->find_last_not_of( s, pos, n );
  317. }
  318. String::size_type String::find_last_not_of( value_type c,
  319. size_type pos ) const {
  320. return THIS_STRING->find_last_not_of( c, pos );
  321. }
  322. String::size_type String::rfind( String const &s, size_type pos ) const {
  323. return THIS_STRING->rfind( *STRING_OF( s ), pos );
  324. }
  325. String::size_type String::rfind( string const &s, size_type pos ) const {
  326. return THIS_STRING->rfind( s, pos );
  327. }
  328. String::size_type String::rfind( const_pointer s, size_type pos ) const {
  329. return THIS_STRING->rfind( s, pos );
  330. }
  331. String::size_type String::rfind( const_pointer s, size_type pos,
  332. size_type n ) const {
  333. return THIS_STRING->rfind( s, pos, n );
  334. }
  335. String::size_type String::rfind( value_type c, size_type pos ) const {
  336. return THIS_STRING->rfind( c, pos );
  337. }
  338. ////////// insert /////////////////////////////////////////////////////////////
  339. String& String::insert( size_type pos, String const &s ) {
  340. THIS_STRING->insert( pos, *STRING_OF( s ) );
  341. return *this;
  342. }
  343. String& String::insert( size_type pos, string const &s ) {
  344. THIS_STRING->insert( pos, s );
  345. return *this;
  346. }
  347. String& String::insert( size_type pos, const_pointer s ) {
  348. THIS_STRING->insert( pos, s );
  349. return *this;
  350. }
  351. String& String::insert( size_type pos, String const &s, size_type s_pos,
  352. size_type n ) {
  353. THIS_STRING->insert( pos, *STRING_OF( s ), s_pos, n );
  354. return *this;
  355. }
  356. String& String::insert( size_type pos, string const &s, size_type s_pos,
  357. size_type n ) {
  358. THIS_STRING->insert( pos, s, s_pos, n );
  359. return *this;
  360. }
  361. String& String::insert( size_type pos, const_pointer s, size_type n ) {
  362. THIS_STRING->insert( pos, s, n );
  363. return *this;
  364. }
  365. String& String::insert( size_type pos, size_type n, value_type c ) {
  366. THIS_STRING->insert( pos, n, c );
  367. return *this;
  368. }
  369. String::iterator String::insert( iterator pos, value_type c ) {
  370. return THIS_STRING->insert( pos, c );
  371. }
  372. void String::insert( iterator pos, size_type n, value_type c ) {
  373. THIS_STRING->insert( pos, n, c );
  374. }
  375. ////////// replace ////////////////////////////////////////////////////////////
  376. String& String::replace( size_type pos, size_type n, String const &s ) {
  377. THIS_STRING->replace( pos, n, *STRING_OF( s ) );
  378. return *this;
  379. }
  380. String& String::replace( size_type pos, size_type n, std::string const &s ) {
  381. THIS_STRING->replace( pos, n, s );
  382. return *this;
  383. }
  384. String& String::replace( size_type pos, size_type n, const_pointer s ) {
  385. THIS_STRING->replace( pos, n, s );
  386. return *this;
  387. }
  388. String& String::replace( size_type pos, size_type n, String const &s,
  389. size_type s_pos, size_type s_n ) {
  390. THIS_STRING->replace( pos, n, *STRING_OF( s ), s_pos, s_n );
  391. return *this;
  392. }
  393. String& String::replace( size_type pos, size_type n, string const &s,
  394. size_type s_pos, size_type s_n ) {
  395. THIS_STRING->replace( pos, n, s, s_pos, s_n );
  396. return *this;
  397. }
  398. String& String::replace( size_type pos, size_type n, const_pointer s,
  399. size_type s_n ) {
  400. THIS_STRING->replace( pos, n, s, s_n );
  401. return *this;
  402. }
  403. String& String::replace( size_type pos, size_type n, size_type c_n,
  404. value_type c ) {
  405. THIS_STRING->replace( pos, n, c_n, c );
  406. return *this;
  407. }
  408. String& String::replace( iterator i, iterator j, String const &s ) {
  409. THIS_STRING->replace( i, j, *STRING_OF( s ) );
  410. return *this;
  411. }
  412. String& String::replace( iterator i, iterator j, std::string const &s ) {
  413. THIS_STRING->replace( i, j, s );
  414. return *this;
  415. }
  416. String& String::replace( iterator i, iterator j, const_pointer s ) {
  417. THIS_STRING->replace( i, j, s );
  418. return *this;
  419. }
  420. String& String::replace( iterator i, iterator j, const_pointer s,
  421. size_type s_n ) {
  422. THIS_STRING->replace( i, j, s, s_n );
  423. return *this;
  424. }
  425. String& String::replace( iterator i, iterator j, size_type n, value_type c ) {
  426. THIS_STRING->replace( i, j, n, c );
  427. return *this;
  428. }
  429. String& String::replace( iterator i, iterator j, iterator si, iterator sj ) {
  430. THIS_STRING->replace( i, j, si, sj );
  431. return *this;
  432. }
  433. ////////// iterators //////////////////////////////////////////////////////////
  434. String::iterator String::begin() {
  435. return THIS_STRING->begin();
  436. }
  437. String::const_iterator String::begin() const {
  438. return THIS_STRING->begin();
  439. }
  440. String::iterator String::end() {
  441. return THIS_STRING->end();
  442. }
  443. String::const_iterator String::end() const {
  444. return THIS_STRING->end();
  445. }
  446. String::reverse_iterator String::rbegin() {
  447. return THIS_STRING->rbegin();
  448. }
  449. String::const_reverse_iterator String::rbegin() const {
  450. return THIS_STRING->rbegin();
  451. }
  452. String::reverse_iterator String::rend() {
  453. return THIS_STRING->rend();
  454. }
  455. String::const_reverse_iterator String::rend() const {
  456. return THIS_STRING->rend();
  457. }
  458. ////////// miscellaneous //////////////////////////////////////////////////////
  459. String::size_type String::copy( pointer buf, size_type n,
  460. size_type pos ) const {
  461. return THIS_STRING->copy( buf, n, pos );
  462. }
  463. String::const_pointer String::c_str() const {
  464. return THIS_STRING->c_str();
  465. }
  466. String::const_pointer String::data() const {
  467. return THIS_STRING->data();
  468. }
  469. void String::reserve( size_type n ) {
  470. THIS_STRING->reserve( n );
  471. }
  472. void String::resize( size_type n, value_type c ) {
  473. THIS_STRING->resize( n, c );
  474. }
  475. string String::str() const {
  476. return THIS_STRING->str();
  477. }
  478. String String::substr( size_type pos, size_type n ) const {
  479. string_type const s( THIS_STRING->substr( pos, n ) );
  480. zstring_ptr const zp = { &s };
  481. return String( zp );
  482. }
  483. void String::swap( String &s ) {
  484. THIS_STRING->swap( *STRING_OF( s ) );
  485. }
  486. ////////// relational operators ///////////////////////////////////////////////
  487. bool operator==( String const &s1, String const &s2 ) {
  488. return *STRING_OF( s1 ) == *STRING_OF( s2 );
  489. }
  490. bool operator==( String const &s1, string const &s2 ) {
  491. return *STRING_OF( s1 ) == s2;
  492. }
  493. bool operator==( String const &s1, String::const_pointer s2 ) {
  494. return *STRING_OF( s1 ) == s2;
  495. }
  496. bool operator<( String const &s1, String const &s2 ) {
  497. return *STRING_OF( s1 ) < *STRING_OF( s2 );
  498. }
  499. bool operator<( String const &s1, string const &s2 ) {
  500. return *STRING_OF( s1 ) < s2;
  501. }
  502. bool operator<( String const &s1, String::const_pointer s2 ) {
  503. return *STRING_OF( s1 ) < s2;
  504. }
  505. bool operator<( string const &s1, String const &s2 ) {
  506. return s1 < *STRING_OF( s2 );
  507. }
  508. bool operator<( String::const_pointer s1, String const &s2 ) {
  509. return s1 < *STRING_OF( s2 );
  510. }
  511. bool operator<=( String const &s1, String const &s2 ) {
  512. return *STRING_OF( s1 ) <= *STRING_OF( s2 );
  513. }
  514. bool operator<=( String const &s1, string const &s2 ) {
  515. return *STRING_OF( s1 ) <= s2;
  516. }
  517. bool operator<=( String const &s1, String::const_pointer s2 ) {
  518. return *STRING_OF( s1 ) <= s2;
  519. }
  520. bool operator<=( string const &s1, String const &s2 ) {
  521. return s1 <= *STRING_OF( s2 );
  522. }
  523. bool operator<=( String::const_pointer s1, String const &s2 ) {
  524. return s1 <= *STRING_OF( s2 );
  525. }
  526. ////////// concatenation //////////////////////////////////////////////////////
  527. String operator+( String const &s1, String const &s2 ) {
  528. string_type const s( *STRING_OF( s1 ) + *STRING_OF( s2 ) );
  529. String::zstring_ptr const zp = { &s };
  530. return String( zp );
  531. }
  532. String operator+( String const &s1, string const &s2 ) {
  533. string_type const s( *STRING_OF( s1 ) + s2 );
  534. String::zstring_ptr const zp = { &s };
  535. return String( zp );
  536. }
  537. String operator+( String const &s1, String::const_pointer s2 ) {
  538. string_type const s( *STRING_OF( s1 ) + s2 );
  539. String::zstring_ptr const zp = { &s };
  540. return String( zp );
  541. }
  542. String operator+( string const &s1, String const &s2 ) {
  543. string_type const s( s1 + *STRING_OF( s2 ) );
  544. String::zstring_ptr const zp = { &s };
  545. return String( zp );
  546. }
  547. String operator+( String::const_pointer s1, String const &s2 ) {
  548. string_type const s( s1 + *STRING_OF( s2 ) );
  549. String::zstring_ptr const zp = { &s };
  550. return String( zp );
  551. }
  552. ////////// ostream insertion //////////////////////////////////////////////////
  553. ostream& operator<<( ostream &os, String const &s ) {
  554. return os << *STRING_OF( s );
  555. }
  556. ///////////////////////////////////////////////////////////////////////////////
  557. } // namespace zorba
  558. /* vim:set et sw=2 ts=2: */