version 1.119, 2006/01/30 16:17:08
|
version 1.123, 2006/11/10 18:14:58
|
|
|
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Mike Brasher (mbrasher@austin.rr.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, Symantec Corp. (david_dillard@symantec.com) |
|
// Mike Brasher (mike-brasher@austin.rr.com) |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/PegasusAssert.h> | #include <Pegasus/Common/PegasusAssert.h> |
|
|
// | // |
// 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. |
// | // |
//============================================================================== | //============================================================================== |
|
|
// Rounds x up to the nearest 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 _roundUpToPow2(Uint32 x) | static Uint32 _roundUpToPow2(Uint32 x) |
{ | { |
#ifndef PEGASUS_STRING_NO_THROW |
// Check for potential overflow in x |
|
PEGASUS_CHECK_CAPACITY_OVERFLOW(x); |
if (x > 0x0FFFFFFF) |
|
throw PEGASUS_STD(bad_alloc)(); |
|
|
|
#endif |
|
| |
if (x < 8) | if (x < 8) |
return 8; | return 8; |
|
|
| |
inline void _checkNullPointer(const void* ptr) | inline void _checkNullPointer(const void* ptr) |
{ | { |
#ifndef PEGASUS_STRING_NO_THROW |
|
|
|
if (!ptr) | if (!ptr) |
throw NullPointer(); | throw NullPointer(); |
|
|
#endif |
|
} | } |
| |
static void _StringThrowBadUTF8(Uint32 index) | static void _StringThrowBadUTF8(Uint32 index) |
|
|
| |
inline StringRep* StringRep::alloc(size_t cap) | inline StringRep* StringRep::alloc(size_t cap) |
{ | { |
#ifndef PEGASUS_STRING_NO_THROW |
// Check for potential overflow in cap |
|
PEGASUS_CHECK_CAPACITY_OVERFLOW(cap); |
// Any string bigger than this is seriously suspect. |
|
if (cap > 0x0FFFFFFF) |
|
throw PEGASUS_STD(bad_alloc)(); |
|
|
|
#endif |
|
| |
StringRep* rep = (StringRep*)::operator new( | StringRep* rep = (StringRep*)::operator new( |
sizeof(StringRep) + cap * sizeof(Uint16)); | sizeof(StringRep) + cap * sizeof(Uint16)); |
|
|
size_t utf8_error_index; | size_t utf8_error_index; |
rep->size = _convert((Uint16*)rep->data, data, size, utf8_error_index); | rep->size = _convert((Uint16*)rep->data, data, size, utf8_error_index); |
| |
#ifndef PEGASUS_STRING_NO_THROW |
|
if (rep->size == size_t(-1)) | if (rep->size == size_t(-1)) |
{ | { |
StringRep::free(rep); | StringRep::free(rep); |
_StringThrowBadUTF8(utf8_error_index); | _StringThrowBadUTF8(utf8_error_index); |
} | } |
#endif |
|
| |
rep->data[rep->size] = '\0'; | rep->data[rep->size] = '\0'; |
| |
|
|
size_t utf8_error_index; | size_t utf8_error_index; |
size_t tmp = _convert((Uint16*)_rep->data + n1, s2, n2, utf8_error_index); | size_t tmp = _convert((Uint16*)_rep->data + n1, s2, n2, utf8_error_index); |
| |
#ifndef PEGASUS_STRING_NO_THROW |
|
if (tmp == size_t(-1)) | if (tmp == size_t(-1)) |
{ | { |
StringRep::free(_rep); | StringRep::free(_rep); |
_rep = &StringRep::_emptyRep; | _rep = &StringRep::_emptyRep; |
_StringThrowBadUTF8(utf8_error_index); | _StringThrowBadUTF8(utf8_error_index); |
} | } |
#endif |
|
| |
_rep->size = n1 + tmp; | _rep->size = n1 + tmp; |
_rep->data[_rep->size] = '\0'; | _rep->data[_rep->size] = '\0'; |
|
|
size_t utf8_error_index; | size_t utf8_error_index; |
size_t tmp = _convert((Uint16*)_rep->data, s1, n1, utf8_error_index); | size_t tmp = _convert((Uint16*)_rep->data, s1, n1, utf8_error_index); |
| |
#ifndef PEGASUS_STRING_NO_THROW |
|
if (tmp == size_t(-1)) | if (tmp == size_t(-1)) |
{ | { |
StringRep::free(_rep); | StringRep::free(_rep); |
_rep = &StringRep::_emptyRep; | _rep = &StringRep::_emptyRep; |
_StringThrowBadUTF8(utf8_error_index); | _StringThrowBadUTF8(utf8_error_index); |
} | } |
#endif |
|
| |
_rep->size = n2 + tmp; | _rep->size = n2 + tmp; |
_copy(_rep->data + n1, s2._rep->data, n2); | _copy(_rep->data + n1, s2._rep->data, n2); |
|
|
size_t utf8_error_index; | size_t utf8_error_index; |
_rep->size = _convert(_rep->data, str, n, utf8_error_index); | _rep->size = _convert(_rep->data, str, n, utf8_error_index); |
| |
#ifndef PEGASUS_STRING_NO_THROW |
|
if (_rep->size == size_t(-1)) | if (_rep->size == size_t(-1)) |
{ | { |
StringRep::free(_rep); | StringRep::free(_rep); |
_rep = &StringRep::_emptyRep; | _rep = &StringRep::_emptyRep; |
_StringThrowBadUTF8(utf8_error_index); | _StringThrowBadUTF8(utf8_error_index); |
} | } |
#endif |
|
| |
_rep->data[_rep->size] = 0; | _rep->data[_rep->size] = 0; |
| |
|
|
| |
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])), str._rep->size); |
} | } |
| |
String& String::append(const char* str, Uint32 size) | String& String::append(const char* str, Uint32 size) |
|
|
size_t tmp = _convert( | size_t tmp = _convert( |
(Uint16*)_rep->data + oldSize, str, size, utf8_error_index); | (Uint16*)_rep->data + oldSize, str, size, utf8_error_index); |
| |
#ifndef PEGASUS_STRING_NO_THROW |
|
if (tmp == size_t(-1)) | if (tmp == size_t(-1)) |
{ | { |
StringRep::free(_rep); | StringRep::free(_rep); |
_rep = &StringRep::_emptyRep; | _rep = &StringRep::_emptyRep; |
_StringThrowBadUTF8(utf8_error_index); | _StringThrowBadUTF8(utf8_error_index); |
} | } |
#endif |
|
| |
_rep->size += tmp; | _rep->size += tmp; |
_rep->data[_rep->size] = '\0'; | _rep->data[_rep->size] = '\0'; |
|
|
if (n == PEG_NOT_FOUND || n > _rep->size - index) | if (n == PEG_NOT_FOUND || n > _rep->size - index) |
n = _rep->size - index; | n = _rep->size - index; |
| |
return String((Char16*)_rep->data + index, n); |
return String((Char16*)(_rep->data + index), n); |
} | } |
| |
return String(); | return String(); |