/*-------------------------------------------------------------------------
 * drawElements Quality Program Test Executor
 * ------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief XML Writer.
 *//*--------------------------------------------------------------------*/

#include "xeXMLWriter.hpp"

#include <cstring>

namespace xe
{
namespace xml
{

const Writer::EndElementType Writer::EndElement = Writer::EndElementType();

inline const char* getEscapeEntity (char ch)
{
	switch (ch)
	{
		case '<':	return "&lt;";
		case '>':	return "&gt;";
		case '&':	return "&amp;";
		case '\'':	return "&apos;";
		case '"':	return "&quot;";

		// Non-printable characters.
		case 0:		return "&lt;NUL&gt;";
		case 1:		return "&lt;SOH&gt;";
		case 2:		return "&lt;STX&gt;";
		case 3:		return "&lt;ETX&gt;";
		case 4:		return "&lt;EOT&gt;";
		case 5:		return "&lt;ENQ&gt;";
		case 6:		return "&lt;ACK&gt;";
		case 7:		return "&lt;BEL&gt;";
		case 8:		return "&lt;BS&gt;";
		case 11:	return "&lt;VT&gt;";
		case 12:	return "&lt;FF&gt;";
		case 14:	return "&lt;SO&gt;";
		case 15:	return "&lt;SI&gt;";
		case 16:	return "&lt;DLE&gt;";
		case 17:	return "&lt;DC1&gt;";
		case 18:	return "&lt;DC2&gt;";
		case 19:	return "&lt;DC3&gt;";
		case 20:	return "&lt;DC4&gt;";
		case 21:	return "&lt;NAK&gt;";
		case 22:	return "&lt;SYN&gt;";
		case 23:	return "&lt;ETB&gt;";
		case 24:	return "&lt;CAN&gt;";
		case 25:	return "&lt;EM&gt;";
		case 26:	return "&lt;SUB&gt;";
		case 27:	return "&lt;ESC&gt;";
		case 28:	return "&lt;FS&gt;";
		case 29:	return "&lt;GS&gt;";
		case 30:	return "&lt;RS&gt;";
		case 31:	return "&lt;US&gt;";

		default:	return DE_NULL;
	}
}

std::streamsize EscapeStreambuf::xsputn (const char* s, std::streamsize count)
{
	std::streamsize	numWritten = 0;

	for (std::streamsize inPos = 0; inPos < count; inPos++)
	{
		const char* entity = getEscapeEntity(s[inPos]);

		if (entity)
		{
			// Flush data prior to entity.
			if (inPos > numWritten)
			{
				m_dst.write(s + numWritten, inPos-numWritten);
				if (m_dst.fail())
					return numWritten;
			}

			// Flush entity value
			m_dst.write(entity, (std::streamsize)strlen(entity));

			numWritten = inPos+1;
		}
	}

	if (numWritten < count)
	{
		m_dst.write(s + numWritten, count-numWritten);
		if (m_dst.fail())
			return numWritten;
	}

	return count;
}

int EscapeStreambuf::overflow (int ch)
{
	if (ch == -1)
		return -1;
	else
	{
		DE_ASSERT((ch & 0xff) == ch);
		const char chVal = (char)(deUint8)(ch & 0xff);
		return xsputn(&chVal, 1) == 1 ? ch : -1;
	}
}

Writer::Writer (std::ostream& dst)
	: m_rawDst	(dst)
	, m_dataBuf	(dst)
	, m_dataStr	(&m_dataBuf)
	, m_state	(STATE_DATA)
{
}

Writer::~Writer (void)
{
}

Writer& Writer::operator<< (const BeginElement& begin)
{
	if (m_state == STATE_ELEMENT)
		m_rawDst << ">";

	if (m_state == STATE_ELEMENT || m_state == STATE_ELEMENT_END)
	{
		m_rawDst << "\n";
		for (int i = 0; i < (int)m_elementStack.size(); i++)
			m_rawDst << "  ";
	}

	m_rawDst << "<" << begin.element;

	m_elementStack.push_back(begin.element);
	m_state = STATE_ELEMENT;

	return *this;
}

Writer& Writer::operator<< (const Attribute& attribute)
{
	DE_ASSERT(m_state == STATE_ELEMENT);

	// \todo [2012-09-05 pyry] Escape?
	m_rawDst << " " << attribute.name << "=\"" << attribute.value << "\"";

	return *this;
}

Writer& Writer::operator<< (const EndElementType&)
{
	if (m_state == STATE_ELEMENT)
		m_rawDst << "/>";
	else
	{
		if (m_state == STATE_ELEMENT_END)
		{
			m_rawDst << "\n";
			for (int i = 0; i < (int)m_elementStack.size()-1; i++)
				m_rawDst << "  ";
		}

		m_rawDst << "</" << m_elementStack.back() << ">";
	}

	m_elementStack.pop_back();
	m_state = STATE_ELEMENT_END;

	return *this;
}

} // xml
} // xe
