#include "config.h"
#include "StringBuilder.h"
using namespace std;
namespace WebCore {
static inline void checkedAppend(unsigned& totalLength, unsigned charactersToAppend)
{
if (numeric_limits<unsigned>::max() - charactersToAppend <= totalLength)
CRASH();
totalLength += charactersToAppend;
}
void StringBuilder::append(const String& string)
{
if (string.isNull())
return;
unsigned totalLength = length();
checkedAppend(totalLength, string.length());
m_totalLength = totalLength;
if (!string.isEmpty())
m_strings.append(string);
}
void StringBuilder::append(UChar c)
{
unsigned totalLength = length();
checkedAppend(totalLength, 1);
m_totalLength = totalLength;
m_strings.append(String(&c, 1));
}
void StringBuilder::append(char c)
{
unsigned totalLength = length();
checkedAppend(totalLength, 1);
m_totalLength = totalLength;
m_strings.append(String(&c, 1));
}
String StringBuilder::toString() const
{
if (isNull())
return String();
unsigned count = m_strings.size();
if (!count)
return String(StringImpl::empty());
if (count == 1)
return m_strings[0];
UChar* buffer;
String result = String::createUninitialized(m_totalLength, buffer);
UChar* p = buffer;
for (unsigned i = 0; i < count; ++i) {
StringImpl* string = m_strings[i].impl();
unsigned length = string->length();
memcpy(p, string->characters(), length * sizeof(UChar));
p += length;
}
ASSERT(p == m_totalLength + buffer);
return result;
}
void StringBuilder::clear()
{
m_totalLength = numeric_limits<unsigned>::max();
m_strings.clear();
}
unsigned StringBuilder::length() const
{
if (isNull())
return 0;
return m_totalLength;
}
}