This source file includes following definitions.
- allocate
- copy
- buffer
- allocate
- copy
- internalNormalizeLineEndingsToCRLF
- normalizeToCROrLF
- normalizeLineEndingsToCRLF
- normalizeLineEndingsToCR
- normalizeLineEndingsToLF
- normalizeLineEndingsToNative
#include "config.h"
#include "platform/text/LineEnding.h"
#include "wtf/text/CString.h"
#include "wtf/text/WTFString.h"
namespace {
class OutputBuffer {
public:
virtual char* allocate(size_t) = 0;
virtual void copy(const CString&) = 0;
virtual ~OutputBuffer() { }
};
class CStringBuffer FINAL : public OutputBuffer {
public:
CStringBuffer(CString& buffer)
: m_buffer(buffer)
{
}
virtual ~CStringBuffer() { }
virtual char* allocate(size_t size) OVERRIDE
{
char* ptr;
m_buffer = CString::newUninitialized(size, ptr);
return ptr;
}
virtual void copy(const CString& source) OVERRIDE
{
m_buffer = source;
}
const CString& buffer() const { return m_buffer; }
private:
CString m_buffer;
};
class VectorCharAppendBuffer FINAL : public OutputBuffer {
public:
VectorCharAppendBuffer(Vector<char>& buffer)
: m_buffer(buffer)
{
}
virtual ~VectorCharAppendBuffer() { }
virtual char* allocate(size_t size) OVERRIDE
{
size_t oldSize = m_buffer.size();
m_buffer.grow(oldSize + size);
return m_buffer.data() + oldSize;
}
virtual void copy(const CString& source) OVERRIDE
{
m_buffer.append(source.data(), source.length());
}
private:
Vector<char>& m_buffer;
};
void internalNormalizeLineEndingsToCRLF(const CString& from, OutputBuffer& buffer)
{
size_t newLen = 0;
const char* p = from.data();
while (p < from.data() + from.length()) {
char c = *p++;
if (c == '\r') {
if (*p != '\n') {
newLen += 2;
}
} else if (c == '\n') {
newLen += 2;
} else {
newLen += 1;
}
}
if (newLen < from.length())
return;
if (newLen == from.length()) {
buffer.copy(from);
return;
}
p = from.data();
char* q = buffer.allocate(newLen);
while (p < from.data() + from.length()) {
char c = *p++;
if (c == '\r') {
if (*p != '\n') {
*q++ = '\r';
*q++ = '\n';
}
} else if (c == '\n') {
*q++ = '\r';
*q++ = '\n';
} else {
*q++ = c;
}
}
}
};
namespace WebCore {
void normalizeToCROrLF(const CString& from, Vector<char>& result, bool toCR);
void normalizeToCROrLF(const CString& from, Vector<char>& result, bool toCR)
{
size_t newLen = 0;
bool needFix = false;
const char* p = from.data();
char fromEndingChar = toCR ? '\n' : '\r';
char toEndingChar = toCR ? '\r' : '\n';
while (p < from.data() + from.length()) {
char c = *p++;
if (c == '\r' && *p == '\n') {
p++;
needFix = true;
} else if (c == fromEndingChar) {
needFix = true;
}
newLen += 1;
}
p = from.data();
size_t oldResultSize = result.size();
result.grow(oldResultSize + newLen);
char* q = result.data() + oldResultSize;
if (!needFix) {
memcpy(q, p, from.length());
return;
}
while (p < from.data() + from.length()) {
char c = *p++;
if (c == '\r' && *p == '\n') {
p++;
*q++ = toEndingChar;
} else if (c == fromEndingChar) {
*q++ = toEndingChar;
} else {
*q++ = c;
}
}
}
CString normalizeLineEndingsToCRLF(const CString& from)
{
if (!from.length())
return from;
CString result;
CStringBuffer buffer(result);
internalNormalizeLineEndingsToCRLF(from, buffer);
return buffer.buffer();
}
void normalizeLineEndingsToCR(const CString& from, Vector<char>& result)
{
normalizeToCROrLF(from, result, true);
}
void normalizeLineEndingsToLF(const CString& from, Vector<char>& result)
{
normalizeToCROrLF(from, result, false);
}
void normalizeLineEndingsToNative(const CString& from, Vector<char>& result)
{
#if OS(WIN)
VectorCharAppendBuffer buffer(result);
internalNormalizeLineEndingsToCRLF(from, buffer);
#else
normalizeLineEndingsToLF(from, result);
#endif
}
}