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/Str14dec/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                    ULONG Len1,     ULONG Len2,     ULONG 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   ULONG newLen = Len1 + Len2;
00063 
00064   
00065   // Don't delete now, since memcpy will occur
00066   // in the case we delete ourself before copy !
00067   JStringData* sd = pData;
00068 
00069   if ( newLen > 0 ) {
00070   pData = new JStringData( newLen + LenExtra );
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   } else { // strNull
00085     pData = strNull;
00086   }  
00087 
00088   sd->Dec(); // Now you can suicide, we don't care.
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////////////
00092 ////////////////////////////////////////////////////////////////////////////
00093 /// Append a JString to THIS JString                                     ///
00094 ///     There are three variants:                                        ///
00095 ///          JString + JString                                           ///
00096 ///          JString + char                                              ///
00097 ///          JString + const char*                                       ///
00098 ////////////////////////////////////////////////////////////////////////////
00099 ////////////////////////////////////////////////////////////////////////////
00100 void JString::Append(const char* s, ULONG Len ) {
00101 
00102   if ( s == NULL  ||  *s == (char)NULL ) return;   // Nothing to do, so Return.
00103 
00104   ULONG newSize = pData->length + Len;
00105 
00106   if ( pData == strNull || pData->nbRefs > 1 || newSize > pData->bufferSize )
00107   {
00108 
00109 ////////////////////////////////////////////////////////////////////////////
00110 /// If the buffer is too small, or if we have a width mismatch,          ///
00111 /// or if THIS points to strNull then we must allocate a new buffer      ///
00112 /// (Worst Case)                                                         ///
00113 ////////////////////////////////////////////////////////////////////////////
00114     Add(pData->data, s, pData->length, Len );  // Add() call Dec() already !
00115 
00116   } else {
00117 
00118 ////////////////////////////////////////////////////////////////////////////
00119 /// If the buffer is big enough, append the new JString to the buffer.   ///
00120 /// (Best Case)                                                          ///
00121 ////////////////////////////////////////////////////////////////////////////
00122     memcpy( (pData->data + pData->length), s, Len);
00123 
00124     assert( (pData->length + Len ) <= (pData->bufferSize) );
00125     pData->length = newSize;
00126     pData->data[ pData->length ] = '\0';
00127   }
00128 }
00129 
00130 const JString& JString::operator=( const JString& src ) {
00131   if ( this != &src  &&  pData != src.pData ) {
00132     JStringData* sd = pData;
00133     pData = src.pData;
00134     src.pData->Inc();
00135 
00136     // Possible case, we assign a JString part of ourself.
00137     sd->Dec();
00138   }
00139   return *this;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////////////
00143 ////////////////////////////////////////////////////////////////////////////
00144 /// Assignment operators:                                                ///
00145 ///  All assign a new value to the JString object:                       ///
00146 ///    (a) first see, if the buffer is big enough                        ///
00147 ///    (b) if enough room, copy on top of old buffer, set size and type  ///
00148 ///    (c) otherwise free old JString data, and create a new one         ///
00149 ///                                                                      ///
00150 ///  All routines return the new JString (but as a 'const JString&')     ///
00151 ///  this way, assigning it again will cause a copy !                    ///
00152 ///  e.g.:  s1 = s2 = "hi there".                                        ///
00153 ///                                                                      ///
00154 ///     There are three variants:                                        ///
00155 ///          JString + JString                                           ///
00156 ///          JString + char                                              ///
00157 ///          JString + const char*                                       ///
00158 ////////////////////////////////////////////////////////////////////////////
00159 ////////////////////////////////////////////////////////////////////////////
00160 const JString& JString::operator=(const char* s) {
00161   if ( s == NULL  ||  *s == (char)NULL ) {     // Case EMPTY
00162     if ( pData != NULL ) pData->Dec();
00163     pData = strNull;             
00164   } else {                               // Case FILLED
00165     JStringData* sd = pData;
00166     pData = new JStringData( s );
00167     sd->Dec();
00168   }
00169   return *this;
00170 }
00171 
00172 const JString& JString::operator=(char ch) {
00173   JStringData* sd = pData;
00174 
00175   if ( ch == '\0' ||  ch == (char)NULL ) {
00176     pData = strNull;
00177   } else {
00178     pData = new JStringData( ch, 1 );
00179   }
00180 
00181   // Possible case, we assign a char of ourself.
00182   sd->Dec();  
00183   return *this;
00184 }
00185 
00186 JString operator+(const JString& S1, const JString& S2) {
00187   JString* s = new JString();         // JStringData = &strNull
00188 
00189   if ( S1.pData == strNull ) {
00190      // S1.pData->Dec();            // Not Needed, NO decrement on Null
00191      s->pData = S2.pData;           // S1 is NULL, assign S2.
00192 
00193      S2.pData->Inc();
00194 
00195      // Inc() & Dec() checks for strNull and don't increase or decrease it
00196 
00197   } else if ( S2.pData == strNull ) {
00198      // S2.pData->Dec();            // Not Needed, NO decrement on Null
00199      s->pData = S1.pData;           // S2 is NULL, assign S1.
00200      S1.pData->Inc();              
00201   } else {                          // Normal Addition, None are NULL
00202 
00203      // Will change this == 's', 
00204      // it works since 's' call it's own function !
00205      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature
00206      S2.pData->data[ S2.pData->length ] = '\0';   // Safety feature
00207 
00208      s->Add( S1.pData->data,   S2.pData->data,
00209              S1.pData->length, S2.pData->length );
00210   }
00211 
00212   assert( s->pData->data[s->pData->length] == '\0');
00213   return *s;
00214 }
00215 
00216 JString operator+(const JString& S1, const char* s2) {
00217   JString* s = new JString();            // JStringData = &strNull
00218 
00219   if ( s2 == NULL || *s2 == (char)NULL ) {     // No addition needed
00220      s->pData = S1.pData;
00221   } else if ( S1.pData == strNull ) {
00222      s->pData = new JStringData( s2 );   // Only s2 is not NULL
00223   } else {                               // Normal Addition, None are NULL
00224      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature
00225 
00226      ULONG Len = strlen( s2 );
00227      s->Add( S1.pData->data, s2, S1.pData->length, Len );
00228   }
00229 
00230   assert( s->pData->data[s->pData->length] == '\0');
00231   return *s;
00232 }
00233 
00234 JString operator+(const char* s1, const JString& S2) {
00235   JString* s = new JString();            // JStringData = &strNull
00236 
00237   if ( s1 == NULL  ||  *s1 == (char)NULL ) {   // No addition needed
00238      s->pData = S2.pData;                // s1 is NULL, assign S2
00239   } else if ( S2.pData == strNull ) {
00240      s->pData = new JStringData( s1 );   // Only s1 is not NULL
00241   } else {                               // Normal Addition, None are NULL
00242      ULONG Len = strlen( s1 );
00243      s->Add( s1, S2.pData->data, Len, S2.pData->length );
00244   }
00245 
00246   assert( s->pData->data[s->pData->length] == '\0');
00247 
00248   return *s;
00249 }
00250 
00251 JString operator+(const JString& S1, char c) {
00252   JString* s = new JString();             // JStringData = &strNull
00253   char s2[2] = { c, '\0' };
00254 
00255   if ( c == '\0'  || c == (char)NULL ) { // No addition needed
00256      s->pData = S1.pData;
00257   } else if ( S1.pData == strNull ) {
00258      s->pData = new JStringData( c );    // Only s2 is not NULL
00259   } else {                               // Normal Addition, None are NULL
00260      S1.pData->data[ S1.pData->length ] = '\0';   // Safety feature   
00261      s->Add( S1.pData->data, s2, S1.pData->length, 1 );
00262   }
00263  
00264   assert( s->pData->data[s->pData->length] == '\0');
00265   return *s;
00266 }
00267 
00268 JString operator+(char c, const JString& S2 ) {
00269   JString* s = new JString();            // JStringData = &strNull
00270   char s1[2] = { c, '\0' };
00271   
00272   if ( c == '\0'  || c == (char)NULL ) { // No addition needed
00273      s->pData = S2.pData;                // s1 is NULL, assign S2  
00274   } else if ( S2.pData == strNull ) {
00275      s->pData = new JStringData( c );    // Only s1 is not NULL
00276   } else {                               // Normal Addition, None are NULL
00277      s->Add( s1, S2.pData->data, 1, S2.pData->length );
00278   }
00279   
00280   assert( s->pData->data[s->pData->length] == '\0');
00281  
00282   return *s;
00283 }
00284 
00285 #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