/*-------------------------------------------------------------------------
 * 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			},
	{ 0x925c7349,	"MeshShader",			ri::TYPE_SHADER			},
	{ 0xc3a35d6f,	"TaskShader",			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			},
	{ 0xc3a35d6f,	"TaskShader",			ri::Shader::SHADERTYPE_TASK				},
	{ 0x925c7349,	"MeshShader",			ri::Shader::SHADERTYPE_MESH				},
};

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
