mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Merge pull request #253 from zrax/plString
Fix a major plStringStream bug, and add an SSO-like optimization to it.
This commit is contained in:
@ -501,11 +501,11 @@ double plString::ToDouble() const
|
|||||||
|
|
||||||
plString plString::IFormat(const char *fmt, va_list vptr)
|
plString plString::IFormat(const char *fmt, va_list vptr)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[STRING_STACK_SIZE];
|
||||||
va_list vptr_save;
|
va_list vptr_save;
|
||||||
va_copy(vptr_save, vptr);
|
va_copy(vptr_save, vptr);
|
||||||
|
|
||||||
int chars = vsnprintf(buffer, 256, fmt, vptr);
|
int chars = vsnprintf(buffer, STRING_STACK_SIZE, fmt, vptr);
|
||||||
if (chars < 0) {
|
if (chars < 0) {
|
||||||
// We will need to try this multiple times until we get a
|
// We will need to try this multiple times until we get a
|
||||||
// large enough buffer :(
|
// large enough buffer :(
|
||||||
@ -522,9 +522,8 @@ plString plString::IFormat(const char *fmt, va_list vptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size *= 2;
|
size *= 2;
|
||||||
hsAssert(size > 0, "Formatted string output is waaaaay too long");
|
|
||||||
}
|
}
|
||||||
} else if (chars >= 256) {
|
} else if (chars >= STRING_STACK_SIZE) {
|
||||||
va_copy(vptr, vptr_save);
|
va_copy(vptr, vptr_save);
|
||||||
plStringBuffer<char> bigbuffer;
|
plStringBuffer<char> bigbuffer;
|
||||||
char *data = bigbuffer.CreateWritableBuffer(chars);
|
char *data = bigbuffer.CreateWritableBuffer(chars);
|
||||||
@ -823,14 +822,24 @@ plString operator+(const char *left, const plString &right)
|
|||||||
|
|
||||||
plStringStream &plStringStream::append(const char *data, size_t length)
|
plStringStream &plStringStream::append(const char *data, size_t length)
|
||||||
{
|
{
|
||||||
if (fLength + length > fBufSize) {
|
size_t bufSize = ICanHasHeap() ? fBufSize : STRING_STACK_SIZE;
|
||||||
char *bigger = new char[fBufSize * 2];
|
char *bufp = ICanHasHeap() ? fBuffer : fShort;
|
||||||
memcpy(bigger, fBuffer, fBufSize);
|
|
||||||
delete [] fBuffer;
|
if (fLength + length > bufSize) {
|
||||||
fBuffer = bigger;
|
size_t bigSize = bufSize;
|
||||||
fBufSize *= 2;
|
do {
|
||||||
|
bigSize *= 2;
|
||||||
|
} while (fLength + length > bigSize);
|
||||||
|
|
||||||
|
char *bigger = new char[bigSize];
|
||||||
|
memcpy(bigger, GetRawBuffer(), bufSize);
|
||||||
|
if (ICanHasHeap())
|
||||||
|
delete [] fBuffer;
|
||||||
|
fBuffer = bufp = bigger;
|
||||||
|
fBufSize = bigSize;
|
||||||
}
|
}
|
||||||
memcpy(fBuffer + fLength, data, length);
|
|
||||||
|
memcpy(bufp + fLength, data, length);
|
||||||
fLength += length;
|
fLength += length;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -855,6 +864,13 @@ plStringStream &plStringStream::operator<<(unsigned int num)
|
|||||||
return operator<<(buffer);
|
return operator<<(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plStringStream &plStringStream::operator<<(double num)
|
||||||
|
{
|
||||||
|
char buffer[64];
|
||||||
|
snprintf(buffer, 64, "%f", num);
|
||||||
|
return operator<<(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
size_t ustrlen(const UniChar *ustr, size_t max)
|
size_t ustrlen(const UniChar *ustr, size_t max)
|
||||||
{
|
{
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
|
@ -49,6 +49,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
typedef unsigned int UniChar;
|
typedef unsigned int UniChar;
|
||||||
|
|
||||||
#define SSO_CHARS (16)
|
#define SSO_CHARS (16)
|
||||||
|
#define STRING_STACK_SIZE (256)
|
||||||
#define WHITESPACE_CHARS " \t\n\r"
|
#define WHITESPACE_CHARS " \t\n\r"
|
||||||
|
|
||||||
template <typename _Ch>
|
template <typename _Ch>
|
||||||
@ -343,17 +344,16 @@ plString operator+(const char *left, const plString &right);
|
|||||||
class plStringStream
|
class plStringStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
plStringStream() : fBufSize(256), fLength(0)
|
plStringStream() : fLength(0) { }
|
||||||
{
|
~plStringStream() { if (ICanHasHeap()) delete [] fBuffer; }
|
||||||
fBuffer = new char[fBufSize];
|
|
||||||
}
|
|
||||||
~plStringStream() { delete [] fBuffer; }
|
|
||||||
|
|
||||||
plStringStream &append(const char *data, size_t length);
|
plStringStream &append(const char *data, size_t length);
|
||||||
|
|
||||||
plStringStream &operator<<(const char *text);
|
plStringStream &operator<<(const char *text);
|
||||||
plStringStream &operator<<(int num);
|
plStringStream &operator<<(int num);
|
||||||
plStringStream &operator<<(unsigned int num);
|
plStringStream &operator<<(unsigned int num);
|
||||||
|
plStringStream &operator<<(float num) { return operator<<(static_cast<double>(num)); }
|
||||||
|
plStringStream &operator<<(double num);
|
||||||
plStringStream &operator<<(char ch) { return append(&ch, 1); }
|
plStringStream &operator<<(char ch) { return append(&ch, 1); }
|
||||||
|
|
||||||
plStringStream &operator<<(const plString &text)
|
plStringStream &operator<<(const plString &text)
|
||||||
@ -361,13 +361,25 @@ public:
|
|||||||
return append(text.c_str(), text.GetSize());
|
return append(text.c_str(), text.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *GetRawBuffer() const // WARNING: Not null-terminated!
|
||||||
|
{
|
||||||
|
return ICanHasHeap() ? fBuffer : fShort;
|
||||||
|
}
|
||||||
|
|
||||||
size_t GetLength() const { return fLength; }
|
size_t GetLength() const { return fLength; }
|
||||||
plString GetString() { return plString::FromUtf8(fBuffer, fLength); }
|
plString GetString() { return plString::FromUtf8(GetRawBuffer(), fLength); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *fBuffer;
|
union {
|
||||||
size_t fBufSize;
|
struct {
|
||||||
|
char *fBuffer;
|
||||||
|
size_t fBufSize;
|
||||||
|
};
|
||||||
|
char fShort[STRING_STACK_SIZE];
|
||||||
|
};
|
||||||
size_t fLength;
|
size_t fLength;
|
||||||
|
|
||||||
|
bool ICanHasHeap() const { return fLength > STRING_STACK_SIZE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t ustrlen(const UniChar *ustr, size_t max = plString::kSizeAuto);
|
size_t ustrlen(const UniChar *ustr, size_t max = plString::kSizeAuto);
|
||||||
|
Reference in New Issue
Block a user