mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Fix a major plStringStream bug, and add an SSO-like optimization to it
This commit is contained in:
@ -800,14 +800,25 @@ plString operator+(const char *left, const plString &right)
|
||||
|
||||
plStringStream &plStringStream::append(const char *data, size_t length)
|
||||
{
|
||||
if (fLength + length > fBufSize) {
|
||||
char *bigger = new char[fBufSize * 2];
|
||||
memcpy(bigger, fBuffer, fBufSize);
|
||||
delete [] fBuffer;
|
||||
fBuffer = bigger;
|
||||
fBufSize *= 2;
|
||||
size_t bufSize = ICanHasHeap() ? fBufSize : 256;
|
||||
char *bufp = ICanHasHeap() ? fBuffer : fShort;
|
||||
|
||||
if (fLength + length > bufSize) {
|
||||
size_t bigSize = bufSize;
|
||||
do {
|
||||
hsAssert(bigSize * 2, "plStringStream buffer too large");
|
||||
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;
|
||||
return *this;
|
||||
}
|
||||
@ -832,6 +843,13 @@ plStringStream &plStringStream::operator<<(unsigned int num)
|
||||
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 length = 0;
|
||||
|
@ -341,17 +341,19 @@ plString operator+(const char *left, const plString &right);
|
||||
class plStringStream
|
||||
{
|
||||
public:
|
||||
plStringStream() : fBufSize(256), fLength(0)
|
||||
plStringStream() : fLength(0)
|
||||
{
|
||||
fBuffer = new char[fBufSize];
|
||||
fShort[0] = 0;
|
||||
}
|
||||
~plStringStream() { delete [] fBuffer; }
|
||||
~plStringStream() { if (ICanHasHeap()) delete [] fBuffer; }
|
||||
|
||||
plStringStream &append(const char *data, size_t length);
|
||||
|
||||
plStringStream &operator<<(const char *text);
|
||||
plStringStream &operator<<(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<<(const plString &text)
|
||||
@ -359,13 +361,25 @@ public:
|
||||
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; }
|
||||
plString GetString() { return plString::FromUtf8(fBuffer, fLength); }
|
||||
plString GetString() { return plString::FromUtf8(GetRawBuffer(), fLength); }
|
||||
|
||||
private:
|
||||
char *fBuffer;
|
||||
size_t fBufSize;
|
||||
union {
|
||||
struct {
|
||||
char *fBuffer;
|
||||
size_t fBufSize;
|
||||
};
|
||||
char fShort[256];
|
||||
};
|
||||
size_t fLength;
|
||||
|
||||
bool ICanHasHeap() const { return fLength > 256; }
|
||||
};
|
||||
|
||||
size_t ustrlen(const UniChar *ustr, size_t max = plString::kSizeAuto);
|
||||
|
Reference in New Issue
Block a user