#include "CXMLWriter.h"
#include <wchar.h>
#include "irrString.h"
#include "IrrCompileConfig.h"
namespace irr
{
namespace io
{
CXMLWriter::CXMLWriter(IWriteFile* file)
: File(file), Tabs(0), TextWrittenLast(false)
{
#ifdef _DEBUG
setDebugName("CXMLWriter");
#endif
if (File)
File->grab();
}
CXMLWriter::~CXMLWriter()
{
if (File)
File->drop();
}
void CXMLWriter::writeXMLHeader()
{
if (!File)
return;
if (sizeof(wchar_t)==2)
{
const u16 h = 0xFEFF;
File->write(&h, 2);
}
else
{
const u32 h = 0x0000FEFF;
File->write(&h, sizeof(wchar_t));
}
const wchar_t* const p = L"<?xml version=\"1.0\"?>";
File->write(p, wcslen(p)*sizeof(wchar_t));
writeLineBreak();
TextWrittenLast = false;
}
void CXMLWriter::writeElement(const wchar_t* name, bool empty,
const wchar_t* attr1Name, const wchar_t* attr1Value,
const wchar_t* attr2Name, const wchar_t* attr2Value,
const wchar_t* attr3Name, const wchar_t* attr3Value,
const wchar_t* attr4Name, const wchar_t* attr4Value,
const wchar_t* attr5Name, const wchar_t* attr5Value)
{
if (!File || !name)
return;
if (Tabs > 0)
{
for (int i=0; i<Tabs; ++i)
File->write(L"\t", sizeof(wchar_t));
}
File->write(L"<", sizeof(wchar_t));
File->write(name, wcslen(name)*sizeof(wchar_t));
writeAttribute(attr1Name, attr1Value);
writeAttribute(attr2Name, attr2Value);
writeAttribute(attr3Name, attr3Value);
writeAttribute(attr4Name, attr4Value);
writeAttribute(attr5Name, attr5Value);
if (empty)
File->write(L" />", 3*sizeof(wchar_t));
else
{
File->write(L">", sizeof(wchar_t));
++Tabs;
}
TextWrittenLast = false;
}
void CXMLWriter::writeElement(const wchar_t* name, bool empty,
core::array<core::stringw> &names,
core::array<core::stringw> &values)
{
if (!File || !name)
return;
if (Tabs > 0)
{
for (int i=0; i<Tabs; ++i)
File->write(L"\t", sizeof(wchar_t));
}
File->write(L"<", sizeof(wchar_t));
File->write(name, wcslen(name)*sizeof(wchar_t));
u32 i=0;
for (; i < names.size() && i < values.size(); ++i)
writeAttribute(names[i].c_str(), values[i].c_str());
if (empty)
File->write(L" />", 3*sizeof(wchar_t));
else
{
File->write(L">", sizeof(wchar_t));
++Tabs;
}
TextWrittenLast = false;
}
void CXMLWriter::writeAttribute(const wchar_t* name, const wchar_t* value)
{
if (!name || !value)
return;
File->write(L" ", sizeof(wchar_t));
File->write(name, wcslen(name)*sizeof(wchar_t));
File->write(L"=\"", 2*sizeof(wchar_t));
writeText(value);
File->write(L"\"", sizeof(wchar_t));
}
void CXMLWriter::writeComment(const wchar_t* comment)
{
if (!File || !comment)
return;
File->write(L"<!--", 4*sizeof(wchar_t));
writeText(comment);
File->write(L"-->", 3*sizeof(wchar_t));
}
void CXMLWriter::writeClosingTag(const wchar_t* name)
{
if (!File || !name)
return;
--Tabs;
if (Tabs > 0 && !TextWrittenLast)
{
for (int i=0; i<Tabs; ++i)
File->write(L"\t", sizeof(wchar_t));
}
File->write(L"</", 2*sizeof(wchar_t));
File->write(name, wcslen(name)*sizeof(wchar_t));
File->write(L">", sizeof(wchar_t));
TextWrittenLast = false;
}
const CXMLWriter::XMLSpecialCharacters XMLWSChar[] =
{
{ L'&', L"&" },
{ L'<', L"<" },
{ L'>', L">" },
{ L'"', L""" },
{ L'\0', 0 }
};
void CXMLWriter::writeText(const wchar_t* text)
{
if (!File || !text)
return;
core::stringw s;
const wchar_t* p = text;
while(*p)
{
bool found = false;
for (s32 i=0; XMLWSChar[i].Character != '\0'; ++i)
if (*p == XMLWSChar[i].Character)
{
s.append(XMLWSChar[i].Symbol);
found = true;
break;
}
if (!found)
s.append(*p);
++p;
}
File->write(s.c_str(), s.size()*sizeof(wchar_t));
TextWrittenLast = true;
}
void CXMLWriter::writeLineBreak()
{
if (!File)
return;
#if defined(_IRR_OSX_PLATFORM_)
File->write(L"\r", sizeof(wchar_t));
#elif defined(_IRR_WINDOWS_API_)
File->write(L"\r\n", 2*sizeof(wchar_t));
#else
File->write(L"\n", sizeof(wchar_t));
#endif
}
}
}