Browse Source

Merge pull request #442 from zrax/plString-construction

plString constructor enhancements
Adam Johnson 11 years ago
parent
commit
964256411e
  1. 24
      Sources/Plasma/CoreLib/plString.cpp
  2. 74
      Sources/Plasma/CoreLib/plString.h

24
Sources/Plasma/CoreLib/plString.cpp

@ -88,14 +88,12 @@ void plString::IConvertFromUtf8(const char *utf8, size_t size)
operator=(plStringBuffer<char>(utf8, size)); operator=(plStringBuffer<char>(utf8, size));
} }
plString &plString::operator=(const plStringBuffer<char> &init)
{
fUtf8Buffer = init;
#ifdef _DEBUG #ifdef _DEBUG
// Check to make sure the string is actually valid UTF-8 // Check to make sure the string is actually valid UTF-8
const char *sp = fUtf8Buffer.GetData(); static void _check_utf8_buffer(const plStringBuffer<char> &buffer)
while (sp < fUtf8Buffer.GetData() + fUtf8Buffer.GetSize()) { {
const char *sp = buffer.GetData();
while (sp < buffer.GetData() + buffer.GetSize()) {
unsigned char unichar = *sp++; unsigned char unichar = *sp++;
if ((unichar & 0xF8) == 0xF0) { if ((unichar & 0xF8) == 0xF0) {
// Four bytes // Four bytes
@ -115,8 +113,22 @@ plString &plString::operator=(const plStringBuffer<char> &init)
hsAssert(0, "UTF-8 character out of range"); hsAssert(0, "UTF-8 character out of range");
} }
} }
}
#else
# define _check_utf8_buffer(buffer) NULL_STMT
#endif #endif
plString &plString::operator=(const plStringBuffer<char> &init)
{
fUtf8Buffer = init;
_check_utf8_buffer(fUtf8Buffer);
return *this;
}
plString &plString::operator=(plStringBuffer<char> &&init)
{
fUtf8Buffer = std::move(init);
_check_utf8_buffer(fUtf8Buffer);
return *this; return *this;
} }

74
Sources/Plasma/CoreLib/plString.h

@ -128,6 +128,13 @@ public:
fData->AddRef(); fData->AddRef();
} }
/** Move constructor */
plStringBuffer(plStringBuffer<_Ch> &&move) : fSize(move.fSize)
{
memcpy(fShort, move.fShort, sizeof(fShort));
move.fSize = 0;
}
/** Construct a string buffer which holds a COPY of the \a data, up to /** Construct a string buffer which holds a COPY of the \a data, up to
* \a size characters. The terminating '\0' is added automatically, * \a size characters. The terminating '\0' is added automatically,
* meaning this constructor is safe to use on buffers which are not * meaning this constructor is safe to use on buffers which are not
@ -154,7 +161,7 @@ public:
} }
/** Assignment operator. Changes the reference to point to the /** Assignment operator. Changes the reference to point to the
* copied buffer in \a copy. * buffer in \a copy.
*/ */
plStringBuffer<_Ch> &operator=(const plStringBuffer<_Ch> &copy) plStringBuffer<_Ch> &operator=(const plStringBuffer<_Ch> &copy)
{ {
@ -168,6 +175,18 @@ public:
return *this; return *this;
} }
/** Move assignment operator */
plStringBuffer<_Ch> &operator=(plStringBuffer<_Ch> &&move)
{
if (IHaveACow())
fData->DecRef();
memcpy(fShort, move.fShort, sizeof(fShort));
fSize = move.fSize;
move.fSize = 0;
return *this;
}
/** Returns a pointer to the referenced string buffer. */ /** Returns a pointer to the referenced string buffer. */
const _Ch *GetData() const { return IHaveACow() ? fData->fStringData : fShort; } const _Ch *GetData() const { return IHaveACow() ? fData->fStringData : fShort; }
@ -235,14 +254,15 @@ private:
void IConvertFromUtf32(const UniChar *ustr, 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:
// Constructing and comparing with nil or nullptr won't break plString, // Constructing and comparing with nil or nullptr won't break plString,
// but it's preferred not to do so with the constants. That is to say, // but it's preferred not to do so with the constants. That is to say,
// you can construct with a const char * which points to null, but // you can construct with a const char * which points to null, but
// don't actually write `plString foo = nil;` // don't actually write `plString foo = nil;`
plString(std::nullptr_t) { } plString(std::nullptr_t) = delete;
void operator=(std::nullptr_t) { } void operator=(std::nullptr_t) = delete;
void operator==(std::nullptr_t) const { } void operator==(std::nullptr_t) const = delete;
void operator!=(std::nullptr_t) const { } void operator!=(std::nullptr_t) const = delete;
public: public:
/** Construct a valid, empty string. */ /** Construct a valid, empty string. */
@ -254,27 +274,50 @@ public:
*/ */
plString(const char *cstr, size_t size = STRLEN_AUTO) { IConvertFromUtf8(cstr, size); } plString(const char *cstr, size_t size = STRLEN_AUTO) { IConvertFromUtf8(cstr, size); }
/** Construct a plString from a string literal.
* \note This constructor expects the input to be UTF-8 encoded. For
* conversion from ISO-8859-1 8-bit data, use FromIso8859_1().
*/
template <size_t _Sz>
plString(const char (&literal)[_Sz]) { IConvertFromUtf8(literal, _Sz); }
/** Copy constructor. */ /** Copy constructor. */
plString(const plString &copy) : fUtf8Buffer(copy.fUtf8Buffer) { } plString(const plString &copy) : fUtf8Buffer(copy.fUtf8Buffer) { }
/** Move constructor. */
plString(plString &&move) : fUtf8Buffer(std::move(move.fUtf8Buffer)) { }
/** Copy constructor from plStringBuffer<char>. /** Copy constructor from plStringBuffer<char>.
* \note This constructor expects the input to be UTF-8 encoded. For * \note This constructor expects the input to be UTF-8 encoded. For
* conversion from ISO-8859-1 8-bit data, use FromIso8859_1(). * conversion from ISO-8859-1 8-bit data, use FromIso8859_1().
*/ */
plString(const plStringBuffer<char> &init) { operator=(init); } plString(const plStringBuffer<char> &init) { operator=(init); }
/** Move constructor from plStringBuffer<char>. */
plString(plStringBuffer<char> &&init) { operator=(std::move(init)); }
/** Construct a string from expanded Unicode data. */ /** Construct a string from expanded Unicode data. */
plString(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); } plString(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); }
/** Assignment operator. Same as plString(const char *). */ /** Assignment operator. Same as plString(const char *). */
plString &operator=(const char *cstr) { IConvertFromUtf8(cstr, STRLEN_AUTO); return *this; } plString &operator=(const char *cstr) { IConvertFromUtf8(cstr, STRLEN_AUTO); return *this; }
/** Assignment operator. Same as plString(const char (&)[_Sz]). */
template <size_t _Sz>
plString &operator=(const char (&literal)[_Sz]) { IConvertFromUtf8(literal, _Sz); return *this; }
/** Assignment operator. Same as plString(const plString &). */ /** Assignment operator. Same as plString(const plString &). */
plString &operator=(const plString &copy) { fUtf8Buffer = copy.fUtf8Buffer; return *this; } plString &operator=(const plString &copy) { fUtf8Buffer = copy.fUtf8Buffer; return *this; }
/** Assignment operator. Same as plString(plString &&). */
plString &operator=(plString &&move) { fUtf8Buffer = std::move(move.fUtf8Buffer); return *this; }
/** Assignment operator. Same as plString(const plStringBuffer<char> &). */ /** Assignment operator. Same as plString(const plStringBuffer<char> &). */
plString &operator=(const plStringBuffer<char> &init); plString &operator=(const plStringBuffer<char> &init);
/** Assignment operator. Same as plString(plStringBuffer<char> &&). */
plString &operator=(plStringBuffer<char> &&init);
/** Assignment operator. Same as plString(const plUnicodeBuffer &). */ /** Assignment operator. Same as plString(const plUnicodeBuffer &). */
plString &operator=(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); return *this; } plString &operator=(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); return *this; }
@ -674,6 +717,27 @@ public:
/** Destructor, frees any allocated heap memory owned by the stream. */ /** Destructor, frees any allocated heap memory owned by the stream. */
~plStringStream() { if (ICanHasHeap()) delete [] fBuffer; } ~plStringStream() { if (ICanHasHeap()) delete [] fBuffer; }
plStringStream(const plStringStream &) = delete;
plStringStream &operator=(const plStringStream &) = delete;
/** Move operator */
plStringStream(plStringStream &&move)
: fBufSize(move.fBufSize), fLength(move.fLength)
{
memcpy(fShort, move.fShort, sizeof(fShort));
move.fBufSize = 0;
}
/** Move assignment operator. */
plStringStream &operator=(plStringStream &&move)
{
memcpy(fShort, move.fShort, sizeof(fShort));
fBufSize = move.fBufSize;
fLength = move.fLength;
move.fBufSize = 0;
return *this;
}
/** Append string data to the end of the stream. */ /** Append string data to the end of the stream. */
plStringStream &append(const char *data, size_t length); plStringStream &append(const char *data, size_t length);

Loading…
Cancel
Save