(file) Return to String.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/String.cpp between version 1.111.6.3 and 1.140

version 1.111.6.3, 2005/10/08 02:16:01 version 1.140, 2014/06/14 16:14:04
Line 1 
Line 1 
 //%2005////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  //
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  // Permission is hereby granted, free of charge, to any person obtaining a
   // copy of this software and associated documentation files (the "Software"),
   // to deal in the Software without restriction, including without limitation
   // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   // and/or sell copies of the Software, and to permit persons to whom the
   // Software is furnished to do so, subject to the following conditions:
   //
   // The above copyright notice and this permission notice shall be included
   // in all copies or substantial portions of the Software.
   //
   // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy  //////////////////////////////////////////////////////////////////////////
 // of this software and associated documentation files (the "Software"), to  
 // deal in the Software without restriction, including without limitation the  
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  
 // sell copies of the Software, and to permit persons to whom the Software is  
 // furnished to do so, subject to the following conditions:  
 //  
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 //  
 //==============================================================================  
 //  
 // Author: Mike Brasher (mbrasher@bmc.com)  
 //  
 // Modified By:  
 //     Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //     Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#3297  
 //     David Dillard, VERITAS Software Corp. (david.dillard@veritas.com)  
 //     Mike Brasher (mike-brasher@austin.rr.com)  
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include <cassert>  #include <Pegasus/Common/PegasusAssert.h>
   #include <cstring>
 #include "InternalException.h" #include "InternalException.h"
 #include "CommonUTF.h"  
 #include "MessageLoader.h" #include "MessageLoader.h"
 #include "StringRep.h" #include "StringRep.h"
   #include <Pegasus/Common/Pegasus_inl.h>
   #include <cstdarg>
  
 #ifdef PEGASUS_HAS_ICU #ifdef PEGASUS_HAS_ICU
   # include <unicode/ures.h>
 #include <unicode/ustring.h> #include <unicode/ustring.h>
 #include <unicode/uchar.h> #include <unicode/uchar.h>
 #endif #endif
Line 54 
Line 49 
 // //
 // Compile-time macros (undefined by default). // Compile-time macros (undefined by default).
 // //
 //     PEGASUS_STRING_NO_THROW -- suppresses throwing of exceptions  
 //  
 //     PEGASUS_STRING_NO_UTF8 -- don't generate slower UTF8 code. //     PEGASUS_STRING_NO_UTF8 -- don't generate slower UTF8 code.
 // //
 //     PEGASUS_USE_INTERNAL_INLINES -- enables internal inlining feature.  
 //  
 //============================================================================== //==============================================================================
  
 //============================================================================== //==============================================================================
Line 68 
Line 59 
 // //
 //============================================================================== //==============================================================================
  
 const Uint8 _to_upper_tbl[256] =  // Note: this table is much faster than the system toupper(). Please do not
   // change.
   
   const Uint8 _toUpperTable[256] =
 { {
     0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,     0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
     0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,     0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
Line 104 
Line 98 
     0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,     0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
 }; };
  
 const Uint8 _to_lower_tbl[256] =  // Note: this table is much faster than the system tolower(). Please do not
   // change.
   
   const Uint8 _toLowerTable[256] =
 { {
     0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,     0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
     0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,     0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
Line 140 
Line 137 
     0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,     0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
 }; };
  
 // Converts 16-bit characters to upper case.  // Converts 16-bit characters to upper case. This routine is faster than the
 inline Uint16 _to_upper(Uint16 x)  // system toupper(). Please do not change.
   inline Uint16 _toUpper(Uint16 x)
 { {
     return (x & 0xFF00) ? x : _to_upper_tbl[x];      return (x & 0xFF00) ? x : _toUpperTable[x];
 } }
  
 // Converts 16-bit characters to lower case.  // Converts 16-bit characters to lower case. This routine is faster than the
 inline Uint16 _to_lower(Uint16 x)  // system toupper(). Please do not change.
   inline Uint16 _toLower(Uint16 x)
 { {
     return (x & 0xFF00) ? x : _to_lower_tbl[x];      return (x & 0xFF00) ? x : _toLowerTable[x];
 } }
  
 // Rounds x to the next power of two (or just returns 8 if x < 8).  // Rounds x up to the nearest power of two (or just returns 8 if x < 8).
 static Uint32 _next_pow_2(Uint32 x)  static Uint32 _roundUpToPow2(Uint32 x)
 { {
       // Check for potential overflow in x
       PEGASUS_CHECK_CAPACITY_OVERFLOW(x);
   
     if (x < 8)     if (x < 8)
         return 8;         return 8;
  
Line 169 
Line 171 
     return x;     return x;
 } }
  
 template<class P, class Q>  
 static void _copy(P* p, const Q* q, size_t n)  
 {  
     // Use loop unrolling.  
   
     while (n >= 8)  
     {  
         p[0] = q[0];  
         p[1] = q[1];  
         p[2] = q[2];  
         p[3] = q[3];  
         p[4] = q[4];  
         p[5] = q[5];  
         p[6] = q[6];  
         p[7] = q[7];  
         p += 8;  
         q += 8;  
         n -= 8;  
     }  
   
     while (n >= 4)  
     {  
         p[0] = q[0];  
         p[1] = q[1];  
         p[2] = q[2];  
         p[3] = q[3];  
         p += 4;  
         q += 4;  
         n -= 4;  
     }  
   
     while (n--)  
         *p++ = *q++;  
 }  
   
 static Uint16* _find(const Uint16* s, size_t n, Uint16 c) static Uint16* _find(const Uint16* s, size_t n, Uint16 c)
 { {
       // The following employs loop unrolling for efficiency. Please do not
       // eliminate.
   
     while (n >= 4)     while (n >= 4)
     {     {
         if (s[0] == c)         if (s[0] == c)
Line 262 
Line 232 
     return 0;     return 0;
 } }
  
 static int _compare_no_utf8(const Uint16* s1, const char* s2)  #ifdef PEGASUS_STRING_NO_UTF8
   static int _compareNoUTF8(const Uint16* s1, const char* s2)
 { {
     Uint16 c1;     Uint16 c1;
     Uint16 c2;     Uint16 c2;
Line 279 
Line 250 
  
     return c1 - c2;     return c1 - c2;
 } }
   #endif
 static int _compare(const Uint16* s1, const Uint16* s2, size_t n)  
 {  
     // This should only be called when s1 and s2 have the same length.  
   
     while (n-- && (*s1++ - *s2++) == 0)  
         ;  
   
     //  
   
     return s1[-1] - s2[-1];  
 }  
  
 static inline void _copy(Uint16* s1, const Uint16* s2, size_t n) static inline void _copy(Uint16* s1, const Uint16* s2, size_t n)
 { {
     memcpy(s1, s2, n * sizeof(Uint16));     memcpy(s1, s2, n * sizeof(Uint16));
 } }
  
 void String_throw_out_of_bounds()  void StringThrowOutOfBounds()
 { {
     throw IndexOutOfBoundsException();     throw IndexOutOfBoundsException();
 } }
  
 #ifdef PEGASUS_STRING_NO_THROW  inline void _checkNullPointer(const void* ptr)
 # define _check_null_pointer(ARG) /* empty */  
 #else  
 template<class T>  
 inline void _check_null_pointer(const T* ptr)  
 { {
     if (!ptr)     if (!ptr)
         throw NullPointer();         throw NullPointer();
 } }
 #endif  
   
 static size_t _copy_from_utf8(Uint16* dest, const char* src, size_t n)  
 {  
     Uint16* p = dest;  
     const Uint8* q = (const Uint8*)src;  
  
     // Process leading 7-bit ASCII characters (to avoid UTF8 overhead later).  #define BADUTF8_MAX_CLEAR_CHAR 40
     // Use loop-unrolling.  #define BADUTF8_MAX_CHAR_TO_HEX 10
  
     while (n >=8 && ((q[0]|q[1]|q[2]|q[3]|q[4]|q[5]|q[6]|q[7]) & 0x80) == 0)  static void _formatBadUTF8Chars(
       char* buffer,
       Uint32 index,
       const char* q,
       size_t n )
     {     {
         p[0] = q[0];  
         p[1] = q[1];  
         p[2] = q[2];  
         p[3] = q[3];  
         p[4] = q[4];  
         p[5] = q[5];  
         p[6] = q[6];  
         p[7] = q[7];  
         p += 8;  
         q += 8;  
         n -= 8;  
     }  
  
     while (n >=4 && ((q[0]|q[1]|q[2]|q[3]) & 0x80) == 0)      char tmp[20];
     {      const char* start;
         p[0] = q[0];  
         p[1] = q[1];  
         p[2] = q[2];  
         p[3] = q[3];  
         p += 4;  
         q += 4;  
         n -= 4;  
     }  
  
     switch (n)      size_t clearChar =
           (( index < BADUTF8_MAX_CLEAR_CHAR ) ? index : BADUTF8_MAX_CLEAR_CHAR );
       size_t charToHex =
           ((n-index-1) < BADUTF8_MAX_CHAR_TO_HEX ?
               (n-index-1) : BADUTF8_MAX_CHAR_TO_HEX );
   
       if (index < BADUTF8_MAX_CLEAR_CHAR)
     {     {
         case 0:          start = q;
             return p - dest;      } else
         case 1:  
             if (q[0] < 128)  
             {             {
                 p[0] = q[0];          start = &(q[ index - BADUTF8_MAX_CLEAR_CHAR]);
                 return p + 1 - dest;  
             }             }
             break;  
         case 2:      // Intialize the buffer with the first character as '\0' to be able to use
             if (((q[0]|q[1]) & 0x80) == 0)      // strnchat() and strcat()
       buffer[0] = 0;
       // Start the buffer with the valid UTF8 chars
       strncat(buffer,start,clearChar);
       for (size_t i = clearChar, j = 0; j <= charToHex; i++,j++ )
             {             {
                 p[0] = q[0];          tmp[0] = 0;
                 p[1] = q[1];          sprintf(&(tmp[0])," 0x%02X",(Uint8)start[i]);
                 return p + 2 - dest;          strncat(buffer,&(tmp[0]),5);
             }  
             break;  
         case 3:  
             if (((q[0]|q[1]|q[2]) & 0x80) == 0)  
             {  
                 p[0] = q[0];  
                 p[1] = q[1];  
                 p[2] = q[2];  
                 return p + 3 - dest;  
             }  
             break;  
     }     }
  
     // Process remaining characters.  }
  
     while (n)  static void _StringThrowBadUTF8(Uint32 index, const char* q, size_t n)
     {     {
         // Optimize for 7-bit ASCII case.      char buffer[1024];
  
         if (*q < 128)      _formatBadUTF8Chars(&(buffer[0]),index,q,n);
         {  
             *p++ = *q++;  
             n--;  
         }  
         else  
         {  
             Uint8 c = UTF_8_COUNT_TRAIL_BYTES(*q) + 1;  
  
             if (c > n || !isValid_U8(q, c) ||      MessageLoaderParms parms(
                 UTF8toUTF16(&q, q + c, &p, p + n) != 0)          "Common.String.BAD_UTF8_LONG",
             {  
                 MessageLoaderParms parms("Common.String.BAD_UTF8",  
                     "The byte sequence starting at index $0 "                     "The byte sequence starting at index $0 "
                     "is not valid UTF-8 encoding.",          "is not valid UTF-8 encoding: $1",
                      q - (const Uint8*)src);          index,buffer);
                 throw Exception(parms);  
             }  
  
             n -= c;      throw Exception(parms);
         }  
     }  
   
     return p - dest;  
 } }
  
 // Note: dest must be at least three times src (plus an extra byte for // Note: dest must be at least three times src (plus an extra byte for
 // terminator). // terminator).
 static inline size_t _copy_to_utf8(char* dest, const Uint16* src, size_t n)  static inline size_t _copyToUTF8(char* dest, const Uint16* src, size_t n)
 { {
       // The following employs loop unrolling for efficiency. Please do not
       // eliminate.
   
     const Uint16* q = src;     const Uint16* q = src;
     Uint8* p = (Uint8*)dest;     Uint8* p = (Uint8*)dest;
  
Line 464 
Line 382 
     return p - (Uint8*)dest;     return p - (Uint8*)dest;
 } }
  
 static inline size_t _convert(Uint16* p, const char* q, size_t n)  //  Function to return a formatted char*  from a va_list.
   //  Allocates space for the returned char* and repeats the
   //  build process until the allocated space is large enough
   //  to hold the result.  This is internal only and the core function
   //  used by stringPrintf and stringVPrintf
   
   static char* _charVPrintf(const char* format, va_list ap)
   {
       // Iniitial allocation size.  This is a guess assuming that
       // most printfs are one or two lines long
       int allocSize = 256;
   
       int rtnSize;
       char *p;
   
       // initial allocate for output
       if ((p = (char*)malloc(allocSize)) == NULL)
 { {
 #ifdef PEGASUS_STRING_NO_UTF8          return 0;
     _copy(p, q, n);      }
     return n;  
 #else      // repeat formatting  with increased realloc until it works.
     return _copy_from_utf8(p, q, n);      do
 #endif      {
           rtnSize = vsnprintf(p, allocSize, format, ap);
   
           // return if successful if not negative and
           // returns less than allocated size.
           if (rtnSize > -1 && rtnSize < allocSize)
           {
               return p;
           }
   
           // increment alloc size. Assumes that positive return is
           // expected size and negative is error.
           allocSize = (rtnSize > -1)? (rtnSize + 1) : allocSize * 2;
   
       } while((p = (char*)peg_inln_realloc(p, allocSize)) != NULL);
   
       // return error code if realloc failed
       return 0;
 } }
  
 //============================================================================== //==============================================================================
Line 517 
Line 468 
 // //
 //============================================================================== //==============================================================================
  
 StringRep StringRep::_empty_rep;  StringRep StringRep::_emptyRep;
  
 inline StringRep* StringRep::alloc(size_t cap) inline StringRep* StringRep::alloc(size_t cap)
 { {
       // Check for potential overflow in cap
       PEGASUS_CHECK_CAPACITY_OVERFLOW(cap);
   
     StringRep* rep = (StringRep*)::operator new(     StringRep* rep = (StringRep*)::operator new(
         sizeof(StringRep) + cap * sizeof(Uint16));         sizeof(StringRep) + cap * sizeof(Uint16));
     rep->cap = cap;     rep->cap = cap;
     Atomic_create(&rep->refs, 1);      new(&rep->refs) AtomicInt(1);
  
     return rep;     return rep;
 } }
  
 static inline void _reserve(StringRep*& rep, Uint32 cap) static inline void _reserve(StringRep*& rep, Uint32 cap)
 { {
     if (cap > rep->cap || Atomic_get(&rep->refs) != 1)      if (cap > rep->cap || rep->refs.get() != 1)
     {     {
         size_t n = _next_pow_2(cap);          size_t n = _roundUpToPow2(cap);
         StringRep* new_rep = StringRep::alloc(n);          StringRep* newRep = StringRep::alloc(n);
         new_rep->size = rep->size;          newRep->size = rep->size;
         _copy(new_rep->data, rep->data, rep->size + 1);          _copy(newRep->data, rep->data, rep->size + 1);
         StringRep::unref(rep);         StringRep::unref(rep);
         rep = new_rep;          rep = newRep;
     }     }
 } }
  
Line 551 
Line 505 
     return rep;     return rep;
 } }
  
 StringRep* StringRep::copy_on_write(StringRep* rep)  StringRep* StringRep::copyOnWrite(StringRep* rep)
 { {
     // Return a new copy of rep. Release rep.     // Return a new copy of rep. Release rep.
  
     StringRep* new_rep = StringRep::alloc(rep->size);      StringRep* newRep = StringRep::alloc(rep->size);
     new_rep->size = rep->size;      newRep->size = rep->size;
     _copy(new_rep->data, rep->data, rep->size);      _copy(newRep->data, rep->data, rep->size);
     new_rep->data[new_rep->size] = '\0';      newRep->data[newRep->size] = '\0';
     StringRep::unref(rep);     StringRep::unref(rep);
     return new_rep;      return newRep;
 } }
  
 StringRep* StringRep::create(const char* data, size_t size) StringRep* StringRep::create(const char* data, size_t size)
 { {
     StringRep* rep = StringRep::alloc(size);     StringRep* rep = StringRep::alloc(size);
     rep->size = _convert((Uint16*)rep->data, data, size);      size_t utf8_error_index;
     rep->data[rep->size] = '\0';      rep->size = _convert((Uint16*)rep->data, data, size, utf8_error_index);
  
     return rep;      if (rep->size == size_t(-1))
       {
           StringRep::free(rep);
           _StringThrowBadUTF8((Uint32)utf8_error_index, data,size);
 } }
  
 StringRep* StringRep::createASCII7(const char* data, size_t size)      rep->data[rep->size] = '\0';
 {  
     StringRep* rep = StringRep::alloc(size);  
     _copy((Uint16*)rep->data, data, size);  
     rep->data[rep->size = size] = '\0';  
     return rep;     return rep;
 } }
  
Line 589 
Line 543 
     while (*end++)     while (*end++)
         ;         ;
  
     return end - str - 1;      return (Uint32)(end - str - 1);
 } }
  
 //============================================================================== //==============================================================================
Line 602 
Line 556 
  
 String::String(const String& str, Uint32 n) String::String(const String& str, Uint32 n)
 { {
     _check_bounds(n, str._rep->size);      _checkBounds(n, str._rep->size);
     _rep = StringRep::create(str._rep->data, n);     _rep = StringRep::create(str._rep->data, n);
 } }
  
 String::String(const Char16* str) String::String(const Char16* str)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
     _rep = StringRep::create((Uint16*)str, StringRep::length((Uint16*)str));     _rep = StringRep::create((Uint16*)str, StringRep::length((Uint16*)str));
 } }
  
 String::String(const Char16* str, Uint32 n) String::String(const Char16* str, Uint32 n)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
     _rep = StringRep::create((Uint16*)str, n);     _rep = StringRep::create((Uint16*)str, n);
 } }
  
 String::String(const char* str) String::String(const char* str)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
     _rep = StringRep::create(str, strlen(str));  
 }  
  
 String::String(const char* str, String::ASCII7Tag tag)      // Set this just in case create() throws an exception.
 {      _rep = &StringRep::_emptyRep;
     _check_null_pointer(str);      _rep = StringRep::create(str, strlen(str));
     _rep = StringRep::createASCII7(str, strlen(str));  
 } }
  
 String::String(const char* str, Uint32 n) String::String(const char* str, Uint32 n)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
     _rep = StringRep::create(str, n);  
 }  
  
 String::String(const char* str, size_t n, String::ASCII7Tag tag)      // Set this just in case create() throws an exception.
 {      _rep = &StringRep::_emptyRep;
     _check_null_pointer(str);      _rep = StringRep::create(str, n);
     _rep = StringRep::createASCII7(str, n);  
 } }
  
 String::String(const String& s1, const String& s2) String::String(const String& s1, const String& s2)
Line 656 
Line 604 
  
 String::String(const String& s1, const char* s2) String::String(const String& s1, const char* s2)
 { {
     _check_null_pointer(s2);      _checkNullPointer(s2);
     size_t n1 = s1._rep->size;     size_t n1 = s1._rep->size;
     size_t n2 = strlen(s2);     size_t n2 = strlen(s2);
     _rep = StringRep::alloc(n1 + n2);     _rep = StringRep::alloc(n1 + n2);
     _copy(_rep->data, s1._rep->data, n1);     _copy(_rep->data, s1._rep->data, n1);
     _rep->size = n1 + _convert((Uint16*)_rep->data + n1, s2, n2);      size_t utf8_error_index;
       size_t tmp = _convert((Uint16*)_rep->data + n1, s2, n2, utf8_error_index);
   
       if (tmp == size_t(-1))
       {
           StringRep::free(_rep);
           _rep = &StringRep::_emptyRep;
           _StringThrowBadUTF8((Uint32)utf8_error_index,s2,n2);
       }
   
       _rep->size = n1 + tmp;
     _rep->data[_rep->size] = '\0';     _rep->data[_rep->size] = '\0';
 } }
  
 String::String(const char* s1, const String& s2) String::String(const char* s1, const String& s2)
 { {
     _check_null_pointer(s1);      _checkNullPointer(s1);
     size_t n1 = strlen(s1);     size_t n1 = strlen(s1);
     size_t n2 = s2._rep->size;     size_t n2 = s2._rep->size;
     _rep = StringRep::alloc(n1 + n2);     _rep = StringRep::alloc(n1 + n2);
     _rep->size = n2 + _convert((Uint16*)_rep->data, s1, n1);      size_t utf8_error_index;
       size_t tmp = _convert((Uint16*)_rep->data, s1, n1, utf8_error_index);
   
       if (tmp ==  size_t(-1))
       {
           StringRep::free(_rep);
           _rep = &StringRep::_emptyRep;
           _StringThrowBadUTF8((Uint32)utf8_error_index,s1,n1);
       }
   
       _rep->size = n2 + tmp;
     _copy(_rep->data + n1, s2._rep->data, n2);     _copy(_rep->data + n1, s2._rep->data, n2);
     _rep->data[_rep->size] = '\0';     _rep->data[_rep->size] = '\0';
 } }
Line 689 
Line 657 
  
 String& String::assign(const Char16* str, Uint32 n) String& String::assign(const Char16* str, Uint32 n)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
  
     if (n > _rep->cap || Atomic_get(&_rep->refs) != 1)      if (n > _rep->cap || _rep->refs.get() != 1)
     {     {
         StringRep::unref(_rep);         StringRep::unref(_rep);
         _rep = StringRep::alloc(n);         _rep = StringRep::alloc(n);
Line 706 
Line 674 
  
 String& String::assign(const char* str, Uint32 n) String& String::assign(const char* str, Uint32 n)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
  
     if (n > _rep->cap || Atomic_get(&_rep->refs) != 1)      if (n > _rep->cap || _rep->refs.get() != 1)
     {     {
         StringRep::unref(_rep);         StringRep::unref(_rep);
         _rep = StringRep::alloc(n);         _rep = StringRep::alloc(n);
     }     }
  
     _rep->size = _convert(_rep->data, str, n);      size_t utf8_error_index;
     _rep->data[_rep->size] = 0;      _rep->size = _convert(_rep->data, str, n, utf8_error_index);
   
     return *this;  
 }  
   
 String& String::assignASCII7(const char* str, Uint32 n)  
 {  
     _check_null_pointer(str);  
  
     if (n > _rep->cap || Atomic_get(&_rep->refs) != 1)      if (_rep->size ==  size_t(-1))
     {     {
         StringRep::unref(_rep);          StringRep::free(_rep);
         _rep = StringRep::alloc(n);          _rep = &StringRep::_emptyRep;
           _StringThrowBadUTF8((Uint32)utf8_error_index,str,n);
     }     }
  
     _copy(_rep->data, str, n);      _rep->data[_rep->size] = 0;
     _rep->data[_rep->size = n] = 0;  
  
     return *this;     return *this;
 } }
Line 740 
Line 701 
 { {
     if (_rep->size)     if (_rep->size)
     {     {
         if (Atomic_get(&_rep->refs) == 1)          if (_rep->refs.get() == 1)
           {
             _rep->size = 0;             _rep->size = 0;
               _rep->data[0] = '\0';
           }
         else         else
         {         {
             StringRep::unref(_rep);             StringRep::unref(_rep);
             _rep = &StringRep::_empty_rep;              _rep = &StringRep::_emptyRep;
         }         }
     }     }
 } }
Line 757 
Line 721 
  
 CString String::getCString() const CString String::getCString() const
 { {
       // A UTF8 string can have three times as many characters as its UTF16
       // counterpart, so we allocate extra memory for the worst case. In the
       // best case, we may need only one third of the memory allocated. But
       // downsizing the string afterwards is expensive and unecessary since
       // CString objects are usually short-lived (disappearing after only a few
       // instructions). CString objects are typically created on the stack as
       // means to obtain a char* pointer.
   
 #ifdef PEGASUS_STRING_NO_UTF8 #ifdef PEGASUS_STRING_NO_UTF8
     char* str = (char*)operator new(_rep->size + 1);     char* str = (char*)operator new(_rep->size + 1);
     _copy(str, _rep->data, _rep->size);     _copy(str, _rep->data, _rep->size);
     str[_rep->size] = '\0';     str[_rep->size] = '\0';
     return CString(str);     return CString(str);
 #else #else
     Uint32 n = 3 * _rep->size;      Uint32 n = (Uint32)(3 * _rep->size);
     char* str = (char*)operator new(n + 1);     char* str = (char*)operator new(n + 1);
     size_t size = _copy_to_utf8(str, _rep->data, _rep->size);      size_t size = _copyToUTF8(str, _rep->data, _rep->size);
     str[size] = '\0';     str[size] = '\0';
     return CString(str);     return CString(str);
 #endif #endif
Line 773 
Line 745 
  
 String& String::append(const Char16* str, Uint32 n) String& String::append(const Char16* str, Uint32 n)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
  
     size_t old_size = _rep->size;      size_t oldSize = _rep->size;
     size_t new_size = old_size + n;      size_t newSize = oldSize + n;
     _reserve(_rep, new_size);      _reserve(_rep, (Uint32)newSize);
     _copy(_rep->data + old_size, (Uint16*)str, n);      _copy(_rep->data + oldSize, (Uint16*)str, n);
     _rep->size = new_size;      _rep->size = newSize;
     _rep->data[new_size] = '\0';      _rep->data[newSize] = '\0';
  
     return *this;     return *this;
 } }
  
 String& String::append(const String& str) String& String::append(const String& str)
 { {
     return append((Char16*)str._rep->data, str._rep->size);      return append((Char16*)(&(str._rep->data[0])), (Uint32)str._rep->size);
 } }
  
 String& String::append(const char* str, Uint32 size) String& String::append(const char* str, Uint32 size)
 { {
     _check_null_pointer(str);      _checkNullPointer(str);
  
     size_t old_size = _rep->size;      size_t oldSize = _rep->size;
     size_t cap = old_size + size;      size_t cap = oldSize + size;
  
     _reserve(_rep, cap);      _reserve(_rep, (Uint32)cap);
     _rep->size += _convert((Uint16*)_rep->data + old_size, str, size);      size_t utf8_error_index;
       size_t tmp = _convert(
           (Uint16*)_rep->data + oldSize, str, size, utf8_error_index);
   
       if (tmp ==  size_t(-1))
       {
           StringRep::free(_rep);
           _rep = &StringRep::_emptyRep;
           _StringThrowBadUTF8((Uint32)utf8_error_index,str,size);
       }
   
       _rep->size += tmp;
     _rep->data[_rep->size] = '\0';     _rep->data[_rep->size] = '\0';
  
     return *this;     return *this;
Line 807 
Line 790 
 void String::remove(Uint32 index, Uint32 n) void String::remove(Uint32 index, Uint32 n)
 { {
     if (n == PEG_NOT_FOUND)     if (n == PEG_NOT_FOUND)
         n = _rep->size - index;          n = (Uint32)(_rep->size - index);
  
     _check_bounds(index + n, _rep->size);      _checkBounds(index + n, _rep->size);
  
     if (Atomic_get(&_rep->refs) != 1)      if (_rep->refs.get() != 1)
         _rep = StringRep::copy_on_write(_rep);          _rep = StringRep::copyOnWrite(_rep);
  
     assert(index + n <= _rep->size);      PEGASUS_ASSERT(index + n <= _rep->size);
  
     size_t rem = _rep->size - (index + n);     size_t rem = _rep->size - (index + n);
     Uint16* data = _rep->data;     Uint16* data = _rep->data;
Line 834 
Line 817 
     if (index < _rep->size)     if (index < _rep->size)
     {     {
         if (n == PEG_NOT_FOUND || n > _rep->size - index)         if (n == PEG_NOT_FOUND || n > _rep->size - index)
             n = _rep->size - index;              n = (Uint32)(_rep->size - index);
  
         return String((Char16*)_rep->data + index, n);          return String((Char16*)(_rep->data + index), n);
     }     }
  
     return String();     return String();
Line 847 
Line 830 
     Uint16* p = (Uint16*)_find(_rep->data, _rep->size, c);     Uint16* p = (Uint16*)_find(_rep->data, _rep->size, c);
  
     if (p)     if (p)
         return p - _rep->data;          return static_cast<Uint32>(p - _rep->data);
  
     return PEG_NOT_FOUND;     return PEG_NOT_FOUND;
 } }
  
 Uint32 String::find(Uint32 index, Char16 c) const Uint32 String::find(Uint32 index, Char16 c) const
 { {
     _check_bounds(index, _rep->size);      _checkBounds(index, _rep->size);
  
     if (index >= _rep->size)     if (index >= _rep->size)
         return PEG_NOT_FOUND;         return PEG_NOT_FOUND;
Line 862 
Line 845 
     Uint16* p = (Uint16*)_find(_rep->data + index, _rep->size - index, c);     Uint16* p = (Uint16*)_find(_rep->data + index, _rep->size - index, c);
  
     if (p)     if (p)
         return p - _rep->data;          return static_cast<Uint32>(p - _rep->data);
  
     return PEG_NOT_FOUND;     return PEG_NOT_FOUND;
 } }
  
 Uint32 String::_find_aux(const Char16* s, Uint32 n) const  Uint32 StringFindAux(
       const StringRep* _rep, const Char16* s, Uint32 n)
 { {
     _check_null_pointer(s);      _checkNullPointer(s);
  
     const Uint16* data = _rep->data;     const Uint16* data = _rep->data;
     size_t rem = _rep->size;     size_t rem = _rep->size;
Line 882 
Line 866 
             break;             break;
  
         if (memcmp(p, s, n * sizeof(Uint16)) == 0)         if (memcmp(p, s, n * sizeof(Uint16)) == 0)
             return p - _rep->data;              return static_cast<Uint32>(p - _rep->data);
  
         p++;         p++;
         rem -= p - data;         rem -= p - data;
Line 894 
Line 878 
  
 Uint32 String::find(const char* s) const Uint32 String::find(const char* s) const
 { {
     _check_null_pointer(s);      _checkNullPointer(s);
  
     // Note: could optimize away creation of temporary, but this is rarely     // Note: could optimize away creation of temporary, but this is rarely
     // called.     // called.
Line 910 
Line 894 
     while (q != p)     while (q != p)
     {     {
         if (*--q == x)         if (*--q == x)
             return q - p;              return static_cast<Uint32>(q - p);
     }     }
  
     return PEG_NOT_FOUND;     return PEG_NOT_FOUND;
Line 922 
Line 906 
  
     if (InitializeICU::initICUSuccessful())     if (InitializeICU::initICUSuccessful())
     {     {
         if (Atomic_get(&_rep->refs) != 1)          if (_rep->refs.get() != 1)
                 _rep = StringRep::copy_on_write(_rep);              _rep = StringRep::copyOnWrite(_rep);
  
         // This will do a locale-insensitive, but context-sensitive convert.         // This will do a locale-insensitive, but context-sensitive convert.
         // Since context-sensitive casing looks at adjacent chars, this         // Since context-sensitive casing looks at adjacent chars, this
Line 936 
Line 920 
  
         UErrorCode err = U_ZERO_ERROR;         UErrorCode err = U_ZERO_ERROR;
  
         int32_t new_size = u_strToLower(          int32_t newSize = u_strToLower(
             NULL, 0, (UChar*)_rep->data, _rep->size, NULL, &err);             NULL, 0, (UChar*)_rep->data, _rep->size, NULL, &err);
  
         err = U_ZERO_ERROR;         err = U_ZERO_ERROR;
  
         //// Reserve enough space for the result.         //// Reserve enough space for the result.
  
         if ((Uint32)new_size > _rep->cap)          if ((Uint32)newSize > _rep->cap)
             _reserve(_rep, new_size);              _reserve(_rep, newSize);
  
         //// Perform the conversion (overlapping buffers are allowed).         //// Perform the conversion (overlapping buffers are allowed).
  
         u_strToLower((UChar*)_rep->data, new_size,          u_strToLower((UChar*)_rep->data, newSize,
             (UChar*)_rep->data, _rep->size, NULL, &err);             (UChar*)_rep->data, _rep->size, NULL, &err);
  
         _rep->size = new_size;          _rep->size = newSize;
         return;         return;
     }     }
  
 #endif /* PEGASUS_HAS_ICU */ #endif /* PEGASUS_HAS_ICU */
  
     if (Atomic_get(&_rep->refs) != 1)      if (_rep->refs.get() != 1)
         _rep = StringRep::copy_on_write(_rep);          _rep = StringRep::copyOnWrite(_rep);
  
     Uint16* p = _rep->data;     Uint16* p = _rep->data;
     size_t n = _rep->size;     size_t n = _rep->size;
Line 966 
Line 950 
     for (; n--; p++)     for (; n--; p++)
     {     {
         if (!(*p & 0xFF00))         if (!(*p & 0xFF00))
             *p = _to_lower(*p);              *p = _toLower(*p);
     }     }
 } }
  
Line 976 
Line 960 
  
     if (InitializeICU::initICUSuccessful())     if (InitializeICU::initICUSuccessful())
     {     {
         if (Atomic_get(&_rep->refs) != 1)          if (_rep->refs.get() != 1)
             _rep = StringRep::copy_on_write(_rep);              _rep = StringRep::copyOnWrite(_rep);
  
         // This will do a locale-insensitive, but context-sensitive convert.         // This will do a locale-insensitive, but context-sensitive convert.
         // Since context-sensitive casing looks at adjacent chars, this         // Since context-sensitive casing looks at adjacent chars, this
Line 990 
Line 974 
  
         UErrorCode err = U_ZERO_ERROR;         UErrorCode err = U_ZERO_ERROR;
  
         int32_t new_size = u_strToUpper(          int32_t newSize = u_strToUpper(
             NULL, 0, (UChar*)_rep->data, _rep->size, NULL, &err);             NULL, 0, (UChar*)_rep->data, _rep->size, NULL, &err);
  
         err = U_ZERO_ERROR;         err = U_ZERO_ERROR;
  
         //// Reserve enough space for the result.         //// Reserve enough space for the result.
  
         if ((Uint32)new_size > _rep->cap)          if ((Uint32)newSize > _rep->cap)
             _reserve(_rep, new_size);              _reserve(_rep, newSize);
  
         //// Perform the conversion (overlapping buffers are allowed).         //// Perform the conversion (overlapping buffers are allowed).
  
         u_strToUpper((UChar*)_rep->data, new_size,          u_strToUpper((UChar*)_rep->data, newSize,
             (UChar*)_rep->data, _rep->size, NULL, &err);             (UChar*)_rep->data, _rep->size, NULL, &err);
  
         _rep->size = new_size;          _rep->size = newSize;
  
         return;         return;
     }     }
  
 #endif /* PEGASUS_HAS_ICU */ #endif /* PEGASUS_HAS_ICU */
  
     if (Atomic_get(&_rep->refs) != 1)      if (_rep->refs.get() != 1)
         _rep = StringRep::copy_on_write(_rep);          _rep = StringRep::copyOnWrite(_rep);
  
     Uint16* p = _rep->data;     Uint16* p = _rep->data;
     size_t n = _rep->size;     size_t n = _rep->size;
  
     for (; n--; p++)     for (; n--; p++)
         *p = _to_upper(*p);          *p = _toUpper(*p);
 } }
  
 int String::compare(const String& s1, const String& s2, Uint32 n) int String::compare(const String& s1, const String& s2, Uint32 n)
 { {
     assert(n <= s1._rep->size);      const Uint16* p1 = s1._rep->data;
     assert(n <= s2._rep->size);      const Uint16* p2 = s2._rep->data;
  
     // Ignoring error in which n is greater than s1.size() or s2.size()      while (n--)
     return _compare(s1._rep->data, s2._rep->data, n);      {
           int r = *p1++ - *p2++;
           if (r)
           {
               return r;
           }
           else if (!p1[-1])
           {
               // We must have encountered a null terminator in both s1 and s2
               return 0;
           }
       }
       return 0;
 } }
  
 int String::compare(const String& s1, const String& s2) int String::compare(const String& s1, const String& s2)
Line 1038 
Line 1034 
  
 int String::compare(const String& s1, const char* s2) int String::compare(const String& s1, const char* s2)
 { {
     _check_null_pointer(s2);      _checkNullPointer(s2);
  
 #ifdef PEGASUS_STRING_NO_UTF8 #ifdef PEGASUS_STRING_NO_UTF8
     return _compare_no_utf8(s1._rep->data, s2);      return _compareNoUTF8(s1._rep->data, s2);
 #else #else
     // ATTN: optimize this!     // ATTN: optimize this!
     return String::compare(s1, String(s2));     return String::compare(s1, String(s2));
Line 1055 
Line 1051 
     if (InitializeICU::initICUSuccessful())     if (InitializeICU::initICUSuccessful())
     {     {
         return  u_strcasecmp(         return  u_strcasecmp(
             str1._rep->data, str2._rep->data, U_FOLD_CASE_DEFAULT);              (const UChar*)str1._rep->data,
               (const UChar*)str2._rep->data,
               U_FOLD_CASE_DEFAULT
               );
     }     }
  
 #endif /* PEGASUS_HAS_ICU */ #endif /* PEGASUS_HAS_ICU */
Line 1065 
Line 1064 
  
     while (*s1 && *s2)     while (*s1 && *s2)
     {     {
         int r = _to_lower(*s1++) - _to_lower(*s2++);          int r = _toLower(*s1++) - _toLower(*s2++);
  
         if (r)         if (r)
             return r;             return r;
Line 1079 
Line 1078 
     return 0;     return 0;
 } }
  
 Boolean String::equalNoCase_aux(const String& s1, const String& s2)  Boolean StringEqualNoCase(const String& s1, const String& s2)
 { {
 #ifdef PEGASUS_HAS_ICU #ifdef PEGASUS_HAS_ICU
  
Line 1087 
Line 1086 
  
 #else /* PEGASUS_HAS_ICU */ #else /* PEGASUS_HAS_ICU */
  
     Uint16* p = (Uint16*)s1._rep->data;      // The following employs loop unrolling for efficiency. Please do not
     Uint16* q = (Uint16*)s2._rep->data;      // eliminate.
     Uint32 n = s2._rep->size;  
       Uint16* p = (Uint16*)s1.getChar16Data();
       Uint16* q = (Uint16*)s2.getChar16Data();
       Uint32 n = s2.size();
  
     while (n >= 8)     while (n >= 8)
     {     {
         if (((p[0] - q[0]) && (_to_upper(p[0]) - _to_upper(q[0]))) ||          if (((p[0] - q[0]) && (_toUpper(p[0]) - _toUpper(q[0]))) ||
             ((p[1] - q[1]) && (_to_upper(p[1]) - _to_upper(q[1]))) ||              ((p[1] - q[1]) && (_toUpper(p[1]) - _toUpper(q[1]))) ||
             ((p[2] - q[2]) && (_to_upper(p[2]) - _to_upper(q[2]))) ||              ((p[2] - q[2]) && (_toUpper(p[2]) - _toUpper(q[2]))) ||
             ((p[3] - q[3]) && (_to_upper(p[3]) - _to_upper(q[3]))) ||              ((p[3] - q[3]) && (_toUpper(p[3]) - _toUpper(q[3]))) ||
             ((p[4] - q[4]) && (_to_upper(p[4]) - _to_upper(q[4]))) ||              ((p[4] - q[4]) && (_toUpper(p[4]) - _toUpper(q[4]))) ||
             ((p[5] - q[5]) && (_to_upper(p[5]) - _to_upper(q[5]))) ||              ((p[5] - q[5]) && (_toUpper(p[5]) - _toUpper(q[5]))) ||
             ((p[6] - q[6]) && (_to_upper(p[6]) - _to_upper(q[6]))) ||              ((p[6] - q[6]) && (_toUpper(p[6]) - _toUpper(q[6]))) ||
             ((p[7] - q[7]) && (_to_upper(p[7]) - _to_upper(q[7]))))              ((p[7] - q[7]) && (_toUpper(p[7]) - _toUpper(q[7]))))
         {         {
             return false;             return false;
         }         }
Line 1112 
Line 1114 
  
     while (n >= 4)     while (n >= 4)
     {     {
         if (((p[0] - q[0]) && (_to_upper(p[0]) - _to_upper(q[0]))) ||          if (((p[0] - q[0]) && (_toUpper(p[0]) - _toUpper(q[0]))) ||
             ((p[1] - q[1]) && (_to_upper(p[1]) - _to_upper(q[1]))) ||              ((p[1] - q[1]) && (_toUpper(p[1]) - _toUpper(q[1]))) ||
             ((p[2] - q[2]) && (_to_upper(p[2]) - _to_upper(q[2]))) ||              ((p[2] - q[2]) && (_toUpper(p[2]) - _toUpper(q[2]))) ||
             ((p[3] - q[3]) && (_to_upper(p[3]) - _to_upper(q[3]))))              ((p[3] - q[3]) && (_toUpper(p[3]) - _toUpper(q[3]))))
         {         {
             return false;             return false;
         }         }
Line 1127 
Line 1129 
  
     while (n--)     while (n--)
     {     {
         if (((p[0] - q[0]) && (_to_upper(p[0]) - _to_upper(q[0]))))          if (((p[0] - q[0]) && (_toUpper(p[0]) - _toUpper(q[0]))))
             return false;             return false;
  
         p++;         p++;
Line 1141 
Line 1143 
  
 Boolean String::equalNoCase(const String& s1, const char* s2) Boolean String::equalNoCase(const String& s1, const char* s2)
 { {
     _check_null_pointer(s2);      _checkNullPointer(s2);
  
 #if defined(PEGASUS_HAS_ICU) #if defined(PEGASUS_HAS_ICU)
  
Line 1158 
Line 1160 
         if (!*p2)         if (!*p2)
             return false;             return false;
  
         if (_to_upper(*p1++) != _to_upper_tbl[int(*p2++)])          if (_toUpper(*p1++) != _toUpperTable[int(*p2++)])
             return false;             return false;
     }     }
  
Line 1177 
Line 1179 
  
 Boolean String::equal(const String& s1, const String& s2) Boolean String::equal(const String& s1, const String& s2)
 { {
     return s1._rep->size == s2._rep->size && memcmp(s1._rep->data,      return (s1._rep == s2._rep) ||
         s2._rep->data, s1._rep->size * sizeof(Uint16)) == 0;          ((s1._rep->size == s2._rep->size) &&
            memcmp(s1._rep->data,
                   s2._rep->data,
                   s1._rep->size * sizeof(Uint16)) == 0);
   }
   
   void String::appendPrintf(const char* format, ...)
   {
       va_list ap;
       va_start(ap, format);
   
       // Format into allocated memory
       ////char* rtnCharPtr = _charVPrintf(format, ap);
   
       // Iniitial allocation size.  This is a guess assuming that
       // most printfs are one or two lines long
       int allocSize = 256;
       int rtnSize;
       char *p;
   
       // initial allocate for output
       if ((p = (char*)malloc(allocSize)) == NULL)
       {
           return;
       }
   
       // repeat formatting  with increased realloc until it works.
       do
       {
           rtnSize = vsnprintf(p, allocSize, format, ap);
   
           // return if successful; i.e. if not negative and
           // returns less than allocated size.
           if (rtnSize > -1 && rtnSize < allocSize)
           {
               break;
           }
   
           // increment alloc size. Positive return is
           // expected size and negative is error.
           allocSize = (rtnSize > -1)? (rtnSize + 1) : allocSize * 2;
   
       } while((p = (char*)peg_inln_realloc(p, allocSize)) != NULL);
   
       // get here only with error in malloc.
   
       va_end(ap);
   
       // Free allocated memory append printf output to current string
       append(p, rtnSize);
       free(p);
 } }
  
 Boolean String::equal(const String& s1, const char* s2) Boolean String::equal(const String& s1, const char* s2)
 { {
 #ifdef PEGASUS_STRING_NO_UTF8 #ifdef PEGASUS_STRING_NO_UTF8
  
     _check_null_pointer(s2);      _checkNullPointer(s2);
  
     const Uint16* p = (Uint16*)s1._rep->data;     const Uint16* p = (Uint16*)s1._rep->data;
     const char* q = s2;     const char* q = s2;
Line 1207 
Line 1259 
  
 PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& str) PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& str)
 { {
 #if defined(PEGASUS_OS_OS400)  
   
     CString cstr = str.getCString();  
     const char* utf8str = cstr;  
     os << utf8str;  
     return os;  
 #else  
   
 #if defined(PEGASUS_HAS_ICU) #if defined(PEGASUS_HAS_ICU)
  
     if (InitializeICU::initICUSuccessful())     if (InitializeICU::initICUSuccessful())
Line 1250 
Line 1294 
     }     }
  
     return os;     return os;
 #endif // PEGASUS_OS_OS400  
 } }
  
 void String::_append_char_aux()  void StringAppendCharAux(StringRep*& _rep)
 { {
     StringRep* tmp;     StringRep* tmp;
  
Line 1273 
Line 1316 
     _rep = tmp;     _rep = tmp;
 } }
  
   void AssignASCII(String& s, const char* str, Uint32 n)
   {
       class StringLayout
       {
       public:
           StringRep* rep;
       };
   
       StringLayout* that = reinterpret_cast<StringLayout*>(&s);
   
       _checkNullPointer(str);
   
       if (n > that->rep->cap || that->rep->refs.get() != 1)
       {
           StringRep::unref(that->rep);
           that->rep = StringRep::alloc(n);
       }
   
       _copy(that->rep->data, str, n);
       that->rep->size = n;
       that->rep->data[that->rep->size] = 0;
   }
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
  
 /* /*
Line 1296 
Line 1362 
         GCC Developers Summit). This reduced default construction to a simple         GCC Developers Summit). This reduced default construction to a simple
         pointer assignment.         pointer assignment.
  
             inline String::String() : _rep(&_empty_rep) { }              inline String::String() : _rep(&_emptyRep) { }
  
     5.  Implemented Uint16 versions of toupper() and tolower() using tables.     5.  Implemented Uint16 versions of toupper() and tolower() using tables.
         For example:         For example:
Line 1306 
Line 1372 
                 0,1,2,...255                 0,1,2,...255
             };             };
  
             inline Uint16 _to_upper(Uint16 x)              inline Uint16 _toUpper(Uint16 x)
             {             {
                 return (x & 0xFF00) ? x : _upper[x];                 return (x & 0xFF00) ? x : _upper[x];
             }             }
Line 1345 
Line 1411 
             String operator+(const String& s1, const char* s2)             String operator+(const String& s1, const char* s2)
             String operator+(const char* s1, const String& s2)             String operator+(const char* s1, const String& s2)
  
     7.  Optimized _next_pow_2(), used in rounding the capacity to the next      7.  Optimized _roundUpToPow2(), used in rounding the capacity to the next
         power of two (algorithm from the book "Hacker's Delight").         power of two (algorithm from the book "Hacker's Delight").
  
             static Uint32 _next_pow_2(Uint32 x)              static Uint32 _roundUpToPow2(Uint32 x)
             {             {
                 if (x < 8)                 if (x < 8)
                     return 8;                     return 8;
Line 1400 
Line 1466 
  
         This avoids slower UTF8 processing when not needed.         This avoids slower UTF8 processing when not needed.
  
 BUG-4200 Review notes:  
   
     1.  Use PEGASUS_USE_EXPERIMENTAL_INTERFACES instead of  
         PEGASUS_STRING_EXTENSIONS.  
   
         Status: done  
   
     2.  Doc++ String.h  
   
         Status: pending  
   
     3.  Look at PEP223 for security coding guidelines for strings.  
   
         Status: pending  
   
     4.  Increasing the number of objects may break Windows 2000 build  
         (limit of 2048 bytes for command line). See BUG-2754  
   
         Status: submitted patch for bug 2754  
   
     5.  Concerns about whether generating inlines and non-inline versions  
         of functions will work with all compilers.  
   
         Status: tested on Windows. Also showed how inlining can be disabled  
         on platforms that don't support it.  
   
     6.  Atomic.h -- more to come  
   
 ================================================================================ ================================================================================
 */ */


Legend:
Removed from v.1.111.6.3  
changed lines
  Added in v.1.140

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2