BugInTheSYS

Untitled

Oct 30th, 2011
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 42.75 KB | None | 0 0
  1. #ifndef BC_STRING_H
  2. #define BC_STRING_H
  3.  
  4. #include "stdafx.h"
  5.  
  6. #define BC_STRING_MINIMUM 16  // Initial and minimal string data size
  7. #define BC_STRING_SLICE   8   // Allocated string data size is always a multiple of this
  8.  
  9. #define BC_BOOL_TRUE_STRING "true"   // Written when writing a true boolean to the string
  10. #define BC_BOOL_FALSE_STRING "false" // false
  11.  
  12. namespace LibBC {
  13.  
  14. class bcString {
  15. public:
  16.                   bcString( void );
  17.                   bcString( const bcString &sText );
  18.                   bcString( const bcString &sText, int nStart, int nEnd );
  19.                   bcString( const char *szText );
  20.                   bcString( const char *szText, int nStart, int nEnd );
  21.   explicit        bcString( const bool bFlag );
  22.   explicit        bcString( const char nCharacter );
  23.   explicit        bcString( const int nNumber );
  24.   explicit        bcString( const unsigned nNumber );
  25.   explicit        bcString( const float fNumber );
  26.   explicit        bcString( const double fNumber );
  27.                   ~bcString( void );
  28.    
  29.   const char      *CString( void ) const;
  30.   char            *PChar( void ) const;
  31.  
  32.                   operator const char *( void ) const;
  33.  
  34.   char            operator[]( int nChar ) const;
  35.   char            &operator[]( int nChar );
  36.  
  37.   void            operator=( const bcString &sText );
  38.   void            operator=( const char *szText );
  39.  
  40.   friend bcString operator+( const bcString &sTextA, const bcString &sTextB );
  41.   friend bcString operator+( const char *szTextA, const bcString &sTextB );
  42.   friend bcString operator+( const bcString &sTextA, const char *szTextB );
  43.  
  44.   friend bcString operator+( const bcString &sText, const bool bFlag );
  45.   friend bcString operator+( const bcString &sText, const char nCharacter );
  46.   friend bcString operator+( const bcString &sText, const int nNumber );
  47.   friend bcString operator+( const bcString &sText, const unsigned nNumber );
  48.   friend bcString operator+( const bcString &sText, const float fNumber );
  49.   friend bcString operator+( const bcString &sText, const double fNumber );
  50.  
  51.   bcString        &operator+=( const bcString &sText );
  52.   bcString        &operator+=( const char *szText );
  53.   bcString        &operator+=( const bool bFlag );
  54.   bcString        &operator+=( const char nCharacter );
  55.   bcString        &operator+=( const int nNumber );
  56.   bcString        &operator+=( const unsigned nNumber );
  57.   bcString        &operator+=( const float fNumber );
  58.   bcString        &operator+=( const double fNumber );
  59.  
  60.   friend bool     operator==( const bcString &sTextA, const bcString &sTextB );
  61.   friend bool     operator==( const bcString &sTextA, const char *szTextB );
  62.   friend bool     operator==( const char *szTextA, const bcString &sTextB );
  63.  
  64.   friend bool     operator!=( const bcString &sTextA, const bcString &sTextB );
  65.   friend bool     operator!=( const bcString &sTextA, const char *szTextB );
  66.   friend bool     operator!=( const char *szTextA, const bcString &sTextB );
  67.  
  68.   bool            Compare( const char *szText ) const;
  69.   bool            CompareUntil( const char *szText, int nEnd ) const;
  70.   bool            ComparePrefix( const char *szPrefix ) const;
  71.  
  72.   bool            CompareIns( const char *szText ) const;
  73.   bool            CompareUntilIns( const char *szText, int nEnd ) const;
  74.   bool            ComparePrefixIns( const char *szPrefix ) const;
  75.  
  76.   int             Length( void ) const;
  77.   int             Allocated( void ) const;
  78.   bcString        &Clear( void );
  79.   bcString        &Empty( void );
  80.   bool            IsEmpty( void ) const;
  81.   bcString        &Append( const char nCharacter );
  82.   bcString        &Append( const bcString &sText );
  83.   bcString        &Append( const char *szText );
  84.   bcString        &Append( const char *szText, int nLength );
  85.   bcString        &Insert( const char nCharacter, const int nIndex );
  86.   bcString        &Insert( const bcString &sText, const int nIndex );
  87.   bcString        &Insert( const char *szText, const int nIndex );
  88.   bcString        &Insert( const char *szText, const int nLength, const int nIndex );
  89.   bcString        &ToLower( void );
  90.   bcString        &ToUpper( void );
  91.   bcString        &Cut( const int nLength );
  92.   bcString        &Fill( const char nCharacter, const int nNewLength );
  93.  
  94.   int             Find( const char nCharacter, int nStart = 0, int nEnd = -1 ) const;
  95.   int             Find( const char *szText, bool bCaseSensitive = true, int nStart = 0, int nEnd = -1 ) const;
  96.   bool            Filter( const char *szFilter, bool bCaseSensitive ) const;
  97.   int             Last( const char nCharacter ) const;
  98.   int             Last( const char *szText, bool bCaseSensitive = true ) const;
  99.   bcString        Left( const int nLength ) const;
  100.   bcString        Right( const int nLength ) const;
  101.   bcString        Mid( const int nStart, const int nLength ) const;
  102.   bcString        &Remove( int nStart, int nLength );
  103.   bcString        &Replace( const char *szOld, const char *szNew );
  104.  
  105.   static bool     Istrcmp( const char *szTextA, const char *szTextB );
  106.   static bool     Istrncmp( const char *szTextA, const char *szTextB, size_t nLength );
  107.   static bool     Filter( const char *szFilter, const char *szText, bool bCaseSensitive );
  108.   static void     Remove( char *szText, int nStart, int nEnd );
  109.  
  110.   void            Reallocate( const int nAmount, bool bPreserveContent );
  111.   void            FreeData( void );
  112.  
  113.   // STATIC IMPLEMENTATIONS:
  114.   static bcString Clear( const bcString &String );
  115.   static bcString Empty( const bcString &String );
  116.   static bcString Append( const bcString &String, const char nCharacter );
  117.   static bcString Append( const bcString &String, const bcString &sAppendix );
  118.   static bcString Append( const bcString &String, const char *szText );
  119.   static bcString Append( const bcString &String, const char *szText, const int nLength );
  120.   static bcString Insert( const bcString &String, const char nCharacter, const int nIndex );
  121.   static bcString Insert( const bcString &String, const bcString &sInsertion, const int nIndex );
  122.   static bcString Insert( const bcString &String, const char *szText, const int nIndex );
  123.   static bcString Insert( const bcString &String, const char *szText, const int nLength, const int nIndex );
  124.   static bcString ToLower( const bcString &String );
  125.   static bcString ToUpper( const bcString &String );
  126.   static bcString Cut( const bcString &String, const int nLength );
  127.   static bcString Remove( const bcString &String, int nStart, int nLength );
  128.   static bcString Replace( const bcString &String, const char *szOld, const char *szNew );
  129.  
  130. protected:
  131.   int             _nLength;
  132.   char            *_data;
  133.   int             _nAllocated;
  134.   char            _base[ BC_STRING_MINIMUM ];
  135.  
  136.   void            _Init( void );
  137.   void            _EnsureAlloc( const int nAmount, bool bPreserveContent = true );
  138. };
  139.  
  140. /*
  141. ====================
  142. bcString::_Init
  143.  
  144.   Initializes the bcString.
  145. ====================
  146. */
  147. BC_INLINE void bcString::_Init( void ) {
  148.   _nLength = 0;
  149.   _data = _base;
  150.   _data[ 0 ] = '\0';
  151.   _nAllocated = BC_STRING_MINIMUM;
  152. }
  153.  
  154. /*
  155. ====================
  156. bcString::_EnsureAlloc
  157.  
  158.   Makes sure stuff is allocated.
  159. ====================
  160. */
  161. BC_INLINE void bcString::_EnsureAlloc( const int nAmount, bool bPreserveContent ) {
  162.   if( nAmount > _nAllocated ) {
  163.     Reallocate( nAmount, bPreserveContent );
  164.   };
  165. }
  166.  
  167. /*
  168. ====================
  169. bcString::bcString
  170.  
  171.   Creates the bcString.
  172. ====================
  173. */
  174. BC_INLINE bcString::bcString( void ) {
  175.   _Init();
  176. }
  177.  
  178. BC_INLINE bcString::bcString( const bcString &sText ) {
  179.   int nLength;
  180.  
  181.   _Init();
  182.   nLength = sText.Length();
  183.   _EnsureAlloc( nLength + 1, false );
  184.   strcpy( _data, sText._data );
  185.   _nLength = nLength;
  186. }
  187.  
  188. BC_INLINE bcString::bcString( const bcString &sText, int nStart, int nEnd ) {
  189.   int nLength, i;
  190.   _Init();
  191.  
  192.   ValueRange( nStart, 0, sText.Length() - 1 );
  193.   ValueRange( nEnd, 0, sText.Length() - 1 );
  194.  
  195.   nLength = nEnd - nStart;
  196.   if( nLength < 0 ) {
  197.     nLength = 0;
  198.   }
  199.  
  200.   _EnsureAlloc( nLength + 1, false );
  201.  
  202.   for( i = 0; i < nLength; i++ ) {
  203.     _data[ i ] = sText[ nStart + i ];
  204.   }
  205.  
  206.   _data[ i + 1 ] = '\0';
  207.   _nLength = nLength;
  208. }
  209.  
  210. BC_INLINE bcString::bcString( const char *szText ) {
  211.   int nLength;
  212.   _Init();
  213.  
  214.   if( szText ) {
  215.     nLength = strlen( szText );
  216.     _EnsureAlloc( nLength + 1, false );
  217.     strcpy( _data, szText );
  218.     _nLength = nLength;
  219.   }
  220. }
  221.  
  222. BC_INLINE bcString::bcString( const char *szText, int nStart, int nEnd ) {
  223.   int nPartLength, nStringLength, i;
  224.   _Init();
  225.  
  226.   if( szText ) {
  227.     nStringLength = strlen( szText );
  228.     ValueRange( nStart, 0, nStringLength - 1 );
  229.     ValueRange( nEnd, 0, nStringLength - 1 );
  230.  
  231.     nPartLength = nEnd - nStart + 1;
  232.     if( nPartLength < 0 ) {
  233.       nPartLength = 0;
  234.     }
  235.  
  236.     _EnsureAlloc( nPartLength + 1, false );
  237.     for( i = 0; i < nPartLength; i++ ) {
  238.       _data[ i ] = szText[ nStart + i ];
  239.     }
  240.  
  241.     _data[ i ] = '\0';
  242.     _nLength = nPartLength;
  243.   }
  244. }
  245.  
  246. BC_INLINE bcString::bcString( const bool bFlag ) {
  247.   int nLength;
  248.   _Init();
  249.  
  250.   if( bFlag ) {
  251.     nLength = strlen( BC_BOOL_TRUE_STRING );
  252.     _EnsureAlloc( nLength + 1, false );
  253.     strcpy( _data, BC_BOOL_TRUE_STRING );
  254.     //_data[ nLength ] = '\0';
  255.     _nLength = nLength;
  256.   } else {
  257.     nLength = strlen( BC_BOOL_FALSE_STRING );
  258.     _EnsureAlloc( nLength + 1, false );
  259.     strcpy( _data, BC_BOOL_FALSE_STRING );
  260.     //_data[ nLength ] = '\0';
  261.     _nLength = nLength;
  262.   }
  263. }
  264.  
  265. BC_INLINE bcString::bcString( const char nCharacter ) {
  266.   _Init();
  267.   _EnsureAlloc( 2, false );
  268.   _data[ 0 ] = nCharacter;
  269.   _data[ 1 ] = '\0';
  270.   _nLength = 1;
  271. }
  272.  
  273. BC_INLINE bcString::bcString( const int nNumber ) {
  274.   char szNumber[ 12 ];
  275.   int nLength;
  276.  
  277.   _Init();
  278.   nLength = sprintf( szNumber, "%i", nNumber );
  279.   _EnsureAlloc( nLength + 1, false );
  280.   strcpy( _data, szNumber );
  281.   _nLength = nLength;
  282. }
  283.  
  284. BC_INLINE bcString::bcString( const unsigned nNumber ) {
  285.   char szNumber[ 12 ];
  286.   int nLength;
  287.  
  288.   _Init();
  289.   nLength = sprintf( szNumber, "%i", nNumber );
  290.   _EnsureAlloc( nLength + 1, false );
  291.   strcpy( _data, szNumber );
  292.   _nLength = nLength;
  293. }
  294.  
  295. BC_INLINE bcString::bcString( const float fNumber ) {
  296.   char szNumber[ 32 ];
  297.   int nLength;
  298.  
  299.   _Init();
  300.   //TODO: _snprintf_s might not work for non-VC compilers(?)
  301.   nLength = bcMath::Minimumi( _snprintf_s( szNumber, sizeof( szNumber ), "%f", fNumber ), 32 );
  302.   while( nLength > 0 && szNumber[ nLength - 1 ] == '0' ) szNumber[ --nLength ] = '\0';
  303.   while( nLength > 0 && szNumber[ nLength - 1 ] == '.' ) szNumber[ --nLength ] = '\0';
  304.  
  305.   _EnsureAlloc( nLength + 1 );
  306.   strcpy( _data, szNumber );
  307.   _nLength = nLength;
  308. }
  309.  
  310. BC_INLINE bcString::bcString( const double fNumber ) {
  311.   char szNumber[ 64 ];
  312.   int nLength;
  313.  
  314.   _Init();
  315.   //TODO: _snprintf_s might not work for non-VC compilers(?)
  316.   nLength = bcMath::Minimumi( _snprintf_s( szNumber, sizeof( szNumber ), "%f", fNumber ), 64 );
  317.   while( nLength > 0 && szNumber[ nLength - 1 ] == '0' ) szNumber[ --nLength ] = '\0';
  318.   while( nLength > 0 && szNumber[ nLength - 1 ] == '.' ) szNumber[ --nLength ] = '\0';
  319.  
  320.   _EnsureAlloc( nLength + 1 );
  321.   strcpy( _data, szNumber );
  322.   _nLength = nLength;
  323. }
  324.  
  325. /*
  326. ====================
  327. bcString::~bcString
  328.  
  329.   Destroys the bcString.
  330. ====================
  331. */
  332. BC_INLINE bcString::~bcString( void ) {
  333.   FreeData();
  334. }
  335.  
  336. /*
  337. ====================
  338. bcString::CString
  339.  
  340.   Returns a constant pointer to the text.
  341. ====================
  342. */
  343. BC_INLINE const char *bcString::CString( void ) const {
  344.   return _data;
  345. }
  346.  
  347. /*
  348. ====================
  349. bcString::PChar
  350.  
  351.   Returns a pointer to the text. Since it allocates new memory, it should be avoided as long as CString is an alternative.
  352. ====================
  353. */
  354. BC_INLINE char *bcString::PChar( void ) const {
  355.   char *pText = new char[ _nLength + 1 ];
  356.   strcpy( pText, _data );
  357.   return pText;
  358. }
  359.  
  360. /*
  361. ====================
  362. bcString::operator const char *
  363.  
  364.   Returns a constant pointer to the text.
  365. ====================
  366. */
  367. BC_INLINE bcString::operator const char *( void ) const {
  368.   return CString();
  369. }
  370.  
  371. /*
  372. ====================
  373. bcString::operator[]
  374.  
  375.   Returns the value of the char at the desired position, rvalue.
  376. ====================
  377. */
  378. BC_INLINE char bcString::operator[]( int nChar ) const {
  379.   return _data[ nChar ];
  380. }
  381.  
  382. /*
  383. ====================
  384. bcString::operator[]
  385.  
  386.   Returns the reference to the char at the desired position, lvalue.
  387. ====================
  388. */
  389. BC_INLINE char &bcString::operator[]( int nChar ) {
  390.   return _data[ nChar ];
  391. }
  392.  
  393. /*
  394. ====================
  395. bcString::operator=
  396.  
  397.   Assigns another string to this instance.
  398. ====================
  399. */
  400. BC_INLINE void bcString::operator=( const bcString &sText ) {
  401.   int nLength;
  402.  
  403.   nLength = sText.Length();
  404.   _EnsureAlloc( nLength + 1, false );
  405.   memcpy( _data, sText._data, nLength );
  406.   _data[ nLength ] = '\0';
  407.   _nLength = nLength;
  408. }
  409.  
  410. /*
  411. ====================
  412. bcString::operator=
  413.  
  414.   Assigns another string to this instance.
  415. ====================
  416. */
  417. BC_INLINE void bcString::operator=( const char *szText ) {
  418.   if( szText ) {
  419.     int nLength;
  420.     nLength = strlen( szText );
  421.     _EnsureAlloc( nLength + 1, false );
  422.     memcpy( _data, szText, nLength );
  423.     _data[ nLength ] = '\0';
  424.     _nLength = nLength;
  425.   }
  426. }
  427.  
  428. /*
  429. ====================
  430. bcString::operator+
  431.  
  432.   Returns the two concatenated strings.
  433. ====================
  434. */
  435. BC_INLINE bcString operator+( const bcString &sTextA, const bcString &sTextB ) {
  436.   bcString sResult( sTextA );
  437.   sResult.Append( sTextB );
  438.   return sResult;
  439. }
  440.  
  441. /*
  442. ====================
  443. bcString::operator+
  444.  
  445.   Returns the two concatenated strings.
  446. ====================
  447. */
  448. BC_INLINE bcString operator+( const bcString &sTextA, const char *szTextB ) {
  449.   bcString sResult( sTextA );
  450.   sResult.Append( szTextB );
  451.   return sResult;
  452. }
  453.  
  454. /*
  455. ====================
  456. bcString::operator+
  457.  
  458.   Returns the two concatenated strings.
  459. ====================
  460. */
  461. BC_INLINE bcString operator+( const char *szTextA, const bcString &sTextB ) {
  462.   bcString sResult( szTextA );
  463.   sResult.Append( sTextB );
  464.   return sResult;
  465. }
  466.  
  467. /*
  468. ====================
  469. bcString::operator+
  470.  
  471.   Returns the two concatenated arguments.
  472. ====================
  473. */
  474. BC_INLINE bcString operator+( const bcString &sText, const bool bFlag ) {
  475.   bcString sResult( sText );
  476.   sResult += bFlag;
  477.   return sResult;
  478. }
  479.  
  480. /*
  481. ====================
  482. bcString::operator+
  483.  
  484.   Returns the two concatenated arguments.
  485. ====================
  486. */
  487. BC_INLINE bcString operator+( const bcString &sText, const char nCharacter ) {
  488.   bcString sResult( sText );
  489.   sResult.Append( nCharacter );
  490.   return sResult;
  491. }
  492.  
  493. /*
  494. ====================
  495. bcString::operator+
  496.  
  497.   Returns the two concatenated arguments.
  498. ====================
  499. */
  500. BC_INLINE bcString operator+( const bcString &sText, const int nNumber ) {
  501.   bcString sResult( sText );
  502.   sResult += nNumber;
  503.   return sResult;
  504. }
  505.  
  506. /*
  507. ====================
  508. bcString::operator+
  509.  
  510.   Returns the two concatenated arguments.
  511. ====================
  512. */
  513. BC_INLINE bcString operator+( const bcString &sText, const unsigned nNumber ) {
  514.   bcString sResult( sText );
  515.   sResult += nNumber;
  516.   return sResult;
  517. }
  518.  
  519. /*
  520. ====================
  521. bcString::operator+
  522.  
  523.   Returns the two concatenated arguments.
  524. ====================
  525. */
  526. BC_INLINE bcString operator+( const bcString &sText, const float fNumber ) {
  527.   bcString sResult( sText );
  528.   sResult += fNumber;
  529.   return sResult;
  530. }
  531.  
  532. /*
  533. ====================
  534. bcString::operator+
  535.  
  536.   Returns the two concatenated arguments.
  537. ====================
  538. */
  539. BC_INLINE bcString operator+( const bcString &sText, const double fNumber ) {
  540.   bcString sResult( sText );
  541.   sResult += fNumber;
  542.   return sResult;
  543. }
  544.  
  545. /*
  546. ====================
  547. bcString::operator+=
  548.  
  549.   Appends to this instance the argument given.
  550. ====================
  551. */
  552. BC_INLINE bcString &bcString::operator+=( const bcString &sText ) {
  553.   Append( sText );
  554.   return *this;
  555. }
  556.  
  557. /*
  558. ====================
  559. bcString::operator+=
  560.  
  561.   Appends to this instance the argument given.
  562. ====================
  563. */
  564. BC_INLINE bcString &bcString::operator+=( const char *szText ) {
  565.   Append( szText );
  566.   return *this;
  567. }
  568.  
  569. /*
  570. ====================
  571. bcString::operator+=
  572.  
  573.   Appends to this instance the argument given.
  574. ====================
  575. */
  576. BC_INLINE bcString &bcString::operator+=( const bool bFlag ) {
  577.   Append( bFlag ? BC_BOOL_TRUE_STRING : BC_BOOL_FALSE_STRING );
  578.   return *this;
  579. }
  580.  
  581. /*
  582. ====================
  583. bcString::operator+=
  584.  
  585.   Appends to this instance the argument given.
  586. ====================
  587. */
  588. BC_INLINE bcString &bcString::operator+=( const char nCharacter ) {
  589.   Append( nCharacter );
  590.   return *this;
  591. }
  592.  
  593. /*
  594. ====================
  595. bcString::operator+=
  596.  
  597.   Appends to this instance the argument given.
  598. ====================
  599. */
  600. BC_INLINE bcString &bcString::operator+=( const int nNumber ) {
  601.   char pBuffer[ 12 ];
  602.  
  603.   sprintf( pBuffer, "%i", nNumber );
  604.   Append( pBuffer );
  605.  
  606.   return *this;
  607. }
  608.  
  609. /*
  610. ====================
  611. bcString::operator+=
  612.  
  613.   Appends to this instance the argument given.
  614. ====================
  615. */
  616. BC_INLINE bcString &bcString::operator+=( const unsigned nNumber ) {
  617.   char pBuffer[ 12 ];
  618.  
  619.   sprintf( pBuffer, "%u", nNumber );
  620.   Append( pBuffer );
  621.  
  622.   return *this;
  623. }
  624.  
  625. /*
  626. ====================
  627. bcString::operator+=
  628.  
  629.   Appends to this instance the argument given.
  630. ====================
  631. */
  632. BC_INLINE bcString &bcString::operator+=( const float fNumber ) {
  633.   char szNumber[ 32 ];
  634.   int nLength;
  635.  
  636.   //TODO: _snprintf_s might not work for non-VC compilers(?)
  637.   nLength = bcMath::Minimumi( _snprintf_s( szNumber, sizeof( szNumber ), "%f", fNumber ), 32 );
  638.   while( nLength > 0 && szNumber[ nLength - 1 ] == '0' ) szNumber[ --nLength ] = '\0';
  639.   while( nLength > 0 && szNumber[ nLength - 1 ] == '.' ) szNumber[ --nLength ] = '\0';
  640.  
  641.   Append( szNumber );
  642.   return *this;
  643. }
  644.  
  645. /*
  646. ====================
  647. bcString::operator+=
  648.  
  649.   Appends to this instance the argument given.
  650. ====================
  651. */
  652. BC_INLINE bcString &bcString::operator+=( const double fNumber ) {
  653.   char szNumber[ 64 ];
  654.   int nLength;
  655.  
  656.   //TODO: _snprintf_s might not work for non-VC compilers(?)
  657.   nLength = bcMath::Minimumi( _snprintf_s( szNumber, sizeof( szNumber ), "%f", fNumber ), 64 );
  658.   while( nLength > 0 && szNumber[ nLength - 1 ] == '0' ) szNumber[ --nLength ] = '\0';
  659.   while( nLength > 0 && szNumber[ nLength - 1 ] == '.' ) szNumber[ --nLength ] = '\0';
  660.  
  661.   Append( szNumber );
  662.   return *this;
  663. }
  664.  
  665. /*
  666. ====================
  667. operator!=( bcString&, bcString& )
  668.  
  669.   Compares the two strings given case-sensitively.
  670. ====================
  671. */
  672. BC_INLINE bool operator==( const bcString &sTextA, const bcString &sTextB ) {
  673.   return !strcmp( sTextA._data, sTextA._data );
  674. }
  675.  
  676. /*
  677. ====================
  678. operator!=( bcString&, char* )
  679.  
  680.   Compares the two strings given case-sensitively.
  681. ====================
  682. */
  683. BC_INLINE bool operator==( const bcString &sTextA, const char *szTextB ) {
  684.   assert( szTextB );
  685.   return !strcmp( sTextA._data, szTextB );
  686. }
  687.  
  688. /*
  689. ====================
  690. operator==( char*, bcString& )
  691.  
  692.   Compares the two strings given case-sensitively.
  693. ====================
  694. */
  695. BC_INLINE bool operator==( const char *szTextA, const bcString &sTextB ) {
  696.   assert( szTextA );
  697.   return !strcmp( szTextA, sTextB._data );
  698. }
  699.  
  700. /*
  701. ====================
  702. operator!=( bcString&, bcString& )
  703.  
  704.   Compares the two strings given case-sensitively.
  705. ====================
  706. */
  707. BC_INLINE bool operator!=( const bcString &sTextA, const bcString &sTextB ) {
  708.   return strcmp( sTextA._data, sTextB._data );
  709. }
  710.  
  711. /*
  712. ====================
  713. operator!=( bcString&, char* )
  714.  
  715.   Compares the two strings given case-sensitively.
  716. ====================
  717. */
  718. BC_INLINE bool operator!=( const bcString &sTextA, const char *szTextB ) {
  719.   assert( szTextB );
  720.   return strcmp( sTextA._data, szTextB );
  721. }
  722.  
  723. /*
  724. ====================
  725. operator!=( char*, bcString& )
  726.  
  727.   Compares the two strings given case-sensitively.
  728. ====================
  729. */
  730. BC_INLINE bool operator!=( const char *szTextA, const bcString &sTextB ) {
  731.   assert( szTextA );
  732.   return strcmp( szTextA, sTextB._data );
  733. }
  734.  
  735. /*
  736. ====================
  737. bcString::Compare
  738.  
  739.   Compares this intance with the string given case-sensitively.
  740. ====================
  741. */
  742. BC_INLINE bool bcString::Compare( const char *szText ) const {
  743.   assert( szText );
  744.   return !strcmp( _data, szText );
  745. }
  746.  
  747. /*
  748. ====================
  749. bcString::CompareUntil
  750.  
  751.   Compares this intance with the string given case-sensitively until it reaches the position specified by nEnd.
  752. ====================
  753. */
  754. BC_INLINE bool bcString::CompareUntil( const char *szText, int nEnd ) const {
  755.   assert( szText );
  756.   if( nEnd < 0 ) {
  757.     nEnd = 0;
  758.   }
  759.   return !strncmp( _data, szText, nEnd + 1 );
  760. }
  761.  
  762. /*
  763. ====================
  764. bcString::ComparePrefix
  765.  
  766.   Compares this intance with the string given case-sensitively until it reaches the end of the given string.
  767. ====================
  768. */
  769. BC_INLINE bool bcString::ComparePrefix( const char *szText ) const {
  770.   assert( szText );
  771.   return !strncmp( _data, szText, strlen( szText ) );
  772. }
  773.  
  774. /*
  775. ====================
  776. bcString::CompareIns
  777.  
  778.   Compares this intance with the string given case-insensitively.
  779. ====================
  780. */
  781. BC_INLINE bool bcString::CompareIns( const char *szText ) const {
  782.   assert( szText );
  783.   return Istrcmp( _data, szText );
  784. }
  785.  
  786. /*
  787. ====================
  788. bcString::CompareUntilIns
  789.  
  790.   Compares this intance with the string given case-sensitively until it reaches nEnd.
  791. ====================
  792. */
  793. BC_INLINE bool bcString::CompareUntilIns( const char *szText, int nEnd ) const {
  794.   assert( szText );
  795.   if( nEnd < 0 ) {
  796.     nEnd = 0;
  797.   }
  798.   return Istrncmp( _data, szText,  nEnd + 1 );
  799. }
  800.  
  801. /*
  802. ====================
  803. bcString::ComparePrefixIns
  804.  
  805.   Compares this intance with the string given case-sensitively until it reaches the end of the given string.
  806. ====================
  807. */
  808. BC_INLINE bool bcString::ComparePrefixIns( const char *szText ) const {
  809.   assert( szText );
  810.   return Istrncmp( _data, szText,  strlen( szText ) );
  811. }
  812.  
  813. /*
  814. ====================
  815. bcString::Length
  816.  
  817.   Returns the length of this instance.
  818. ====================
  819. */
  820. BC_INLINE int bcString::Length( void ) const {
  821.   return _nLength;
  822. }
  823.  
  824. /*
  825. ====================
  826. bcString::Allocated
  827.  
  828.   Returns the amount of bytes this instance has allocated for the data.
  829. ====================
  830. */
  831. BC_INLINE int bcString::Allocated( void ) const {
  832.   return _nAllocated;
  833. }
  834.  
  835. /*
  836. ====================
  837. bcString::Clear
  838.  
  839.   Clears the string.
  840. ====================
  841. */
  842. BC_INLINE bcString &bcString::Clear( void ) {
  843.   delete[] _data;
  844.   _data = _base;
  845.   _data[ 0 ] = '\0';
  846.   _nAllocated = BC_STRING_MINIMUM;
  847.   _nLength = 0;
  848.   return *this;
  849. }
  850.  
  851. /*
  852. ====================
  853. bcString::Empty
  854.  
  855.   Removes all characters the string.
  856. ====================
  857. */
  858. BC_INLINE bcString &bcString::Empty( void ) {
  859.   _data[ 0 ] = '\0';
  860.   _nLength = 0;
  861.   return *this;
  862. }
  863.  
  864. /*
  865. ====================
  866. bcString::Append
  867.  
  868.   Appends the variable passed to this instance.
  869. ====================
  870. */
  871. BC_INLINE bcString &bcString::Append( const char nCharacter ) {
  872.   _EnsureAlloc( ++_nLength );
  873.   _data[ _nLength - 1 ] = nCharacter;
  874.   _data[ _nLength ] = '\0';
  875.   return *this;
  876. }
  877.  
  878. /*
  879. ====================
  880. bcString::Append
  881.  
  882.   Appends the variable passed to this instance.
  883. ====================
  884. */
  885. BC_INLINE bcString &bcString::Append( const bcString &sText ) {
  886.   _EnsureAlloc( _nLength + sText._nLength + 1 );
  887.   strcpy( _data + _nLength, sText._data );
  888.   _nLength += sText._nLength;
  889.   return *this;
  890. }
  891.  
  892. /*
  893. ====================
  894. bcString::Append
  895.  
  896.   Appends the variable passed to this instance.
  897. ====================
  898. */
  899. BC_INLINE bcString &bcString::Append( const char *szText ) {
  900.   assert( szText );
  901.   int nLength;
  902.   nLength = strlen( szText );
  903.   _EnsureAlloc( _nLength + nLength + 1 );
  904.   strcpy( _data + _nLength, szText );
  905.   _nLength += nLength;
  906.   return *this;
  907. }
  908.  
  909. /*
  910. ====================
  911. bcString::Append
  912.  
  913.   Appends the variable passed to this instance.
  914. ====================
  915. */
  916. BC_INLINE bcString &bcString::Append( const char *szText, int nLength ) {
  917.   assert( szText );
  918.   ValueRange( nLength, 0, static_cast<signed>( strlen( szText ) ) - 1 );
  919.   _EnsureAlloc( _nLength + nLength + 1 );
  920.   strcpy( _data + _nLength, szText );
  921.   _nLength += nLength;
  922.   return *this;
  923. }
  924.  
  925. /*
  926. ====================
  927. bcString::Insert
  928.  
  929.   Inserts the variable passed to this instance at nIndex.
  930. ====================
  931. */
  932. BC_INLINE bcString &bcString::Insert( const char nCharacter, const int nIndex ) {
  933.   assert( nIndex < _nLength );
  934.   char *pCurrent;
  935.   _EnsureAlloc( ++_nLength );
  936.   pCurrent = _data + _nLength;
  937.   while( true ) {
  938.     *pCurrent-- = *( pCurrent - 1 );
  939.     if( pCurrent == _data + nIndex ) break;
  940.   }
  941.   *( _data + nIndex ) = nCharacter;
  942.   return *this;
  943. }
  944.  
  945. /*
  946. ====================
  947. bcString::Insert
  948.  
  949.   Inserts the variable passed to this instance at nIndex.
  950. ====================
  951. */
  952. BC_INLINE bcString &bcString::Insert( const bcString &sText, const int nIndex ) {
  953.   assert( nIndex < _nLength );
  954.   char *pCurrent;
  955.   int nLength;
  956.   nLength = sText._nLength;
  957.   _EnsureAlloc( _nLength + nLength + 1 );
  958.   pCurrent = _data + _nLength + nLength;
  959.  
  960.   while( true ) {
  961.     *pCurrent-- = *( pCurrent - nLength );
  962.     if( pCurrent == _data + nIndex ) break;
  963.   }
  964.   memcpy( _data + nIndex, sText._data, nLength );
  965.   _nLength += nLength;
  966.   return *this;
  967. }
  968.  
  969. /*
  970. ====================
  971. bcString::Insert
  972.  
  973.   Inserts the variable passed to this instance at nIndex.
  974. ====================
  975. */
  976. BC_INLINE bcString &bcString::Insert( const char *szText, const int nIndex ) {
  977.   assert( szText );
  978.   assert( nIndex < _nLength );
  979.   char *pCurrent;
  980.   int nLength;
  981.   nLength = strlen( szText );
  982.   _EnsureAlloc( _nLength + nLength + 1 );
  983.   pCurrent = _data + _nLength + nLength;
  984.  
  985.   while( true ) {
  986.     *pCurrent-- = *( pCurrent - nLength );
  987.     if( pCurrent == _data + nIndex ) break;
  988.   }
  989.   memcpy( _data + nIndex, szText, nLength );
  990.   _nLength += nLength;
  991.   return *this;
  992. }
  993.  
  994. /*
  995. ====================
  996. bcString::Insert
  997.  
  998.   Inserts the variable passed to this instance at nIndex.
  999. ====================
  1000. */
  1001. BC_INLINE bcString &bcString::Insert( const char *szText, const int nLength, const int nIndex ) {
  1002.   assert( szText );
  1003.   assert( nIndex < _nLength );
  1004.   char *pCurrent;
  1005.   _EnsureAlloc( _nLength + nLength + 1 );
  1006.   pCurrent = _data + _nLength + nLength;
  1007.  
  1008.   while( true ) {
  1009.     *pCurrent-- = *( pCurrent - nLength );
  1010.     if( pCurrent == _data + nIndex ) break;
  1011.   }
  1012.   memcpy( _data + nIndex, szText, nLength );
  1013.   _nLength += nLength;
  1014.   return *this;
  1015. }
  1016.  
  1017. /*
  1018. ====================
  1019. bcString::ToLower
  1020.  
  1021.   Converts this string to lower case.
  1022. ====================
  1023. */
  1024. BC_INLINE bcString &bcString::ToLower( void ) {
  1025.   char *nChar;
  1026.   int i;
  1027.   nChar = _data;
  1028.   for( i = 0; i < _nLength; i++ ) {
  1029.     if( ( *nChar >= 'A' && *nChar <= 'Z' ) || ( *nChar >= 0xC0 && *nChar <= 0xDE && *nChar != 0xD7 ) ) {
  1030.       *nChar += 0x20;
  1031.     }
  1032.     ++nChar;
  1033.   }
  1034.   return *this;
  1035. }
  1036.  
  1037. /*
  1038. ====================
  1039. bcString::ToUpper
  1040.  
  1041.   Converts this string to upper case.
  1042. ====================
  1043. */
  1044. BC_INLINE bcString &bcString::ToUpper( void ) {
  1045.   char *nChar;
  1046.   int i;
  1047.   nChar = _data;
  1048.   for( i = 0; i < _nLength; i++ ) {
  1049.     if( ( *nChar >= 'a' && *nChar <= 'z' ) || ( *nChar >= 0xE0 && *nChar <= 0xFE && *nChar != 0xF7 ) ) {
  1050.       *nChar -= 0x20;
  1051.     }
  1052.     ++nChar;
  1053.   }
  1054.   return *this;
  1055. }
  1056.  
  1057. /*
  1058. ====================
  1059. bcString::Cut
  1060.  
  1061.   Cuts this string down to the length given.
  1062. ====================
  1063. */
  1064. BC_INLINE bcString &bcString::Cut( const int nLength ) {
  1065.   assert( nLength <= _nLength );
  1066.   _data[ nLength ] = '\0';
  1067.   _nLength = nLength;
  1068.   return *this;
  1069. }
  1070.  
  1071. /*
  1072. ====================
  1073. bcString::Fill
  1074.  
  1075.   Fills this string with nNewLength nCharacters.
  1076. ====================
  1077. */
  1078. BC_INLINE bcString &bcString::Fill( const char nCharacter, const int nNewLength ) {
  1079.   assert( nNewLength >= 0 );
  1080.   _EnsureAlloc( nNewLength + 1, false );
  1081.   memset( _data, static_cast<int>( nCharacter ), nNewLength );
  1082.   _nLength = nNewLength;
  1083.   _data[ _nLength ] = '\0';
  1084.   return *this;
  1085. }
  1086.  
  1087. /*
  1088. ====================
  1089. bcString::Find
  1090.  
  1091.   Finds the first occasion of nCharacter in this string, starting to look at nStart and stopping at nEnd.
  1092.   Returns -1 on fail.
  1093. ====================
  1094. */
  1095. BC_INLINE int bcString::Find( const char nCharacter, int nStart, int nEnd ) const {
  1096.   ValueRange( nStart, 0, _nLength - 1 );
  1097.   ValueRange( nEnd, 0, _nLength - 1 );
  1098.   do {
  1099.     if( _data[ nStart ] = nCharacter ) return nStart;
  1100.   } while( nStart++ != nEnd );
  1101.   return -1;
  1102. }
  1103.  
  1104. /*
  1105. ====================
  1106. bcString::Find
  1107.  
  1108.   Finds the first occasion of szText in this string, starting to look at nStart and stopping at nEnd.
  1109.   Returns -1 on fail.
  1110. ====================
  1111. */
  1112. BC_INLINE int bcString::Find( const char *szText, bool bCaseSensitive, int nStart, int nEnd ) const {
  1113.   assert( szText );
  1114.   ValueRange( nStart, 0, _nLength - 1 );
  1115.   ValueRange( nEnd, 0, _nLength - 1 );
  1116.   int nLength;
  1117.   nLength = strlen( szText );
  1118.   do {
  1119.     if( bCaseSensitive ) {
  1120.       if( !strncmp( _data + nStart, szText, nLength ) ) return nStart;
  1121.     } else {
  1122.       if( Istrncmp( _data + nStart, szText, nLength ) ) return nStart;
  1123.     }
  1124.   } while( nStart++ != nEnd );
  1125.   return -1;
  1126. }
  1127.  
  1128. /*
  1129. ====================
  1130. bcString::Filter
  1131.  
  1132.   Sees if this string conforms to the filter. Use:
  1133.   *     as a wildcard
  1134.   ?     as a single-character wildcard
  1135.   [a-z] as a character range wildcard
  1136. ====================
  1137. */
  1138. BC_INLINE bool bcString::Filter( const char *szFilter, bool bCaseSensitive ) const {
  1139.   assert( szFilter );
  1140.   return Filter( szFilter, _data, bCaseSensitive );
  1141. }
  1142.  
  1143. /*
  1144. ====================
  1145. bcString::Last
  1146.  
  1147.   Finds the last occasion of nCharacter in this string.
  1148.   Returns -1 on fail.
  1149. ====================
  1150. */
  1151. BC_INLINE int bcString::Last( const char nCharacter ) const {
  1152.   int nPosition;
  1153.   nPosition = _nLength - 1;
  1154.   do {
  1155.     if( _data[ nPosition ] == nCharacter ) return nPosition;
  1156.   } while( nPosition-- >= 0 );
  1157.   return -1;
  1158. }
  1159.  
  1160. /*
  1161. ====================
  1162. bcString::Last
  1163.  
  1164.   Finds the last occasion of szText in this string.
  1165.   Returns -1 on fail.
  1166. ====================
  1167. */
  1168. BC_INLINE int bcString::Last( const char *szText, bool bCaseSensitive ) const {
  1169.   assert( szText );
  1170.   int nPosition, nLength;
  1171.   nLength = strlen( szText );
  1172.   nPosition = _nLength - nLength;
  1173.   do {
  1174.     if( !strncmp( _data + nPosition, szText, nLength ) ) return nPosition;
  1175.   } while( nPosition-- >= 0 );
  1176.   return -1;
  1177. }
  1178.  
  1179. /*
  1180. ====================
  1181. bcString::Left
  1182.  
  1183.   Returns the first nLength characters in a new bcString.
  1184. ====================
  1185. */
  1186. BC_INLINE bcString bcString::Left( const int nLength ) const {
  1187.   return bcString( _data, 0, nLength - 1 );
  1188. }
  1189.  
  1190. /*
  1191. ====================
  1192. bcString::Right
  1193.  
  1194.   Returns the last nLength characters in a new bcString.
  1195. ====================
  1196. */
  1197. BC_INLINE bcString bcString::Right( const int nLength ) const {
  1198.   return bcString( _data, _nLength - nLength, _nLength - 1 );
  1199. }
  1200.  
  1201. /*
  1202. ====================
  1203. bcString::Mid
  1204.  
  1205.   Returns the nLength characters starting from nStart in a new bcString.
  1206. ====================
  1207. */
  1208. BC_INLINE bcString bcString::Mid( const int nStart, const int nLength ) const {
  1209.   assert( nStart + nLength <= _nLength );
  1210.   return bcString( _data, nStart, nStart + nLength - 1 );
  1211. }                                                    
  1212.  
  1213. /*
  1214. ====================
  1215. bcString::Remove
  1216.  
  1217.   Removes the portion of this string starting at nStart with a length of nLength.
  1218. ====================
  1219. */
  1220. BC_INLINE bcString &bcString::Remove( int nStart, int nLength ) {
  1221.   ValueRange( nStart, 0, _nLength - 1 );
  1222.   ValueRange( nLength, 0, _nLength - 1 );
  1223.   Remove( _data, nStart, nStart + nLength - 1 );
  1224.   _nLength -= nLength;
  1225.   return *this;
  1226. }
  1227.  
  1228.  
  1229. /*
  1230. ====================
  1231. bcString::Replace
  1232.  
  1233.   Replaces all occasions of szOld with szNew.
  1234. ====================
  1235. */
  1236. BC_INLINE bcString &bcString::Replace( const char *szOld, const char *szNew ) {
  1237.   assert( szOld );
  1238.   assert( szNew );
  1239.  
  1240.   int i, nOldLength, nNewLength;
  1241.   nOldLength = strlen( szOld );
  1242.   nNewLength = strlen( szNew );
  1243.   for( i = 0; i < _nLength - nOldLength; i++ ) {
  1244.     if( !strncmp( _data + i, szOld, nOldLength ) ) {
  1245.       Remove( i, nOldLength );
  1246.       Insert( szNew, i );
  1247.       i += nNewLength - 1;
  1248.     }
  1249.   }
  1250.   return *this;
  1251. }
  1252.  
  1253. // STATIC VERSIONS
  1254. /*
  1255. ====================
  1256. bcString::Clear
  1257.  
  1258.   Clears the string.
  1259. ====================
  1260. */
  1261. BC_INLINE bcString bcString::Clear( const bcString &String ) {
  1262.   bcString Result( String );
  1263.   Result.Clear();
  1264.   return Result;
  1265. }
  1266.  
  1267. /*
  1268. ====================
  1269. bcString::Empty
  1270.  
  1271.   Removes all characters the string.
  1272. ====================
  1273. */
  1274. BC_INLINE bcString bcString::Empty( const bcString &String ) {
  1275.   bcString Result( String );
  1276.   Result.Empty();
  1277.   return Result;
  1278. }
  1279.  
  1280. /*
  1281. ====================
  1282. bcString::Append
  1283.  
  1284.   Appends the variable passed to the string.
  1285. ====================
  1286. */
  1287. BC_INLINE bcString bcString::Append( const bcString &String, const char nCharacter ) {
  1288.   bcString Result( String );
  1289.   Result.Append( nCharacter );
  1290.   return Result;
  1291. }
  1292.  
  1293. /*
  1294. ====================
  1295. bcString::Append
  1296.  
  1297.   Appends the variable passed to the string.
  1298. ====================
  1299. */
  1300. BC_INLINE bcString bcString::Append( const bcString &String, const bcString &sAppendix ) {
  1301.   bcString Result( String );
  1302.   Result.Append( sAppendix );
  1303.   return Result;
  1304. }
  1305.  
  1306. /*
  1307. ====================
  1308. bcString::Append
  1309.  
  1310.   Appends the variable passed to the string.
  1311. ====================
  1312. */
  1313. BC_INLINE bcString bcString::Append( const bcString &String, const char *szText ) {
  1314.   bcString Result( String );
  1315.   Result.Append( szText );
  1316.   return Result;
  1317. }
  1318.  
  1319. /*
  1320. ====================
  1321. bcString::Append
  1322.  
  1323.   Appends the variable passed to the string.
  1324. ====================
  1325. */
  1326. BC_INLINE bcString bcString::Append( const bcString &String, const char *szText, const int nLength ) {
  1327.   bcString Result( String );
  1328.   Result.Append( szText, nLength );
  1329.   return Result;
  1330. }
  1331.  
  1332. /*
  1333. ====================
  1334. bcString::Insert
  1335.  
  1336.   Inserts the variable passed to the string passed at nIndex.
  1337. ====================
  1338. */
  1339. BC_INLINE bcString bcString::Insert( const bcString &String, const char nCharacter, const int nIndex ) {
  1340.   bcString Result( String );
  1341.   Result.Insert( nCharacter, nIndex );
  1342.   return Result;
  1343. }
  1344.  
  1345. /*
  1346. ====================
  1347. bcString::Insert
  1348.  
  1349.   Inserts the variable passed to the string passed at nIndex.
  1350. ====================
  1351. */
  1352. BC_INLINE bcString bcString::Insert( const bcString &String, const bcString &sInsertion, const int nIndex ) {
  1353.   bcString Result( String );
  1354.   Result.Insert( sInsertion, nIndex );
  1355.   return Result;
  1356. }
  1357.  
  1358. /*
  1359. ====================
  1360. bcString::Insert
  1361.  
  1362.   Inserts the variable passed to the string passed at nIndex.
  1363. ====================
  1364. */
  1365. BC_INLINE bcString bcString::Insert( const bcString &String, const char *szText, const int nIndex ) {
  1366.   bcString Result( String );
  1367.   Result.Insert( szText, nIndex );
  1368.   return Result;
  1369. }
  1370.  
  1371. /*
  1372. ====================
  1373. bcString::Insert
  1374.  
  1375.   Inserts the variable passed to the string passed at nIndex.
  1376. ====================
  1377. */
  1378. BC_INLINE bcString bcString::Insert( const bcString &String, const char *szText, const int nLength, const int nIndex ) {
  1379.   bcString Result( String );
  1380.   Result.Insert( szText, nLength, nIndex );
  1381.   return Result;
  1382. }
  1383.  
  1384. /*
  1385. ====================
  1386. bcString::ToLower
  1387.  
  1388.   Converts the string passed to lower case.
  1389. ====================
  1390. */
  1391. BC_INLINE bcString bcString::ToLower( const bcString &String ) {
  1392.   bcString Result( String );
  1393.   Result.ToLower();
  1394.   return Result;
  1395. }
  1396.  
  1397. /*
  1398. ====================
  1399. bcString::ToUpper
  1400.  
  1401.   Converts the string passed to upper case.
  1402. ====================
  1403. */
  1404. BC_INLINE bcString bcString::ToUpper( const bcString &String ) {
  1405.   bcString Result( String );
  1406.   Result.ToUpper();
  1407.   return Result;
  1408. }
  1409.  
  1410. /*
  1411. ====================
  1412. bcString::Cut
  1413.  
  1414.   Cuts the string passed down to the length given.
  1415. ====================
  1416. */
  1417. BC_INLINE bcString bcString::Cut( const bcString &String, const int nLength ) {
  1418.   bcString Result( String );
  1419.   Result.Cut( nLength );
  1420.   return Result;
  1421. }
  1422.  
  1423. /*
  1424. ====================
  1425. bcString::Remove
  1426.  
  1427.   Removes the portion of the string passed starting at nStart with a length of nLength.
  1428. ====================
  1429. */
  1430. BC_INLINE bcString bcString::Remove( const bcString &String, int nStart, int nLength ) {
  1431.   bcString Result( String );
  1432.   Result.Remove( nStart, nLength );
  1433.   return Result;
  1434. }
  1435.  
  1436. /*
  1437. ====================
  1438. bcString::Replace
  1439.  
  1440.   Replaces all occasions of szOld with szNew.
  1441. ====================
  1442. */
  1443. BC_INLINE bcString bcString::Replace( const bcString &String, const char *szOld, const char *szNew ) {
  1444.   bcString Result( String );
  1445.   Result.Replace( szOld, szNew );
  1446.   return Result;
  1447. }
  1448.  
  1449. }
  1450.  
  1451. #endif //BC_STRING_H
  1452.  
  1453. // FUCKIN HEADER END
  1454. /*********************************************************************************/
  1455. // FUCKIN CPP BEGIN
  1456.  
  1457. #include "stdafx.h"
  1458.  
  1459.  
  1460. /*
  1461. ====================
  1462. bcString::Reallocate
  1463.  
  1464.   Allocates new place for the bcString.
  1465. ====================
  1466. */
  1467. void LibBC::bcString::Reallocate( const int nAmount, bool bPreserveContent ) {
  1468.   assert( nAmount >= 0 );
  1469.   int nNewSize;
  1470.   int nMod = nAmount % BC_STRING_SLICE;
  1471.   char *pNewBuffer;
  1472.  
  1473.   if( !nMod ) {
  1474.     nNewSize = nAmount;
  1475.   } else {
  1476.     nNewSize = nAmount + BC_STRING_SLICE - nMod;
  1477.   }
  1478.   pNewBuffer = new char[ nNewSize ];
  1479.  
  1480.   if( bPreserveContent ) {
  1481.     _data[ _nLength ] = '\0';
  1482.     strcpy( pNewBuffer, _data );
  1483.   }
  1484.  
  1485.   if( _data && _data != _base ) {
  1486.     delete[] _data;
  1487.   }
  1488.  
  1489.   _data = pNewBuffer;
  1490.   _nAllocated = nNewSize;
  1491. }
  1492.  
  1493. /*
  1494. ====================
  1495. bcString::Istrcmp
  1496.  
  1497.   Compares the two strings case-insensitively.
  1498. ====================
  1499. */
  1500. bool LibBC::bcString::Istrcmp( const char *szTextA, const char *szTextB ) {
  1501.   char nCharA, nCharB, nDifference, nMinimum;
  1502.  
  1503.   do {
  1504.     nCharA = *szTextA++;
  1505.     nCharB = *szTextB++;
  1506.  
  1507.     nDifference =  nCharA - nCharB;
  1508.     if( bcMath::Absolute8i( nDifference ) == 0x20 ) {
  1509.       nMinimum = bcMath::Minimum8i( nCharA, nCharB );
  1510.       if( nDifference > 0 ) {
  1511.         if( ( nCharB <= 'A' && nCharB >= 'Z' && nCharB <= 0xC0 && nCharB >= 0xDE ) || nCharB == 0xD7 ) {
  1512.           return false;
  1513.         }
  1514.       } else {
  1515.         if( ( nCharA <= 'A' && nCharA >= 'Z' && nCharA <= 0xC0 && nCharA >= 0xDE ) || nCharA == 0xD7 ) {
  1516.           return false;
  1517.         }
  1518.       }
  1519.     } else if( nDifference ) return false;
  1520.   } while( nCharA && nCharB );
  1521.  
  1522.   return true;
  1523. }
  1524.  
  1525. /*
  1526. ====================
  1527. bcString::Istrncmp
  1528.  
  1529.   Compares the two strings case-insensitively until it reaches nLength.
  1530. ====================
  1531. */
  1532. bool LibBC::bcString::Istrncmp( const char *szTextA, const char *szTextB, size_t nLength ) {
  1533.   char nCharA, nCharB, nDifference, nMinimum;
  1534.   dword nPosition;
  1535.  
  1536.   for( nPosition = 0; nPosition < nLength; ++nPosition ) {
  1537.     nCharA = *szTextA++;
  1538.     nCharB = *szTextB++;
  1539.  
  1540.     nDifference =  nCharA - nCharB;
  1541.     if( bcMath::Absolute8i( nDifference ) == 0x20 ) {
  1542.       nMinimum = bcMath::Minimum8i( nCharA, nCharB );
  1543.       if( nDifference > 0 ) {
  1544.         if( ( nCharB <= 'A' && nCharB >= 'Z' && nCharB <= 0xC0 && nCharB >= 0xDE ) || nCharB == 0xD7 ) {
  1545.           return false;
  1546.         }
  1547.       } else {
  1548.         if( ( nCharA <= 'A' && nCharA >= 'Z' && nCharA <= 0xC0 && nCharA >= 0xDE ) || nCharA == 0xD7 ) {
  1549.           return false;
  1550.         }
  1551.       }
  1552.     } else if( nDifference ) return false;
  1553.   };
  1554.  
  1555.   return true;
  1556. }
  1557.  
  1558.  
  1559. /*
  1560. ====================
  1561. bcString::FreeData
  1562.  
  1563.   Frees the data used by the string.
  1564. ====================
  1565. */
  1566. void LibBC::bcString::FreeData( void ) {
  1567.   if( _data && _data != _base ) {
  1568.     delete[] _data;
  1569.     _data = _base;
  1570.   }
  1571. }
  1572.  
  1573. /*
  1574. ====================
  1575. bcString::Filter
  1576.  
  1577.   Sees if the string given conforms to the filter. Use:
  1578.   *     as a wildcard
  1579.   ?     as a single-character wildcard
  1580.   [a-z] as a character range wildcard
  1581. ====================
  1582. */
  1583. bool LibBC::bcString::Filter( const char *szFilter, const char *szText, bool bCaseSensitive ) {
  1584.   bcString sBuffer;
  1585.   bool bFound;
  1586.   int i, nIndex;
  1587.  
  1588.   while( *szFilter ) {
  1589.     if ( *szFilter == '*' ) {
  1590.       szFilter++;
  1591.       sBuffer.Empty();
  1592.       for ( i = 0; *szFilter; i++ ) {
  1593.         if( *szFilter == '*' || *szFilter == '?' || ( *szFilter == '[' && *( szFilter + 1 ) != '[' ) ) {
  1594.           break;
  1595.         }
  1596.         sBuffer += *szFilter;
  1597.         if ( *szFilter == '[' ) {
  1598.           szFilter++;
  1599.         }
  1600.         szFilter++;
  1601.       }
  1602.       if ( sBuffer.Length() ) {
  1603.         nIndex = bcString( szText ).Find( sBuffer.CString(), bCaseSensitive );
  1604.         if ( nIndex == -1 ) {
  1605.           return false;
  1606.         }
  1607.         szText += nIndex + strlen( sBuffer );
  1608.       }
  1609.     } else if ( *szFilter == '?' ) {
  1610.       szFilter++;
  1611.       szText++;
  1612.     } else if ( *szFilter == '[' ) {
  1613.       if ( *( szFilter + 1 ) == '[' ) {
  1614.         if ( *szText != '[' ) {
  1615.           return false;
  1616.         }
  1617.         szFilter += 2;
  1618.         szText++;
  1619.       } else {
  1620.         szFilter++;
  1621.         bFound = false;
  1622.         while( *szFilter && !bFound ) {
  1623.           if ( *szFilter == ']' && *( szFilter + 1 ) != ']' ) {
  1624.             break;
  1625.           }
  1626.           if ( *( szFilter + 1 ) == '-' && *( szFilter + 2 ) && ( *(szFilter + 2 ) != ']' || *( szFilter + 3 ) == ']' ) ) {
  1627.             if ( bCaseSensitive ) {
  1628.               if ( *szText >= *szFilter && *szText <= *( szFilter + 2 ) ) {
  1629.                 bFound = true;
  1630.               }
  1631.             }
  1632.             else {
  1633.               if ( toupper( *szText ) >= toupper( *szFilter ) && toupper( *szText ) <= toupper( *( szFilter + 2 ) ) ) {
  1634.                 bFound = true;
  1635.               }
  1636.             }
  1637.             szFilter += 3;
  1638.           }
  1639.           else {
  1640.             if ( bCaseSensitive ) {
  1641.               if ( *szFilter == *szText ) {
  1642.                 bFound = true;
  1643.               }
  1644.             }
  1645.             else {
  1646.               if ( toupper(*szFilter) == toupper( *szText ) ) {
  1647.                 bFound = true;
  1648.               }
  1649.             }
  1650.             szFilter++;
  1651.           }
  1652.         }
  1653.         if ( !bFound ) {
  1654.           return false;
  1655.         }
  1656.         while( *szFilter ) {
  1657.           if ( *szFilter == ']' && *(szFilter+1) != ']' ) {
  1658.             break;
  1659.           }
  1660.           szFilter++;
  1661.         }
  1662.         szFilter++;
  1663.         szText++;
  1664.       }
  1665.     } else {
  1666.       if ( bCaseSensitive ) {
  1667.         if ( *szFilter != *szText ) {
  1668.           return false;
  1669.         }
  1670.       } else {
  1671.         if ( toupper( *szFilter ) != toupper( *szText ) ) {
  1672.           return false;
  1673.         }
  1674.       }
  1675.       szFilter++;
  1676.       szText++;
  1677.     }
  1678.   }
  1679.   return true;
  1680. }
  1681.  
  1682. void LibBC::bcString::Remove( char *szText, int nStart, int nEnd ) {
  1683.   assert( szText );
  1684.   int i, nLength;
  1685.   nLength = strlen( szText );
  1686.   if( nStart >= nLength ) nStart = nLength - 1;
  1687.   if( nEnd >= nLength ) nEnd = nLength - 1;
  1688.   for( i = nStart; i <= nLength - 1; i++ ) {
  1689.     szText[ i ] = szText[ i + nEnd - nStart + 1 ];
  1690.   }
  1691.   szText[ i ] = '\0';
  1692. }
  1693.  
Advertisement
Add Comment
Please, Sign In to add comment