bbstring.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. #ifndef BB_STRING_H
  2. #define BB_STRING_H
  3. #include "bbtypes.h"
  4. #include "bbassert.h"
  5. namespace bbGC{
  6. void *malloc( size_t size );
  7. void free( void *p );
  8. }
  9. class bbCString;
  10. class bbString{
  11. struct Rep{
  12. #ifdef BB_THREADS
  13. std::atomic_int refs;
  14. #else
  15. int refs;
  16. #endif
  17. int length;
  18. bbChar data[0];
  19. static Rep *alloc( int length );
  20. template<class C> static Rep *create( const C *p,int length ){
  21. Rep *rep=alloc( length );
  22. for( int i=0;i<length;++i ) rep->data[i]=p[i];
  23. return rep;
  24. }
  25. template<class C> static Rep *create( const C *p ){
  26. const C *e=p;
  27. while( *e ) ++e;
  28. return create( p,e-p );
  29. }
  30. };
  31. static Rep _nullRep;
  32. #ifdef BB_THREADS
  33. std::atomic<Rep*> _rep;
  34. void retain()const{
  35. ++_rep.load()->refs;
  36. }
  37. void release(){
  38. Rep *rep=_rep.load();
  39. if( !--rep->refs && rep!=&_nullRep ) bbGC::free( rep );
  40. }
  41. #else
  42. Rep *_rep;
  43. void retain()const{
  44. ++_rep->refs;
  45. }
  46. void release(){
  47. if( !--_rep->refs && _rep!=&_nullRep ) bbGC::free( _rep );
  48. }
  49. #endif
  50. bbString( Rep *rep ):_rep(rep){
  51. }
  52. public:
  53. const char *c_str()const;
  54. bbString():_rep( &_nullRep ){
  55. }
  56. #if BB_THREADS
  57. bbString( const bbString &s ):_rep( s._rep.load() ){
  58. retain();
  59. }
  60. #else
  61. bbString( const bbString &s ):_rep( s._rep ){
  62. retain();
  63. }
  64. #endif
  65. bbString( const void *data );
  66. bbString( const void *data,int length );
  67. bbString( const bbChar *data );
  68. bbString( const bbChar *data,int length );
  69. bbString( const wchar_t *data );
  70. bbString( const wchar_t *data,int length );
  71. #if __OBJC__
  72. bbString( const NSString *str );
  73. #endif
  74. explicit bbString( bool b );
  75. explicit bbString( int n );
  76. explicit bbString( unsigned int n );
  77. explicit bbString( long n );
  78. explicit bbString( unsigned long n );
  79. explicit bbString( long long n );
  80. explicit bbString( unsigned long long n );
  81. explicit bbString( float n );
  82. explicit bbString( double n );
  83. ~bbString(){
  84. release();
  85. }
  86. #if BB_THREADS
  87. const bbChar *data()const{
  88. return _rep.load()->data;
  89. }
  90. int length()const{
  91. return _rep.load()->length;
  92. }
  93. #else
  94. const bbChar *data()const{
  95. return _rep->data;
  96. }
  97. int length()const{
  98. return _rep->length;
  99. }
  100. #endif
  101. bbChar operator[]( int index )const{
  102. bbDebugAssert( index>=0 && index<length(),"String character index out of range" );
  103. return data()[index];
  104. }
  105. bbString operator+()const{
  106. return *this;
  107. }
  108. bbString operator-()const;
  109. bbString operator+( const bbString &str )const;
  110. bbString operator+( const char *str )const{
  111. return operator+( bbString( str ) );
  112. }
  113. bbString operator*( int n )const;
  114. #ifdef BB_THREADS
  115. bbString &operator=( const bbString &str ){
  116. Rep *oldrep=_rep,*newrep=str._rep;
  117. if( _rep.compare_exchange_strong( oldrep,newrep ) ){
  118. ++newrep->refs;
  119. if( !--oldrep->refs && oldrep!=&_nullRep ) bbGC::free( oldrep );
  120. }
  121. return *this;
  122. }
  123. #else
  124. bbString &operator=( const bbString &str ){
  125. str.retain();
  126. release();
  127. _rep=str._rep;
  128. return *this;
  129. }
  130. #endif
  131. template<class C> bbString &operator=( const C *data ){
  132. release();
  133. _rep=Rep::create( data );
  134. return *this;
  135. }
  136. bbString &operator+=( const bbString &str ){
  137. *this=*this+str;
  138. return *this;
  139. }
  140. bbString &operator+=( const char *str ){
  141. return operator+=( bbString( str ) );
  142. }
  143. int find( bbString str,int from=0 )const;
  144. int findLast( const bbString &str,int from=0 )const;
  145. bool contains( const bbString &str )const{
  146. return find( str )!=-1;
  147. }
  148. bbString slice( int from )const;
  149. bbString slice( int from,int term )const;
  150. bbString left( int count )const{
  151. return slice( 0,count );
  152. }
  153. bbString right( int count )const{
  154. return slice( -count );
  155. }
  156. bbString mid( int from,int count )const{
  157. return slice( from,from+count );
  158. }
  159. bool startsWith( const bbString &str )const;
  160. bool endsWith( const bbString &str )const;
  161. bbString toUpper()const;
  162. bbString toLower()const;
  163. bbString capitalize()const;
  164. bbString trim()const;
  165. bbString trimStart()const;
  166. bbString trimEnd()const;
  167. bbString dup( int n )const;
  168. bbString replace( const bbString &str,const bbString &repl )const;
  169. bbArray<bbString> split( bbString sep )const;
  170. bbString join( bbArray<bbString> bits )const;
  171. int compare( const bbString &t )const;
  172. bool operator<( const bbString &t )const{
  173. return compare( t )<0;
  174. }
  175. bool operator>( const bbString &t )const{
  176. return compare( t )>0;
  177. }
  178. bool operator<=( const bbString &t )const{
  179. return compare( t )<=0;
  180. }
  181. bool operator>=( const bbString &t )const{
  182. return compare( t )>=0;
  183. }
  184. bool operator==( const bbString &t )const{
  185. return compare( t )==0;
  186. }
  187. bool operator!=( const bbString &t )const{
  188. return compare( t )!=0;
  189. }
  190. operator bbBool()const{
  191. return length()!=0;
  192. }
  193. operator bbInt()const;
  194. operator bbByte()const;
  195. operator bbUByte()const;
  196. operator bbShort()const;
  197. operator bbUShort()const;
  198. operator bbUInt()const;
  199. operator bbLong()const;
  200. operator bbULong()const;
  201. operator float()const;
  202. operator double()const;
  203. int utf8Length()const;
  204. void toCString( void *buf,int size )const;
  205. void toWString( void *buf,int size )const;
  206. #if __OBJC__
  207. NSString *ToNSString()const;
  208. #endif
  209. static bbString fromChar( int chr );
  210. static bbString fromChars( bbArray<int> chrs );
  211. static bbString fromCString( const void *data ){ return bbString( data ); }
  212. static bbString fromCString( const void *data,int size ){ return bbString( data,size ); }
  213. static bbString fromWString( const void *data ){ return bbString( (const wchar_t*)data ); }
  214. static bbString fromWString( const void *data,int size ){ return bbString( (const wchar_t*)data,size ); }
  215. };
  216. class bbCString{
  217. char *_data;
  218. public:
  219. bbCString():_data(0){}
  220. bbCString( const bbString &str );
  221. ~bbCString();
  222. operator char*()const;
  223. operator signed char*()const;
  224. operator unsigned char*()const;
  225. };
  226. class bbWString{
  227. wchar_t *_data;
  228. public:
  229. bbWString():_data(0){}
  230. bbWString( const bbString &str );
  231. ~bbWString();
  232. operator wchar_t*()const;
  233. };
  234. template<class C> bbString operator+( const C *str,const bbString &str2 ){
  235. return bbString::fromCString( str )+str2;
  236. }
  237. inline bbString BB_T( const char *p ){
  238. return bbString::fromCString( p );
  239. }
  240. #endif