Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/Deprecated/old_18mar_diff/String/StrAdd.cpp

Go to the documentation of this file.
00001 #ifndef __J2K__JString_Add_CPP__
00002 #define __J2K__JString_Add_CPP__
00003 
00004 #include <j2k/Fred/String/String.hpp>
00005 
00006 // TODO:  Check for effects of LOCK functions !
00007 // JStringAt also !
00008 
00009 /*
00010 Functions defined:
00011 ------------------
00012 CopyBeforeWrite()
00013 
00014 Assign( const char* s )
00015 Add( const char* s1, const char* s2 )
00016 Append( const char* s )
00017 
00018 operator=
00019 operator+
00020 operator+=
00021 */
00022 
00023 ////////////////////////////////////////////////////////////////////////////
00024 /// Used in:  StrMorph, JStringAt, StrExtra                              ///
00025 ////////////////////////////////////////////////////////////////////////////
00026 void JString::CopyBeforeWrite() {
00027   if ( pData == strNull  ||  pData->nbRefs > 1  ||  pData->lock != 0 ) {
00028     JStringData* sd = pData;
00029     pData = new JStringData( *sd );
00030     sd->Dec();
00031   }
00032 
00033 #ifdef __J2K__DEBUG
00034   else {
00035     printf("Data is unique, so no copy was made !\n");
00036   }
00037 #endif
00038 
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////////////
00042 ////////////////////////////////////////////////////////////////////////////
00043 /// Concatenation of JStrings                                            ///
00044 /// "operator+" is done as friend functions for simplicity               ///
00045 ///     There are five variants:                                         ///
00046 ///          JString + JString                                           ///
00047 ///          JString + char                                              ///
00048 ///          JString + const char*                                       ///
00049 ///          char   + JString                                            ///
00050 ///          const char* + JString                                       ///
00051 ////////////////////////////////////////////////////////////////////////////
00052 ////////////////////////////////////////////////////////////////////////////
00053 void JString::Add( const char* s1, const char* s2,
00054                    size_t Len1,    size_t Len2, size_t LenExtra )
00055 {
00056   // -- Modify THIS JString Object.
00057 
00058   // Take care of NULL JString parameters, if any.
00059   if ( s1 == NULL  ||  *s2 == (char)NULL ) { Len1 = 0; }
00060   if ( s2 == NULL  ||  *s2 == (char)NULL ) { Len2 = 0; }
00061 
00062   size_t newLen = Len1 + Len2;
00063 
00064   // Don't delete now, since memcpy will occur
00065   // in the case we delete ourself before copy !
00066   JStringData* sd = pData;
00067 
00068   pData = new JStringData( newLen + LenExtra );
00069 
00070   // Will fill this String with '\0'
00071 
00072   if ( Len1 > 0 ) {  memcpy( pData->data,        s1, Len1 );  }  
00073   if ( Len2 > 0 ) {  memcpy( pData->data + Len1, s2, Len2 );  }
00074 
00075   pData->length = newLen;
00076   pData->data[ newLen ] = '\0';
00077 
00078    /*
00079      This Null ending is needed since the last string
00080      might not be ended by '\0' or in case the copy
00081      doesn't go up to Zero. To be checked!
00082    */
00083 
00084   sd->Dec(); // Now you can suicide, we don't care.
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////////////
00088 ////////////////////////////////////////////////////////////////////////////
00089 /// Append a JString to THIS JString                                     ///
00090 ///     There are three variants:                                        ///
00091 ///          JString + JString                                           ///
00092 ///          JString + char                                              ///
00093 ///          JString + const char*                                       ///
00094 ////////////////////////////////////////////////////////////////////////////
00095 ////////////////////////////////////////////////////////////////////////////
00096 void JString::Append(const char* s, size_t Len ) {
00097 
00098   if ( s == NULL  ||  *s == (char)NULL ) return;   // Nothing to do, so Return.
00099 
00100   size_t newSize = pData->length + Len;
00101 
00102   if ( pData == strNull || pData->nbRefs > 1 || newSize > pData->bufferSize )
00103   {
00104 
00105 ////////////////////////////////////////////////////////////////////////////
00106 /// If the buffer is too small, or if we have a width mismatch,          ///
00107 /// or if THIS points to strNull then we must allocate a new buffer      ///
00108 /// (Worst Case)                                                         ///
00109 ////////////////////////////////////////////////////////////////////////////
00110     Add(pData->data, s, pData->length, Len );  // Add() call Dec() already !
00111 
00112   } else {
00113 
00114 ////////////////////////////////////////////////////////////////////////////
00115 /// If the buffer is big enough, append the new JString to the buffer.   ///
00116 /// (Best Case)                                                          ///
00117 ////////////////////////////////////////////////////////////////////////////
00118     memcpy( (pData->data + pData->length), s, Len);
00119 
00120     assert( (pData->length + Len ) <= (pData->bufferSize) );
00121     pData->length = newSize;
00122     pData->data[ pData->length ] = '\0';
00123   }
00124 }
00125 
00126 const JString& JString::operator=( const JString& src ) {
00127   if ( this != &src  &&  pData != src.pData ) {
00128     JStringData* sd = pData;
00129     pData = src.pData;
00130     src.pData->Inc();
00131 
00132     // Possible case, we assign a JString part of ourself.
00133     sd->Dec();
00134   }
00135   return *this;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////////////
00139 ////////////////////////////////////////////////////////////////////////////
00140 /// Assignment operators:                                                ///
00141 ///  All assign a new value to the JString object:                       ///
00142 ///    (a) first see, if the buffer is big enough                        ///
00143 ///    (b) if enough room, copy on top of old buffer, set size and type  ///
00144 ///    (c) otherwise free old JString data, and create a new one         ///
00145 ///                                                                      ///
00146 ///  All routines return the new JString (but as a 'const JString&')     ///
00147 ///  this way, assigning it again will cause a copy !                    ///
00148 ///  e.g.:  s1 = s2 = "hi there".                                        ///
00149 ///                                                                      ///
00150 ///     There are three variants:                                        ///
00151 ///          JString + JString                                           ///
00152 ///          JString + char                                              ///
00153 ///          JString + const char*                                       ///
00154 ////////////////////////////////////////////////////////////////////////////
00155 ////////////////////////////////////////////////////////////////////////////
00156 const JString& JString::operator=(const char* s) {
00157   if ( s == NULL  ||  *s == (char)NULL ) {     // Case EMPTY
00158     if ( pData != NULL ) pData->Dec();
00159     pData = strNull;             
00160   } else {                               // Case FILLED
00161     JStringData* sd = pData;
00162     pData = new JStringData( s );
00163     sd->Dec();
00164   }
00165   return *this;
00166 }
00167 
00168 const JString& JString::operator=(char ch) {
00169   JStringData* sd = pData;
00170 
00171   if ( ch == '\0' ||  ch == (char)NULL ) {
00172     pData = strNull;
00173   } else {
00174     pData = new JStringData( ch, 1 );
00175   }
00176 
00177   // Possible case, we assign a char of ourself.
00178   sd->Dec();  
00179   return *this;
00180 }
00181 
00182 JString operator+(const JString& S1, const JString& S2) {
00183   JString* s = new JString();         // JStringData = &strNull
00184 
00185   if ( S1.pData == strNull ) {
00186      // S1.pData->Dec();            // Not Needed, NO decrement on Null
00187      s->pData = S2.pData;           // S1 is NULL, assign S2.
00188 
00189      S2.pData->Inc();
00190 
00191      // Inc() & Dec() checks for strNull and don't increase or decrease it
00192 
00193   } else if ( S2.pData == strNull ) {
00194      // S2.pData->Dec();            // Not Needed, NO decrement on Null
00195      s->pData = S1.pData;           // S2 is NULL, assign S1.
00196      S1.pData->Inc();              
00197   } else {                          // Normal Addition, None are NULL
00198 
00199      // Will change this == 's', 
00200      // it works since 's' call it's own function !
00201      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature
00202      S2.pData->data[ S2.pData->length ] = '\0';   // Safety feature
00203 
00204      s->Add( S1.pData->data,   S2.pData->data,
00205              S1.pData->length, S2.pData->length );
00206   }
00207 
00208   assert( s->pData->data[s->pData->length] == '\0');
00209   return *s;
00210 }
00211 
00212 JString operator+(const JString& S1, const char* s2) {
00213   JString* s = new JString();            // JStringData = &strNull
00214 
00215   if ( s2 == NULL || *s2 == (char)NULL ) {     // No addition needed
00216      s->pData = S1.pData;
00217   } else if ( S1.pData == strNull ) {
00218      s->pData = new JStringData( s2 );   // Only s2 is not NULL
00219   } else {                               // Normal Addition, None are NULL
00220      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature
00221 
00222      size_t Len = strlen( s2 );
00223      s->Add( S1.pData->data, s2, S1.pData->length, Len );
00224   }
00225 
00226   assert( s->pData->data[s->pData->length] == '\0');
00227   return *s;
00228 }
00229 
00230 JString operator+(const char* s1, const JString& S2) {
00231   JString* s = new JString();            // JStringData = &strNull
00232 
00233   if ( s1 == NULL  ||  *s1 == (char)NULL ) {   // No addition needed
00234      s->pData = S2.pData;                // s1 is NULL, assign S2
00235   } else if ( S2.pData == strNull ) {
00236      s->pData = new JStringData( s1 );   // Only s1 is not NULL
00237   } else {                               // Normal Addition, None are NULL
00238      size_t Len = strlen( s1 );
00239      s->Add( s1, S2.pData->data, Len, S2.pData->length );
00240   }
00241 
00242   assert( s->pData->data[s->pData->length] == '\0');
00243 
00244   return *s;
00245 }
00246 
00247 JString operator+(const JString& S1, char c) {
00248   JString* s = new JString();             // JStringData = &strNull
00249   char s2[2] = { c, '\0' };
00250 
00251   if ( c == '\0'  || c == (char)NULL ) { // No addition needed
00252      s->pData = S1.pData;
00253   } else if ( S1.pData == strNull ) {
00254      s->pData = new JStringData( c );    // Only s2 is not NULL
00255   } else {                               // Normal Addition, None are NULL
00256      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature   
00257      s->Add( S1.pData->data, s2, S1.pData->length, 1 );
00258   }
00259  
00260   assert( s->pData->data[s->pData->length] == '\0');
00261   return *s;
00262 }
00263 
00264 JString operator+(char c, const JString& S2 ) {
00265   JString* s = new JString();            // JStringData = &strNull
00266   char s1[2] = { c, '\0' };
00267   
00268   if ( c == '\0'  || c == (char)NULL ) { // No addition needed
00269      s->pData = S2.pData;                // s1 is NULL, assign S2  
00270   } else if ( S2.pData == strNull ) {
00271      s->pData = new JStringData( c );    // Only s1 is not NULL
00272   } else {                               // Normal Addition, None are NULL
00273      s->Add( s1, S2.pData->data, 1, S2.pData->length );
00274   }
00275   
00276   assert( s->pData->data[s->pData->length] == '\0');
00277  
00278   return *s;
00279 }
00280 
00281 #endif

Generated on Sun Oct 14 18:46:26 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001