home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 v2.4 Fix / W95-v2.4fix.iso / ACADWIN / ADS / CPP / GENERAL / ADSSTRNG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  6.9 KB  |  226 lines

  1. /* 
  2.     ADSSTRNG.CPP -
  3.     
  4.     This file:
  5.  
  6.         Defines class ADS_STRING.  
  7.  
  8.     (C) Copyright 1988-1994 by Autodesk, Inc.
  9.  
  10.     This program is copyrighted by Autodesk, Inc. and is  licensed
  11.     to you under the following conditions.  You may not distribute
  12.     or  publish the source code of this program in any form.   You
  13.     may  incorporate this code in object form in derivative  works
  14.     provided  such  derivative  works  are  (i.) are  designed and
  15.     intended  to  work  solely  with  Autodesk, Inc. products, and
  16.     (ii.)  contain  Autodesk's  copyright  notice  "(C)  Copyright
  17.     1988-1994 by Autodesk, Inc."
  18.  
  19.     AUTODESK  PROVIDES THIS PROGRAM "AS IS" AND WITH  ALL  FAULTS.
  20.     AUTODESK  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF  MER-
  21.     CHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK,  INC.
  22.     DOES  NOT  WARRANT THAT THE OPERATION OF THE PROGRAM  WILL  BE
  23.     UNINTERRUPTED OR ERROR FREE.
  24.  
  25. */
  26. #include "adsinc.h"
  27.  
  28. /******************************************************************************
  29. *                                                                             *
  30. *                            ADS_STRING class                                 *
  31. *                                                                             *
  32. ******************************************************************************/
  33. //-----------------------------------------------------------------------------
  34. size_t    ADS_STRING::initial_capac     = 63;
  35. size_t    ADS_STRING::resize_inc        = 64;
  36. size_t    ADS_STRING::max_waste         = 63;
  37.  
  38. //-----------------------------------------------------------------------------
  39. ADS_STRING& ADS_STRING::Assign( const ADS_STRING  &src
  40.                                 , size_t origin
  41.                                 , size_t how_long )
  42. {
  43.     if( origin != 0 || how_long < src.Length() )
  44.     {
  45.         size_t loc = min( origin,src.Length() );
  46.         size_t len = min( src.Length() - loc, how_long );
  47.         STRING_REF *temp = new STRING_REF( src.CString() + loc, len, 0, 0, 0);
  48.         if( p->RemoveReference() == 0 )
  49.         {
  50.             delete p;
  51.         }
  52.         p = temp;
  53.     }
  54.     else
  55.     {
  56.         src.p->AddReference();
  57.         if( p->RemoveReference() == 0 )
  58.         {
  59.             delete p;
  60.         }
  61.         p = src.p;
  62.     }
  63.     return *this;
  64. }
  65.  
  66. //-----------------------------------------------------------------------------
  67. ADS_STRING& ADS_STRING::Append( const ADS_STRING &src
  68.                                 , size_t orig
  69.                                 , size_t n )
  70. {
  71.     CopyOnWrite();
  72.     size_t loc = min( orig, src.Length() );
  73.     size_t len = min( src.Length() - loc, n );
  74.     p->Splice( p->nchars, 0, src.CString(), len );
  75.     return *this;
  76. }
  77.  
  78. /******************************************************************************
  79. *                                                                             *
  80. *                            STRING_REF                                       *
  81. *                                                                             *
  82. ******************************************************************************/
  83. //-----------------------------------------------------------------------------
  84. void STRING_REF::GrowTo( size_t n )
  85. {
  86.     capacity = n;
  87.     array = ( char * )realloc( array, capacity +1 );
  88.     ASSERT( array != 0 );
  89. }
  90.  
  91. //-----------------------------------------------------------------------------
  92. STRING_REF::STRING_REF( const char *str1, size_t count1
  93.                         , const char *str2, size_t count2
  94.                         , size_t extra ) : ADS_REFERENCE( 1 )
  95. {
  96.     nchars = count1 + count2;
  97.     capacity = RoundCapacity( nchars + extra );
  98.     array = new char[ capacity + 1 ];
  99.     ASSERT( array != NULL );
  100.     memcpy( array, str1, count1 );
  101.     memcpy( array + count1, str2, count2 );
  102.     array[ count1 + count2 ] = '\0';
  103. }
  104.  
  105. //-----------------------------------------------------------------------------
  106. void STRING_REF::Splice( size_t start
  107.                         , size_t extent
  108.                         , const char *cp
  109.                         , size_t num_char )
  110. {
  111.     char  *destarray;         // Will point to final destination array
  112.  
  113.     // Final length:
  114.     size_t tot = nchars + num_char - extent;
  115.     // Final capacity:
  116.     size_t newCapac = RoundCapacity( tot );
  117.  
  118.     // Resize if necessary:
  119.     if( newCapac > capacity )
  120.     {
  121.         GrowTo( newCapac );     // Grew
  122.         destarray = array;      // Record what will be the final
  123.                                 // destination array
  124.     }
  125.     else if( capacity - newCapac > ADS_STRING::GetMaxWaste() )
  126.     {
  127.         // Shrunk.  destarray will point to brand new memory
  128.         destarray = new char[ newCapac + 1 ];
  129.         if( array == 0 )
  130.         {
  131.             ASSERT( "Outta of it" != NULL );
  132.         }
  133.         if( start )
  134.         {
  135.             memcpy( destarray, array, start ); // Copy beginning of string.
  136.         }
  137.         capacity = newCapac;
  138.     }
  139.     else
  140.     {
  141.         destarray = array;  // string capacity stayed the same.  Reuse old array.
  142.     }
  143.  
  144.     //
  145.     // Copy the end of the string. This will be necessary if new memory is
  146.     // involved, or if the size of the replacing substring does not match
  147.     // the original extent.
  148.     //
  149.     if( destarray != array || num_char != extent )
  150.     {
  151.         memmove( destarray + start + num_char
  152.                 , array + start + extent
  153.                 , nchars - start - extent );
  154.     }
  155.  
  156.     // Copy middle of string:
  157.     if( num_char )
  158.     {
  159.         if( cp )
  160.         {
  161.             memmove( destarray + start, cp, num_char );  /* NB: memmove() necessary */
  162.         }
  163.         else
  164.         {
  165.             memset( destarray + start, ' ', num_char );
  166.         }
  167.     }
  168.  
  169.     nchars = tot;
  170.     destarray[nchars] = '\0';
  171.  
  172.     if( destarray != array )
  173.     {
  174.         free(array);
  175.         array = destarray;
  176.     }
  177. }
  178.  
  179. //-----------------------------------------------------------------------------
  180. size_t  STRING_REF::RoundCapacity( size_t nc )
  181. {
  182.     size_t init_cap = ADS_STRING::GetInitialCapacity();
  183.     size_t resize_size = ADS_STRING::GetResizeIncrement();
  184.     return ( ( nc - init_cap + resize_size - 1 ) / resize_size ) * resize_size
  185.             + init_cap ;
  186. }
  187.  
  188. #ifdef TEST_ADSSTRNG
  189.  
  190. #include <iostream.h>
  191.  
  192. void Test( ADS_STRING& src, ADS_STRING* dst )
  193. {
  194.     *dst = src;
  195. }
  196.  
  197. #ifdef main
  198. #undef main
  199. #endif
  200.  
  201. void main()
  202. {
  203.     ADS_STRING mystring( "Hello, my dear" );
  204.     ADS_STRING *foo = new ADS_STRING;
  205.     *foo = mystring;
  206.     cout << mystring << endl;
  207.     cout << *foo << endl;
  208.     mystring += mystring + *foo;
  209.     delete foo;
  210.     cout << mystring << endl;
  211.  
  212.     ADS_STRING bar("Hello, ");
  213.     bar += "my dear";
  214.     cout << bar << endl;
  215.     if ( bar == mystring )
  216.     {
  217.         cout << "Passed!" << endl;
  218.     }
  219.     else
  220.     {
  221.         cout << "Failed!" << endl;
  222.     }
  223. }
  224.  
  225. #endif
  226.