/*-------------------------------------------------------------------------
 * 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 Test case result parser.
 *//*--------------------------------------------------------------------*/

#include "xeTestResultParser.hpp"
#include "xeTestCaseResult.hpp"
#include "xeBatchResult.hpp"
#include "deString.h"
#include "deInt32.h"

#include <sstream>
#include <stdlib.h>

using std::string;
using std::vector;

namespace xe
{

static inline int toInt (const char* str)
{
	return atoi(str);
}

static inline double toDouble (const char* str)
{
	return atof(str);
}

static inline deInt64 toInt64 (const char* str)
{
	std::istringstream	s	(str);
	deInt64				val;

	s >> val;

	return val;
}

static inline bool toBool (const char* str)
{
	return deStringEqual(str, "OK") || deStringEqual(str, "True");
}

static const char* stripLeadingWhitespace (const char* str)
{
	int whitespaceCount = 0;

	while (str[whitespaceCount]	!= 0	&&
		   (str[whitespaceCount] == ' '		||
			str[whitespaceCount] == '\t'	||
			str[whitespaceCount] == '\r'	||
			str[whitespaceCount] == '\n'))
		whitespaceCount += 1;

	return str + whitespaceCount;
}

struct EnumMapEntry
{
	deUint32		hash;
	const char*		name;
	int				value;
};

static const EnumMapEntry s_statusCodeMap[] =
{
	{ 0x7c8a99bc,	"Pass",					TESTSTATUSCODE_PASS						},
	{ 0x7c851ca1,	"Fail",					TESTSTATUSCODE_FAIL						},
	{ 0x10ecd324,	"QualityWarning",		TESTSTATUSCODE_QUALITY_WARNING			},
	{ 0x341ae835,	"CompatibilityWarning",	TESTSTATUSCODE_COMPATIBILITY_WARNING	},
	{ 0x058acbca,	"Pending",				TESTSTATUSCODE_PENDING					},
	{ 0xc4d74b26,	"Running",				TESTSTATUSCODE_RUNNING					},
	{ 0x6409f93c,	"NotSupported",			TESTSTATUSCODE_NOT_SUPPORTED			},
	{ 0xfa5a9ab7,	"ResourceError",		TESTSTATUSCODE_RESOURCE_ERROR			},
	{ 0xad6793ec,	"InternalError",		TESTSTATUSCODE_INTERNAL_ERROR			},
	{ 0x838f3034,	"Canceled",				TESTSTATUSCODE_CANCELED					},
	{ 0x42b6efac,	"Timeout",				TESTSTATUSCODE_TIMEOUT					},
	{ 0x0cfb98f6,	"Crash",				TESTSTATUSCODE_CRASH					},
	{ 0xe326e01d,	"Disabled",				TESTSTATUSCODE_DISABLED					},
	{ 0x77061af2,	"Terminated",			TESTSTATUSCODE_TERMINATED				},
	{ 0xd9e6b393,	"Waiver",			    TESTSTATUSCODE_WAIVER				    }
};

static const EnumMapEntry s_resultItemMap[] =
{
	{ 0xce8ac2e4,	"Result",				ri::TYPE_RESULT			},
	{ 0x7c8cdcea,	"Text",					ri::TYPE_TEXT			},
	{ 0xc6540c6e,	"Number",				ri::TYPE_NUMBER			},
	{ 0x0d656c88,	"Image",				ri::TYPE_IMAGE			},
	{ 0x8ac9ee14,	"ImageSet",				ri::TYPE_IMAGESET		},
	{ 0x1181fa5a,	"VertexShader",			ri::TYPE_SHADER			},
	{ 0xa93daef0,	"FragmentShader",		ri::TYPE_SHADER			},
	{ 0x8f066128,	"GeometryShader",		ri::TYPE_SHADER			},
	{ 0x235a931c,	"TessControlShader",	ri::TYPE_SHADER			},
	{ 0xa1bf7153,	"TessEvaluationShader",	ri::TYPE_SHADER			},
	{ 0x6c1415d9,	"ComputeShader",		ri::TYPE_SHADER			},
	{ 0x68738b22,	"RaygenShader",			ri::TYPE_SHADER			},
	{ 0x51d29ce9,	"AnyHitShader",			ri::TYPE_SHADER			},
	{ 0x8c64a6be,	"ClosestHitShader",		ri::TYPE_SHADER			},
	{ 0xb30ed398,	"MissShader",			ri::TYPE_SHADER			},
	{ 0x26150e53,	"IntersectionShader",	ri::TYPE_SHADER			},
	{ 0x7e50944c,	"CallableShader",		ri::TYPE_SHADER			},
	{ 0x72863a54,	"ShaderProgram",		ri::TYPE_SHADERPROGRAM	},
	{ 0xb4efc08d,	"ShaderSource",			ri::TYPE_SHADERSOURCE	},
	{ 0xaee4380a,	"SpirVAssemblySource",	ri::TYPE_SPIRVSOURCE	},
	{ 0xff265913,	"InfoLog",				ri::TYPE_INFOLOG		},
	{ 0x84159b73,	"EglConfig",			ri::TYPE_EGLCONFIG		},
	{ 0xdd34391f,	"EglConfigSet",			ri::TYPE_EGLCONFIGSET	},
	{ 0xebbb3aba,	"Section",				ri::TYPE_SECTION		},
	{ 0xa0f15677,	"KernelSource",			ri::TYPE_KERNELSOURCE	},
	{ 0x1ee9083a,	"CompileInfo",			ri::TYPE_COMPILEINFO	},
	{ 0xf1004023,	"SampleList",			ri::TYPE_SAMPLELIST		},
	{ 0xf0feae93,	"SampleInfo",			ri::TYPE_SAMPLEINFO		},
	{ 0x2aa6f14e,	"ValueInfo",			ri::TYPE_VALUEINFO		},
	{ 0xd09429e7,	"Sample",				ri::TYPE_SAMPLE			},
	{ 0x0e4a4722,	"Value",				ri::TYPE_SAMPLEVALUE	}
};

static const EnumMapEntry s_imageFormatMap[] =
{
	{ 0xcc4ffac8,	"RGB888",		ri::Image::FORMAT_RGB888	},
	{ 0x20dcb0c1,	"RGBA8888",		ri::Image::FORMAT_RGBA8888	}
};

static const EnumMapEntry s_compressionMap[] =
{
	{ 0x7c89bbd5,	"None",			ri::Image::COMPRESSION_NONE	},
	{ 0x0b88118a,	"PNG",			ri::Image::COMPRESSION_PNG	}
};

static const EnumMapEntry s_shaderTypeFromTagMap[] =
{
	{ 0x1181fa5a,	"VertexShader",			ri::Shader::SHADERTYPE_VERTEX			},
	{ 0xa93daef0,	"FragmentShader",		ri::Shader::SHADERTYPE_FRAGMENT			},
	{ 0x8f066128,	"GeometryShader",		ri::Shader::SHADERTYPE_GEOMETRY			},
	{ 0x235a931c,	"TessControlShader",	ri::Shader::SHADERTYPE_TESS_CONTROL		},
	{ 0xa1bf7153,	"TessEvaluationShader",	ri::Shader::SHADERTYPE_TESS_EVALUATION	},
	{ 0x6c1415d9,	"ComputeShader",		ri::Shader::SHADERTYPE_COMPUTE			},
	{ 0x68738b22,	"RaygenShader",			ri::Shader::SHADERTYPE_RAYGEN			},
	{ 0x51d29ce9,	"AnyHitShader",			ri::Shader::SHADERTYPE_ANY_HIT			},
	{ 0x8c64a6be,	"ClosestHitShader",		ri::Shader::SHADERTYPE_CLOSEST_HIT		},
	{ 0xb30ed398,	"MissShader",			ri::Shader::SHADERTYPE_MISS				},
	{ 0x26150e53,	"IntersectionShader",	ri::Shader::SHADERTYPE_INTERSECTION		},
	{ 0x7e50944c,	"CallableShader",		ri::Shader::SHADERTYPE_CALLABLE			}
};

static const EnumMapEntry s_testTypeMap[] =
{
	{ 0x7fa80959,	"SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
	{ 0xdb797567,	"Capability",	TESTCASETYPE_CAPABILITY		},
	{ 0x2ca3ec10,	"Accuracy",		TESTCASETYPE_ACCURACY		},
	{ 0xa48ac277,	"Performance",	TESTCASETYPE_PERFORMANCE	}
};

static const EnumMapEntry s_logVersionMap[] =
{
	{ 0x0b7dac93,	"0.2.0",		TESTLOGVERSION_0_2_0	},
	{ 0x0b7db0d4,	"0.3.0",		TESTLOGVERSION_0_3_0	},
	{ 0x0b7db0d5,	"0.3.1",		TESTLOGVERSION_0_3_1	},
	{ 0x0b7db0d6,	"0.3.2",		TESTLOGVERSION_0_3_2	},
	{ 0x0b7db0d7,	"0.3.3",		TESTLOGVERSION_0_3_3	},
	{ 0x0b7db0d8,	"0.3.4",		TESTLOGVERSION_0_3_4	}
};

static const EnumMapEntry s_sampleValueTagMap[] =
{
	{ 0xddf2d0d1,	"Predictor",	ri::ValueInfo::VALUETAG_PREDICTOR	},
	{ 0x9bee2c34,	"Response",		ri::ValueInfo::VALUETAG_RESPONSE	},
};

#if defined(DE_DEBUG)
static void printHashes (const char* name, const EnumMapEntry* entries, int numEntries)
{
	printf("%s:\n", name);

	for (int ndx = 0; ndx < numEntries; ndx++)
		printf("0x%08x\t%s\n", deStringHash(entries[ndx].name), entries[ndx].name);

	printf("\n");
}

#define PRINT_HASHES(MAP) printHashes(#MAP, MAP, DE_LENGTH_OF_ARRAY(MAP))

void TestResultParser_printHashes (void)
{
	PRINT_HASHES(s_statusCodeMap);
	PRINT_HASHES(s_resultItemMap);
	PRINT_HASHES(s_imageFormatMap);
	PRINT_HASHES(s_compressionMap);
	PRINT_HASHES(s_shaderTypeFromTagMap);
	PRINT_HASHES(s_testTypeMap);
	PRINT_HASHES(s_logVersionMap);
	PRINT_HASHES(s_sampleValueTagMap);
}
#endif

static inline int getEnumValue (const char* enumName, const EnumMapEntry* entries, int numEntries, const char* name)
{
	deUint32 hash = deStringHash(name);

	for (int ndx = 0; ndx < numEntries; ndx++)
	{
		if (entries[ndx].hash == hash && deStringEqual(entries[ndx].name, name))
			return entries[ndx].value;
	}

	throw TestResultParseError(string("Could not map '") + name + "' to " + enumName);
}

TestStatusCode getTestStatusCode (const char* statusCode)
{
	return (TestStatusCode)getEnumValue("status code", s_statusCodeMap, DE_LENGTH_OF_ARRAY(s_statusCodeMap), statusCode);
}

static ri::Type getResultItemType (const char* elemName)
{
	return (ri::Type)getEnumValue("result item type", s_resultItemMap, DE_LENGTH_OF_ARRAY(s_resultItemMap), elemName);
}

static ri::Image::Format getImageFormat (const char* imageFormat)
{
	return (ri::Image::Format)getEnumValue("image format", s_imageFormatMap, DE_LENGTH_OF_ARRAY(s_imageFormatMap), imageFormat);
}

static ri::Image::Compression getImageCompression (const char* compression)
{
	return (ri::Image::Compression)getEnumValue("image compression", s_compressionMap, DE_LENGTH_OF_ARRAY(s_compressionMap), compression);
}

static ri::Shader::ShaderType getShaderTypeFromTagName (const char* shaderType)
{
	return (ri::Shader::ShaderType)getEnumValue("shader type", s_shaderTypeFromTagMap, DE_LENGTH_OF_ARRAY(s_shaderTypeFromTagMap), shaderType);
}

static TestCaseType getTestCaseType (const char* caseType)
{
	return (TestCaseType)getEnumValue("test case type", s_testTypeMap, DE_LENGTH_OF_ARRAY(s_testTypeMap), caseType);
}

static TestLogVersion getTestLogVersion (const char* logVersion)
{
	return (TestLogVersion)getEnumValue("test log version", s_logVersionMap, DE_LENGTH_OF_ARRAY(s_logVersionMap), logVersion);
}

static ri::ValueInfo::ValueTag getSampleValueTag (const char* tag)
{
	return (ri::ValueInfo::ValueTag)getEnumValue("sample value tag", s_sampleValueTagMap, DE_LENGTH_OF_ARRAY(s_sampleValueTagMap), tag);
}

static TestCaseType getTestCaseTypeFromPath (const char* casePath)
{
	if (deStringBeginsWith(casePath, "dEQP-GLES2."))
	{
		const char* group = casePath+11;
		if (deStringBeginsWith(group, "capability."))
			return TESTCASETYPE_CAPABILITY;
		else if (deStringBeginsWith(group, "accuracy."))
			return TESTCASETYPE_ACCURACY;
		else if (deStringBeginsWith(group, "performance."))
			return TESTCASETYPE_PERFORMANCE;
	}

	return TESTCASETYPE_SELF_VALIDATE;
}

static ri::NumericValue getNumericValue (const std::string& value)
{
	const bool	isFloat		= value.find('.') != std::string::npos || value.find('e') != std::string::npos;

	if (isFloat)
	{
		const double num = toDouble(stripLeadingWhitespace(value.c_str()));
		return ri::NumericValue(num);
	}
	else
	{
		const deInt64 num = toInt64(stripLeadingWhitespace(value.c_str()));
		return ri::NumericValue(num);
	}
}

TestResultParser::TestResultParser (void)
	: m_result				(DE_NULL)
	, m_state				(STATE_NOT_INITIALIZED)
	, m_logVersion			(TESTLOGVERSION_LAST)
	, m_curItemList			(DE_NULL)
	, m_base64DecodeOffset	(0)
{
}

TestResultParser::~TestResultParser (void)
{
}

void TestResultParser::clear (void)
{
	m_xmlParser.clear();
	m_itemStack.clear();

	m_result				= DE_NULL;
	m_state					= STATE_NOT_INITIALIZED;
	m_logVersion			= TESTLOGVERSION_LAST;
	m_curItemList			= DE_NULL;
	m_base64DecodeOffset	= 0;
	m_curNumValue.clear();
}

void TestResultParser::init (TestCaseResult* dstResult)
{
	clear();
	m_result		= dstResult;
	m_state			= STATE_INITIALIZED;
	m_curItemList	= &dstResult->resultItems;
}

TestResultParser::ParseResult TestResultParser::parse (const deUint8* bytes, int numBytes)
{
	DE_ASSERT(m_result && m_state != STATE_NOT_INITIALIZED);

	try
	{
		bool resultChanged = false;

		m_xmlParser.feed(bytes, numBytes);

		for (;;)
		{
			xml::Element curElement = m_xmlParser.getElement();

			if (curElement == xml::ELEMENT_INCOMPLETE	||
				curElement == xml::ELEMENT_END_OF_STRING)
				break;

			switch (curElement)
			{
				case xml::ELEMENT_START:	handleElementStart();		break;
				case xml::ELEMENT_END:		handleElementEnd();			break;
				case xml::ELEMENT_DATA:		handleData();				break;

				default:
					DE_ASSERT(false);
			}

			resultChanged = true;
			m_xmlParser.advance();
		}

		if (m_xmlParser.getElement() == xml::ELEMENT_END_OF_STRING)
		{
			if (m_state != STATE_TEST_CASE_RESULT_ENDED)
				throw TestResultParseError("Unexpected end of log data");

			return PARSERESULT_COMPLETE;
		}
		else
			return resultChanged ? PARSERESULT_CHANGED
								 : PARSERESULT_NOT_CHANGED;
	}
	catch (const TestResultParseError& e)
	{
		// Set error code to result.
		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
		m_result->statusDetails	= e.what();

		return PARSERESULT_ERROR;
	}
	catch (const xml::ParseError& e)
	{
		// Set error code to result.
		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
		m_result->statusDetails	= e.what();

		return PARSERESULT_ERROR;
	}
}

const char* TestResultParser::getAttribute (const char* name)
{
	if (!m_xmlParser.hasAttribute(name))
		throw TestResultParseError(string("Missing attribute '") + name + "' in <" + m_xmlParser.getElementName() + ">");

	return m_xmlParser.getAttribute(name);
}

ri::Item* TestResultParser::getCurrentItem (void)
{
	return !m_itemStack.empty() ? m_itemStack.back() : DE_NULL;
}

ri::List* TestResultParser::getCurrentItemList (void)
{
	DE_ASSERT(m_curItemList);
	return m_curItemList;
}

void TestResultParser::updateCurrentItemList (void)
{
	m_curItemList = DE_NULL;

	for (vector<ri::Item*>::reverse_iterator i = m_itemStack.rbegin(); i != m_itemStack.rend(); i++)
	{
		ri::Item*	item	= *i;
		ri::Type	type	= item->getType();

		if (type == ri::TYPE_IMAGESET)
			m_curItemList = &static_cast<ri::ImageSet*>(item)->images;
		else if (type == ri::TYPE_SECTION)
			m_curItemList = &static_cast<ri::Section*>(item)->items;
		else if (type == ri::TYPE_EGLCONFIGSET)
			m_curItemList = &static_cast<ri::EglConfigSet*>(item)->configs;
		else if (type == ri::TYPE_SHADERPROGRAM)
			m_curItemList = &static_cast<ri::ShaderProgram*>(item)->shaders;

		if (m_curItemList)
			break;
	}

	if (!m_curItemList)
		m_curItemList = &m_result->resultItems;
}

void TestResultParser::pushItem (ri::Item* item)
{
	m_itemStack.push_back(item);
	updateCurrentItemList();
}

void TestResultParser::popItem (void)
{
	m_itemStack.pop_back();
	updateCurrentItemList();
}

void TestResultParser::handleElementStart (void)
{
	const char* elemName = m_xmlParser.getElementName();

	if (m_state == STATE_INITIALIZED)
	{
		// Expect TestCaseResult.
		if (!deStringEqual(elemName, "TestCaseResult"))
			throw TestResultParseError(string("Expected <TestCaseResult>, got <") + elemName + ">");

		const char* version = getAttribute("Version");
		m_logVersion = getTestLogVersion(version);
		// \note Currently assumed that all known log versions are supported.

		m_result->caseVersion	= version;
		m_result->casePath		= getAttribute("CasePath");
		m_result->caseType		= TESTCASETYPE_SELF_VALIDATE;

		if (m_xmlParser.hasAttribute("CaseType"))
			m_result->caseType = getTestCaseType(m_xmlParser.getAttribute("CaseType"));
		else
		{
			// Do guess based on path for legacy log files.
			if (m_logVersion >= TESTLOGVERSION_0_3_2)
				throw TestResultParseError("Missing CaseType attribute in <TestCaseResult>");
			m_result->caseType = getTestCaseTypeFromPath(m_result->casePath.c_str());
		}

		m_state = STATE_IN_TEST_CASE_RESULT;
	}
	else
	{
		ri::List*	curList		= getCurrentItemList();
		ri::Type	itemType	= getResultItemType(elemName);
		ri::Item*	item		= DE_NULL;
		ri::Item*	parentItem	= getCurrentItem();
		ri::Type	parentType	= parentItem ? parentItem->getType() : ri::TYPE_LAST;

		switch (itemType)
		{
			case ri::TYPE_RESULT:
			{
				ri::Result* result = curList->allocItem<ri::Result>();
				result->statusCode = getTestStatusCode(getAttribute("StatusCode"));
				item = result;
				break;
			}

			case ri::TYPE_TEXT:
				item = curList->allocItem<ri::Text>();
				break;

			case ri::TYPE_SECTION:
			{
				ri::Section* section = curList->allocItem<ri::Section>();
				section->name			= getAttribute("Name");
				section->description	= getAttribute("Description");
				item = section;
				break;
			}

			case ri::TYPE_NUMBER:
			{
				ri::Number* number = curList->allocItem<ri::Number>();
				number->name		= getAttribute("Name");
				number->description	= getAttribute("Description");
				number->unit		= getAttribute("Unit");

				if (m_xmlParser.hasAttribute("Tag"))
					number->tag = m_xmlParser.getAttribute("Tag");

				item = number;

				m_curNumValue.clear();
				break;
			}

			case ri::TYPE_IMAGESET:
			{
				ri::ImageSet* imageSet = curList->allocItem<ri::ImageSet>();
				imageSet->name			= getAttribute("Name");
				imageSet->description	= getAttribute("Description");
				item = imageSet;
				break;
			}

			case ri::TYPE_IMAGE:
			{
				ri::Image* image = curList->allocItem<ri::Image>();
				image->name			= getAttribute("Name");
				image->description	= getAttribute("Description");
				image->width		= toInt(getAttribute("Width"));
				image->height		= toInt(getAttribute("Height"));
				image->format		= getImageFormat(getAttribute("Format"));
				image->compression	= getImageCompression(getAttribute("CompressionMode"));
				item = image;
				break;
			}

			case ri::TYPE_SHADERPROGRAM:
			{
				ri::ShaderProgram* shaderProgram = curList->allocItem<ri::ShaderProgram>();
				shaderProgram->linkStatus = toBool(getAttribute("LinkStatus"));
				item = shaderProgram;
				break;
			}

			case ri::TYPE_SHADER:
			{
				if (parentType != ri::TYPE_SHADERPROGRAM)
					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");

				ri::Shader* shader = curList->allocItem<ri::Shader>();

				shader->shaderType		= getShaderTypeFromTagName(elemName);
				shader->compileStatus	= toBool(getAttribute("CompileStatus"));

				item = shader;
				break;
			}

			case ri::TYPE_SPIRVSOURCE:
			{
				if (parentType != ri::TYPE_SHADERPROGRAM)
					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");
				item = curList->allocItem<ri::SpirVSource>();
				break;
			}

			case ri::TYPE_SHADERSOURCE:
				if (parentType == ri::TYPE_SHADER)
					item = &static_cast<ri::Shader*>(parentItem)->source;
				else
					throw TestResultParseError("Unexpected <ShaderSource>");
				break;

			case ri::TYPE_INFOLOG:
				if (parentType == ri::TYPE_SHADERPROGRAM)
					item = &static_cast<ri::ShaderProgram*>(parentItem)->linkInfoLog;
				else if (parentType == ri::TYPE_SHADER)
					item = &static_cast<ri::Shader*>(parentItem)->infoLog;
				else if (parentType == ri::TYPE_COMPILEINFO)
					item = &static_cast<ri::CompileInfo*>(parentItem)->infoLog;
				else
					throw TestResultParseError("Unexpected <InfoLog>");
				break;

			case ri::TYPE_KERNELSOURCE:
				item = curList->allocItem<ri::KernelSource>();
				break;

			case ri::TYPE_COMPILEINFO:
			{
				ri::CompileInfo* info = curList->allocItem<ri::CompileInfo>();
				info->name			= getAttribute("Name");
				info->description	= getAttribute("Description");
				info->compileStatus	= toBool(getAttribute("CompileStatus"));
				item = info;
				break;
			}

			case ri::TYPE_EGLCONFIGSET:
			{
				ri::EglConfigSet* set = curList->allocItem<ri::EglConfigSet>();
				set->name			= getAttribute("Name");
				set->description	= m_xmlParser.hasAttribute("Description") ? m_xmlParser.getAttribute("Description") : "";
				item = set;
				break;
			}

			case ri::TYPE_EGLCONFIG:
			{
				ri::EglConfig* config = curList->allocItem<ri::EglConfig>();
				config->bufferSize				= toInt(getAttribute("BufferSize"));
				config->redSize					= toInt(getAttribute("RedSize"));
				config->greenSize				= toInt(getAttribute("GreenSize"));
				config->blueSize				= toInt(getAttribute("BlueSize"));
				config->luminanceSize			= toInt(getAttribute("LuminanceSize"));
				config->alphaSize				= toInt(getAttribute("AlphaSize"));
				config->alphaMaskSize			= toInt(getAttribute("AlphaMaskSize"));
				config->bindToTextureRGB		= toBool(getAttribute("BindToTextureRGB"));
				config->bindToTextureRGBA		= toBool(getAttribute("BindToTextureRGBA"));
				config->colorBufferType			= getAttribute("ColorBufferType");
				config->configCaveat			= getAttribute("ConfigCaveat");
				config->configID				= toInt(getAttribute("ConfigID"));
				config->conformant				= getAttribute("Conformant");
				config->depthSize				= toInt(getAttribute("DepthSize"));
				config->level					= toInt(getAttribute("Level"));
				config->maxPBufferWidth			= toInt(getAttribute("MaxPBufferWidth"));
				config->maxPBufferHeight		= toInt(getAttribute("MaxPBufferHeight"));
				config->maxPBufferPixels		= toInt(getAttribute("MaxPBufferPixels"));
				config->maxSwapInterval			= toInt(getAttribute("MaxSwapInterval"));
				config->minSwapInterval			= toInt(getAttribute("MinSwapInterval"));
				config->nativeRenderable		= toBool(getAttribute("NativeRenderable"));
				config->renderableType			= getAttribute("RenderableType");
				config->sampleBuffers			= toInt(getAttribute("SampleBuffers"));
				config->samples					= toInt(getAttribute("Samples"));
				config->stencilSize				= toInt(getAttribute("StencilSize"));
				config->surfaceTypes			= getAttribute("SurfaceTypes");
				config->transparentType			= getAttribute("TransparentType");
				config->transparentRedValue		= toInt(getAttribute("TransparentRedValue"));
				config->transparentGreenValue	= toInt(getAttribute("TransparentGreenValue"));
				config->transparentBlueValue	= toInt(getAttribute("TransparentBlueValue"));
				item = config;
				break;
			}

			case ri::TYPE_SAMPLELIST:
			{
				ri::SampleList* list = curList->allocItem<ri::SampleList>();
				list->name			= getAttribute("Name");
				list->description	= getAttribute("Description");
				item = list;
				break;
			}

			case ri::TYPE_SAMPLEINFO:
			{
				if (parentType != ri::TYPE_SAMPLELIST)
					throw TestResultParseError("<SampleInfo> outside of <SampleList>");

				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
				ri::SampleInfo*	info	= &list->sampleInfo;

				item = info;
				break;
			}

			case ri::TYPE_VALUEINFO:
			{
				if (parentType != ri::TYPE_SAMPLEINFO)
					throw TestResultParseError("<ValueInfo> outside of <SampleInfo>");

				ri::SampleInfo*	sampleInfo	= static_cast<ri::SampleInfo*>(parentItem);
				ri::ValueInfo*	valueInfo	= sampleInfo->valueInfos.allocItem<ri::ValueInfo>();

				valueInfo->name			= getAttribute("Name");
				valueInfo->description	= getAttribute("Description");
				valueInfo->tag			= getSampleValueTag(getAttribute("Tag"));

				if (m_xmlParser.hasAttribute("Unit"))
					valueInfo->unit = getAttribute("Unit");

				item = valueInfo;
				break;
			}

			case ri::TYPE_SAMPLE:
			{
				if (parentType != ri::TYPE_SAMPLELIST)
					throw TestResultParseError("<Sample> outside of <SampleList>");

				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
				ri::Sample*		sample	= list->samples.allocItem<ri::Sample>();

				item = sample;
				break;
			}

			case ri::TYPE_SAMPLEVALUE:
			{
				if (parentType != ri::TYPE_SAMPLE)
					throw TestResultParseError("<Value> outside of <Sample>");

				ri::Sample*			sample	= static_cast<ri::Sample*>(parentItem);
				ri::SampleValue*	value	= sample->values.allocItem<ri::SampleValue>();

				item = value;
				break;
			}

			default:
				throw TestResultParseError(string("Unsupported element '") + elemName + ("'"));
		}

		DE_ASSERT(item);
		pushItem(item);

		// Reset base64 decoding offset.
		m_base64DecodeOffset = 0;
	}
}

void TestResultParser::handleElementEnd (void)
{
	const char* elemName = m_xmlParser.getElementName();

	if (m_state != STATE_IN_TEST_CASE_RESULT)
		throw TestResultParseError(string("Unexpected </") + elemName + "> outside of <TestCaseResult>");

	if (deStringEqual(elemName, "TestCaseResult"))
	{
		// Logs from buggy test cases may contain invalid XML.
		// DE_ASSERT(getCurrentItem() == DE_NULL);
		// \todo [2012-11-22 pyry] Log warning.

		m_state = STATE_TEST_CASE_RESULT_ENDED;
	}
	else
	{
		ri::Type	itemType	= getResultItemType(elemName);
		ri::Item*	curItem		= getCurrentItem();

		if (!curItem || itemType != curItem->getType())
			throw TestResultParseError(string("Unexpected </") + elemName + ">");

		if (itemType == ri::TYPE_RESULT)
		{
			ri::Result* result = static_cast<ri::Result*>(curItem);
			m_result->statusCode	= result->statusCode;
			m_result->statusDetails	= result->details;
		}
		else if (itemType == ri::TYPE_NUMBER)
		{
			// Parse value for number.
			ri::Number*	number	= static_cast<ri::Number*>(curItem);
			number->value = getNumericValue(m_curNumValue);
			m_curNumValue.clear();
		}
		else if (itemType == ri::TYPE_SAMPLEVALUE)
		{
			ri::SampleValue* value = static_cast<ri::SampleValue*>(curItem);
			value->value = getNumericValue(m_curNumValue);
			m_curNumValue.clear();
		}

		popItem();
	}
}

void TestResultParser::handleData (void)
{
	ri::Item*	curItem		= getCurrentItem();
	ri::Type	type		= curItem ? curItem->getType() : ri::TYPE_LAST;

	switch (type)
	{
		case ri::TYPE_RESULT:
			m_xmlParser.appendDataStr(static_cast<ri::Result*>(curItem)->details);
			break;

		case ri::TYPE_TEXT:
			m_xmlParser.appendDataStr(static_cast<ri::Text*>(curItem)->text);
			break;

		case ri::TYPE_SHADERSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::ShaderSource*>(curItem)->source);
			break;

		case ri::TYPE_SPIRVSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::SpirVSource*>(curItem)->source);
			break;

		case ri::TYPE_INFOLOG:
			m_xmlParser.appendDataStr(static_cast<ri::InfoLog*>(curItem)->log);
			break;

		case ri::TYPE_KERNELSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::KernelSource*>(curItem)->source);
			break;

		case ri::TYPE_NUMBER:
		case ri::TYPE_SAMPLEVALUE:
			m_xmlParser.appendDataStr(m_curNumValue);
			break;

		case ri::TYPE_IMAGE:
		{
			ri::Image* image = static_cast<ri::Image*>(curItem);

			// Base64 decode.
			int numBytesIn = m_xmlParser.getDataSize();

			for (int inNdx = 0; inNdx < numBytesIn; inNdx++)
			{
				deUint8		byte		= m_xmlParser.getDataByte(inNdx);
				deUint8		decodedBits	= 0;

				if (de::inRange<deInt8>(byte, 'A', 'Z'))
					decodedBits = (deUint8)(byte - 'A');
				else if (de::inRange<deInt8>(byte, 'a', 'z'))
					decodedBits = (deUint8)(('Z'-'A'+1) + (byte-'a'));
				else if (de::inRange<deInt8>(byte, '0', '9'))
					decodedBits = (deUint8)(('Z'-'A'+1) + ('z'-'a'+1) + (byte-'0'));
				else if (byte == '+')
					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+1);
				else if (byte == '/')
					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+2);
				else if (byte == '=')
				{
					// Padding at end - remove last byte.
					if (image->data.empty())
						throw TestResultParseError("Malformed base64 data");
					image->data.pop_back();
					continue;
				}
				else
					continue; // Not an B64 input character.

				int phase = m_base64DecodeOffset % 4;

				if (phase == 0)
					image->data.resize(image->data.size()+3, 0);

				if ((int)image->data.size() < (m_base64DecodeOffset>>2)*3 + 3)
					throw TestResultParseError("Malformed base64 data");
				deUint8* outPtr = &image->data[(m_base64DecodeOffset>>2)*3];

				switch (phase)
				{
					case 0: outPtr[0] |= (deUint8)(decodedBits<<2);																								break;
					case 1: outPtr[0] = (deUint8)(outPtr[0] | (deUint8)(decodedBits>>4));	outPtr[1] = (deUint8)(outPtr[1] | (deUint8)((decodedBits&0xF)<<4));	break;
					case 2: outPtr[1] = (deUint8)(outPtr[1] | (deUint8)(decodedBits>>2));	outPtr[2] = (deUint8)(outPtr[2] | (deUint8)((decodedBits&0x3)<<6));	break;
					case 3: outPtr[2] |= decodedBits;																											break;
					default:
						DE_ASSERT(false);
				}

				m_base64DecodeOffset += 1;
			}

			break;
		}

		default:
			// Just ignore data.
			break;
	}
}

//! Helper for parsing TestCaseResult from TestCaseResultData.
void parseTestCaseResultFromData (TestResultParser* parser, TestCaseResult* result, const TestCaseResultData& data)
{
	DE_ASSERT(result->resultItems.getNumItems() == 0);

	// Initialize status codes etc. from data.
	result->casePath		= data.getTestCasePath();
	result->caseType		= TESTCASETYPE_SELF_VALIDATE;
	result->statusCode		= data.getStatusCode();
	result->statusDetails	= data.getStatusDetails();

	if (data.getDataSize() > 0)
	{
		parser->init(result);

		const TestResultParser::ParseResult parseResult = parser->parse(data.getData(), data.getDataSize());

		if (result->statusCode == TESTSTATUSCODE_LAST)
		{
			result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR;

			if (parseResult == TestResultParser::PARSERESULT_ERROR)
				result->statusDetails = "Test case result parsing failed";
			else if (parseResult != TestResultParser::PARSERESULT_COMPLETE)
				result->statusDetails = "Incomplete test case result";
			else
				result->statusDetails = "Test case result is missing <Result> item";
		}
	}
	else if (result->statusCode == TESTSTATUSCODE_LAST)
	{
		result->statusCode		= TESTSTATUSCODE_TERMINATED;
		result->statusDetails	= "Empty test case result";
	}

	if (result->casePath.empty())
		throw Error("Empty test case path in result");

	if (result->caseType == TESTCASETYPE_LAST)
		throw Error("Invalid test case type in result");

	DE_ASSERT(result->statusCode != TESTSTATUSCODE_LAST);
}

} // xe
