Browse Source

Add UnicodeBuffer as first class data type and allow plStrings to be constructed with it

Michael Hansen 12 years ago
parent
commit
66fe6ed73e
  1. 33
      Sources/Plasma/CoreLib/plString.cpp
  2. 20
      Sources/Plasma/CoreLib/plString.h

33
Sources/Plasma/CoreLib/plString.cpp

@ -204,19 +204,25 @@ void plString::IConvertFromWchar(const wchar_t *wstr, size_t size)
// We assume that if sizeof(wchar_t) == 2, the data is UTF-16 already // We assume that if sizeof(wchar_t) == 2, the data is UTF-16 already
IConvertFromUtf16((const uint16_t *)wstr, size); IConvertFromUtf16((const uint16_t *)wstr, size);
#else #else
IConvertFromUtf32((const UniChar *)wstr, size);
#endif
}
void plString::IConvertFromUtf32(const UniChar *ustr, size_t size)
{
fUtf8Buffer = plStringBuffer<char>(); fUtf8Buffer = plStringBuffer<char>();
if (wstr == nil) if (ustr == nil)
return; return;
if ((int32_t)size < 0) if ((int32_t)size < 0)
size = wcsnlen(wstr, -(int32_t)size); size = ustrlen(ustr, -(int32_t)size);
// Calculate the UTF-8 size // Calculate the UTF-8 size
size_t convlen = 0; size_t convlen = 0;
const wchar_t *sp = wstr; const UniChar *sp = ustr;
while (sp < wstr + size) { while (sp < ustr + size) {
if (*sp > 0x10FFFF) { if (*sp > 0x10FFFF) {
hsAssert(0, "UCS-4 character out of range"); hsAssert(0, "UTF-32 character out of range");
convlen += 3; // Use U+FFFD for release builds convlen += 3; // Use U+FFFD for release builds
} }
else if (*sp > 0xFFFF) else if (*sp > 0xFFFF)
@ -233,8 +239,8 @@ void plString::IConvertFromWchar(const wchar_t *wstr, size_t size)
// And perform the actual conversion // And perform the actual conversion
char *utf8 = fUtf8Buffer.CreateWritableBuffer(convlen); char *utf8 = fUtf8Buffer.CreateWritableBuffer(convlen);
char *dp = utf8; char *dp = utf8;
sp = wstr; sp = ustr;
while (sp < wstr + size) { while (sp < ustr + size) {
if (*sp > 0x10FFFF) { if (*sp > 0x10FFFF) {
// Character out of range; Use U+FFFD instead // Character out of range; Use U+FFFD instead
*dp++ = 0xE0 | ((BADCHAR_REPLACEMENT >> 12) & 0x0F); *dp++ = 0xE0 | ((BADCHAR_REPLACEMENT >> 12) & 0x0F);
@ -258,7 +264,6 @@ void plString::IConvertFromWchar(const wchar_t *wstr, size_t size)
++sp; ++sp;
} }
utf8[convlen] = 0; utf8[convlen] = 0;
#endif
} }
void plString::IConvertFromIso8859_1(const char *astr, size_t size) void plString::IConvertFromIso8859_1(const char *astr, size_t size)
@ -462,9 +467,9 @@ plStringBuffer<char> plString::ToIso8859_1() const
return result; return result;
} }
plStringBuffer<UniChar> plString::GetUnicodeArray() const plUnicodeBuffer plString::GetUnicodeArray() const
{ {
plStringBuffer<UniChar> result; plUnicodeBuffer result;
if (IsEmpty()) if (IsEmpty())
return result; return result;
@ -822,3 +827,11 @@ plStringStream &plStringStream::operator<<(unsigned int num)
snprintf(buffer, 12, "%u", num); snprintf(buffer, 12, "%u", num);
return operator<<(buffer); return operator<<(buffer);
} }
size_t ustrlen(const UniChar *ustr, size_t max)
{
size_t length = 0;
for ( ; *ustr++ && max--; ++length)
;
return length;
}

20
Sources/Plasma/CoreLib/plString.h

@ -121,7 +121,6 @@ public:
const _Ch *GetData() const { return IHaveACow() ? fData->fStringData : fShort; } const _Ch *GetData() const { return IHaveACow() ? fData->fStringData : fShort; }
size_t GetSize() const { return fSize; } size_t GetSize() const { return fSize; }
operator const _Ch *() const { return GetData(); } operator const _Ch *() const { return GetData(); }
// From Haxxia with love // From Haxxia with love
@ -142,14 +141,15 @@ public:
} }
}; };
typedef plStringBuffer<UniChar> plUnicodeBuffer;
class plString class plString
{ {
public:
enum { enum {
kSizeAuto = (size_t)(0x80000000) kSizeAuto = (size_t)(0x80000000)
}; };
public:
static const plString Null; static const plString Null;
private: private:
@ -158,6 +158,7 @@ private:
void IConvertFromUtf8(const char *utf8, size_t size); void IConvertFromUtf8(const char *utf8, size_t size);
void IConvertFromUtf16(const uint16_t *utf16, size_t size); void IConvertFromUtf16(const uint16_t *utf16, size_t size);
void IConvertFromWchar(const wchar_t *wstr, size_t size); void IConvertFromWchar(const wchar_t *wstr, size_t size);
void IConvertFromUtf32(const UniChar *ustr, size_t size);
void IConvertFromIso8859_1(const char *astr, size_t size); void IConvertFromIso8859_1(const char *astr, size_t size);
public: public:
@ -166,10 +167,12 @@ public:
plString(const char *cstr) { IConvertFromUtf8(cstr, kSizeAuto); } plString(const char *cstr) { IConvertFromUtf8(cstr, kSizeAuto); }
plString(const plString &copy) : fUtf8Buffer(copy.fUtf8Buffer) { } plString(const plString &copy) : fUtf8Buffer(copy.fUtf8Buffer) { }
plString(const plStringBuffer<char> &init) { operator=(init); } plString(const plStringBuffer<char> &init) { operator=(init); }
plString(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); }
plString &operator=(const char *cstr) { IConvertFromUtf8(cstr, kSizeAuto); return *this; } plString &operator=(const char *cstr) { IConvertFromUtf8(cstr, kSizeAuto); return *this; }
plString &operator=(const plString &copy) { fUtf8Buffer = copy.fUtf8Buffer; return *this; } plString &operator=(const plString &copy) { fUtf8Buffer = copy.fUtf8Buffer; return *this; }
plString &operator=(const plStringBuffer<char> &init); plString &operator=(const plStringBuffer<char> &init);
plString &operator=(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); }
plString &operator+=(const char *cstr) { return operator=(*this + cstr); } plString &operator+=(const char *cstr) { return operator=(*this + cstr); }
plString &operator+=(const plString &str) { return operator=(*this + str); } plString &operator+=(const plString &str) { return operator=(*this + str); }
@ -213,7 +216,7 @@ public:
plStringBuffer<char> ToIso8859_1() const; plStringBuffer<char> ToIso8859_1() const;
// For use in displaying characters in a GUI // For use in displaying characters in a GUI
plStringBuffer<UniChar> GetUnicodeArray() const; plUnicodeBuffer GetUnicodeArray() const;
size_t GetSize() const { return fUtf8Buffer.GetSize(); } size_t GetSize() const { return fUtf8Buffer.GetSize(); }
bool IsEmpty() const { return fUtf8Buffer.GetSize() == 0; } bool IsEmpty() const { return fUtf8Buffer.GetSize() == 0; }
@ -399,6 +402,13 @@ public:
return ch; return ch;
} }
UniChar operator[](size_t offset) const
{
iterator copy(*this);
copy += offset;
return *copy;
}
bool AtEnd() const { return m_ptr >= m_end; } bool AtEnd() const { return m_ptr >= m_end; }
bool IsValid() const { return m_ptr != 0; } bool IsValid() const { return m_ptr != 0; }
@ -464,4 +474,6 @@ private:
size_t fLength; size_t fLength;
}; };
size_t ustrlen(const UniChar *ustr, size_t max = plString::kSizeAuto);
#endif //plString_Defined #endif //plString_Defined

Loading…
Cancel
Save