/*-------------------------------------------------------------------------
 * drawElements TestLog Library
 * ----------------------------
 *
 * 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 logging
 *//*--------------------------------------------------------------------*/

#include "qpTestLog.h"
#include "qpXmlWriter.h"
#include "qpInfo.h"
#include "qpDebugOut.h"

#include "deMemory.h"
#include "deInt32.h"
#include "deString.h"

#include "deMutex.h"

#if defined(QP_SUPPORT_PNG)
#	include <png.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#if (DE_OS == DE_OS_WIN32)
#	include <windows.h>
#	include <io.h>
#endif

#if defined(DE_DEBUG)

/* Utils for verifying container (Section, ImageSet, EglConfigSet) usage in debug builds. */

typedef enum ContainerType_e
{
	CONTAINERTYPE_SECTION = 0,
	CONTAINERTYPE_IMAGESET,
	CONTAINERTYPE_EGLCONFIGSET,
	CONTAINERTYPE_SHADERPROGRAM,
	CONTAINERTYPE_SAMPLELIST,
	CONTAINERTYPE_SAMPLEINFO,
	CONTAINERTYPE_SAMPLE,

	CONTAINERTYPE_LAST
} ContainerType;

DE_INLINE deBool childContainersOk (ContainerType type)
{
	return type == CONTAINERTYPE_SECTION || type == CONTAINERTYPE_SAMPLELIST;
}

enum
{
	MAX_CONTAINER_STACK_DEPTH		= 32
};

typedef struct ContainerStack_s
{
	int				numElements;
	ContainerType	elements[MAX_CONTAINER_STACK_DEPTH];
} ContainerStack;

DE_INLINE void ContainerStack_reset (ContainerStack* stack)
{
	deMemset(stack, 0, sizeof(ContainerStack));
}

DE_INLINE deBool ContainerStack_isEmpty (const ContainerStack* stack)
{
	return stack->numElements == 0;
}

DE_INLINE deBool ContainerStack_push (ContainerStack* stack, ContainerType type)
{
	if (stack->numElements == MAX_CONTAINER_STACK_DEPTH)
		return DE_FALSE;

	if (stack->numElements > 0 && !childContainersOk(stack->elements[stack->numElements-1]))
		return DE_FALSE;

	stack->elements[stack->numElements]  = type;
	stack->numElements					+= 1;

	return DE_TRUE;
}

DE_INLINE ContainerType ContainerStack_pop (ContainerStack* stack)
{
	DE_ASSERT(stack->numElements > 0);
	stack->numElements -= 1;
	return stack->elements[stack->numElements];
}

DE_INLINE ContainerType ContainerStack_getTop (const ContainerStack* stack)
{
	if (stack->numElements > 0)
		return stack->elements[stack->numElements-1];
	else
		return CONTAINERTYPE_LAST;
}

#endif

/* qpTestLog instance */
struct qpTestLog_s
{
	deUint32				flags;				/*!< Logging flags.						*/

	deMutex					lock;				/*!< Lock for mutable state below.		*/

	/* State protected by lock. */
	FILE*					outputFile;
	qpXmlWriter*			writer;
	deBool					isSessionOpen;
	deBool					isCaseOpen;

#if defined(DE_DEBUG)
	ContainerStack			containerStack;		/*!< For container usage verification.	*/
#endif
};

/* Maps integer to string. */
typedef struct qpKeyStringMap_s
{
	int		key;
	char*	string;
} qpKeyStringMap;

static const char* LOG_FORMAT_VERSION = "0.3.4";

/* Mapping enum to above strings... */
static const qpKeyStringMap s_qpTestTypeMap[] =
{
	{ QP_TEST_CASE_TYPE_SELF_VALIDATE,		"SelfValidate"	},
	{ QP_TEST_CASE_TYPE_PERFORMANCE,		"Performance"	},
	{ QP_TEST_CASE_TYPE_CAPABILITY,			"Capability"	},
	{ QP_TEST_CASE_TYPE_ACCURACY,			"Accuracy"		},

	{ QP_TEST_CASE_TYPE_LAST,				DE_NULL			}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTestTypeMap) == QP_TEST_CASE_TYPE_LAST + 1);

static const qpKeyStringMap s_qpTestResultMap[] =
{
	{ QP_TEST_RESULT_PASS,						"Pass"					},
	{ QP_TEST_RESULT_FAIL,						"Fail"					},
	{ QP_TEST_RESULT_QUALITY_WARNING,			"QualityWarning"		},
	{ QP_TEST_RESULT_COMPATIBILITY_WARNING,		"CompatibilityWarning"	},
	{ QP_TEST_RESULT_PENDING,					"Pending"				},	/* should not be needed here */
	{ QP_TEST_RESULT_NOT_SUPPORTED,				"NotSupported"			},
	{ QP_TEST_RESULT_RESOURCE_ERROR,			"ResourceError"			},
	{ QP_TEST_RESULT_INTERNAL_ERROR,			"InternalError"			},
	{ QP_TEST_RESULT_CRASH,						"Crash"					},
	{ QP_TEST_RESULT_TIMEOUT,					"Timeout"				},

	/* Add new values here if needed, remember to update qpTestResult enumeration. */

	{ QP_TEST_RESULT_LAST,						DE_NULL					}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTestResultMap) == QP_TEST_RESULT_LAST + 1);

/* Key tag to string mapping. */

static const qpKeyStringMap s_qpTagMap[] =
{
	{ QP_KEY_TAG_NONE,			DE_NULL			},
	{ QP_KEY_TAG_PERFORMANCE,	"Performance"	},
	{ QP_KEY_TAG_QUALITY,		"Quality"		},
	{ QP_KEY_TAG_PRECISION,		"Precision"		},
	{ QP_KEY_TAG_TIME,			"Time"			},

	{ QP_KEY_TAG_LAST,			DE_NULL			}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTagMap) == QP_KEY_TAG_LAST + 1);

/* Sample value tag to string mapping. */

static const qpKeyStringMap s_qpSampleValueTagMap[] =
{
	{ QP_SAMPLE_VALUE_TAG_PREDICTOR,	"Predictor"	},
	{ QP_SAMPLE_VALUE_TAG_RESPONSE,		"Response"	},

	{ QP_SAMPLE_VALUE_TAG_LAST,			DE_NULL		}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpSampleValueTagMap) == QP_SAMPLE_VALUE_TAG_LAST + 1);

/* Image compression mode to string mapping. */

static const qpKeyStringMap s_qpImageCompressionModeMap[] =
{
	{ QP_IMAGE_COMPRESSION_MODE_NONE,	"None"	},
	{ QP_IMAGE_COMPRESSION_MODE_PNG,	"PNG"	},

	{ QP_IMAGE_COMPRESSION_MODE_BEST,	DE_NULL	},	/* not allowed to be written! */

	{ QP_IMAGE_COMPRESSION_MODE_LAST,	DE_NULL	}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpImageCompressionModeMap) == QP_IMAGE_COMPRESSION_MODE_LAST + 1);

/* Image format to string mapping. */

static const qpKeyStringMap s_qpImageFormatMap[] =
{
	{ QP_IMAGE_FORMAT_RGB888,	"RGB888"	},
	{ QP_IMAGE_FORMAT_RGBA8888,	"RGBA8888"	},

	{ QP_IMAGE_FORMAT_LAST,		DE_NULL		}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpImageFormatMap) == QP_IMAGE_FORMAT_LAST + 1);

/* Shader type to string mapping. */

static const qpKeyStringMap s_qpShaderTypeMap[] =
{
	{ QP_SHADER_TYPE_VERTEX,			"VertexShader"			},
	{ QP_SHADER_TYPE_FRAGMENT,			"FragmentShader"		},
	{ QP_SHADER_TYPE_GEOMETRY,			"GeometryShader"		},
	{ QP_SHADER_TYPE_TESS_CONTROL,		"TessControlShader"		},
	{ QP_SHADER_TYPE_TESS_EVALUATION,	"TessEvaluationShader"	},
	{ QP_SHADER_TYPE_COMPUTE,			"ComputeShader"			},

	{ QP_SHADER_TYPE_LAST,				DE_NULL					}
};

DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpShaderTypeMap) == QP_SHADER_TYPE_LAST + 1);

static void qpTestLog_flushFile (qpTestLog* log)
{
	DE_ASSERT(log && log->outputFile);
	fflush(log->outputFile);
#if (DE_OS == DE_OS_WIN32) && (DE_COMPILER == DE_COMPILER_MSC)
	/* \todo [petri] Is this really necessary? */
	FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(log->outputFile)));
#endif
}

#define QP_LOOKUP_STRING(KEYMAP, KEY)	qpLookupString(KEYMAP, DE_LENGTH_OF_ARRAY(KEYMAP), (int)(KEY))

static const char* qpLookupString (const qpKeyStringMap* keyMap, int keyMapSize, int key)
{
	DE_ASSERT(keyMap);
	DE_ASSERT(deInBounds32(key, 0, keyMapSize));
	DE_ASSERT(keyMap[key].key == key);
	DE_UNREF(keyMapSize); /* for asserting only */
	return keyMap[key].string;
}

DE_INLINE void int32ToString (int val, char buf[32])
{
	deSprintf(&buf[0], 32, "%d", val);
}

DE_INLINE void int64ToString (deInt64 val, char buf[32])
{
	deSprintf(&buf[0], 32, "%lld", (long long int)val);
}

DE_INLINE void floatToString (float value, char* buf, size_t bufSize)
{
	deSprintf(buf, bufSize, "%f", value);
}

DE_INLINE void doubleToString (double value, char* buf, size_t bufSize)
{
	deSprintf(buf, bufSize, "%f", value);
}

static deBool beginSession (qpTestLog* log)
{
	DE_ASSERT(log && !log->isSessionOpen);

	/* Write session info. */
	fprintf(log->outputFile, "#sessionInfo releaseName %s\n", qpGetReleaseName());
	fprintf(log->outputFile, "#sessionInfo releaseId 0x%08x\n", qpGetReleaseId());
	fprintf(log->outputFile, "#sessionInfo targetName \"%s\"\n", qpGetTargetName());

    /* Write out #beginSession. */
	fprintf(log->outputFile, "#beginSession\n");
	qpTestLog_flushFile(log);

	log->isSessionOpen = DE_TRUE;

	return DE_TRUE;
}

static deBool endSession (qpTestLog* log)
{
	DE_ASSERT(log && log->isSessionOpen);

    /* Make sure xml is flushed. */
    qpXmlWriter_flush(log->writer);

    /* Write out #endSession. */
	fprintf(log->outputFile, "\n#endSession\n");
	qpTestLog_flushFile(log);

	log->isSessionOpen = DE_FALSE;

	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Create a file based logger instance
 * \param fileName Name of the file where to put logs
 * \return qpTestLog instance, or DE_NULL if cannot create file
 *//*--------------------------------------------------------------------*/
qpTestLog* qpTestLog_createFileLog (const char* fileName, deUint32 flags)
{
	qpTestLog* log = (qpTestLog*)deCalloc(sizeof(qpTestLog));
	if (!log)
		return DE_NULL;

	DE_ASSERT(fileName && fileName[0]); /* must have filename. */

#if defined(DE_DEBUG)
	ContainerStack_reset(&log->containerStack);
#endif

	qpPrintf("Writing test log into %s\n", fileName);

	/* Create output file. */
	log->outputFile = fopen(fileName, "wb");
	if (!log->outputFile)
	{
		qpPrintf("ERROR: Unable to open test log output file '%s'.\n", fileName);
		qpTestLog_destroy(log);
		return DE_NULL;
	}

	log->flags			= flags;
	log->writer			= qpXmlWriter_createFileWriter(log->outputFile, 0, !(flags & QP_TEST_LOG_NO_FLUSH));
	log->lock			= deMutex_create(DE_NULL);
	log->isSessionOpen	= DE_FALSE;
	log->isCaseOpen		= DE_FALSE;

	if (!log->writer)
	{
		qpPrintf("ERROR: Unable to create output XML writer to file '%s'.\n", fileName);
		qpTestLog_destroy(log);
		return DE_NULL;
	}

	if (!log->lock)
	{
		qpPrintf("ERROR: Unable to create mutex.\n");
		qpTestLog_destroy(log);
		return DE_NULL;
	}

	beginSession(log);

	return log;
}

/*--------------------------------------------------------------------*//*!
 * \brief Destroy a logger instance
 * \param a	qpTestLog instance
 *//*--------------------------------------------------------------------*/
void qpTestLog_destroy (qpTestLog* log)
{
	DE_ASSERT(log);

	if (log->isSessionOpen)
		endSession(log);

	if (log->writer)
		qpXmlWriter_destroy(log->writer);

	if (log->outputFile)
		fclose(log->outputFile);

	if (log->lock)
		deMutex_destroy(log->lock);

	deFree(log);
}

/*--------------------------------------------------------------------*//*!
 * \brief Log start of test case
 * \param log qpTestLog instance
 * \param testCasePath	Full test case path (as seen in Candy).
 * \param testCaseType	Test case type
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_startCase (qpTestLog* log, const char* testCasePath, qpTestCaseType testCaseType)
{
	const char*		typeStr				= QP_LOOKUP_STRING(s_qpTestTypeMap, testCaseType);
	int				numResultAttribs	= 0;
	qpXmlAttribute	resultAttribs[8];

	DE_ASSERT(log && testCasePath && (testCasePath[0] != 0));
	deMutex_lock(log->lock);

	DE_ASSERT(!log->isCaseOpen);
	DE_ASSERT(ContainerStack_isEmpty(&log->containerStack));

	/* Flush XML and write out #beginTestCaseResult. */
	qpXmlWriter_flush(log->writer);
	fprintf(log->outputFile, "\n#beginTestCaseResult %s\n", testCasePath);
	if (!(log->flags & QP_TEST_LOG_NO_FLUSH))
		qpTestLog_flushFile(log);

	log->isCaseOpen = DE_TRUE;

	/* Fill in attributes. */
	resultAttribs[numResultAttribs++] = qpSetStringAttrib("Version", LOG_FORMAT_VERSION);
	resultAttribs[numResultAttribs++] = qpSetStringAttrib("CasePath", testCasePath);
	resultAttribs[numResultAttribs++] = qpSetStringAttrib("CaseType", typeStr);

	if (!qpXmlWriter_startDocument(log->writer) ||
		!qpXmlWriter_startElement(log->writer, "TestCaseResult", numResultAttribs, resultAttribs))
	{
		qpPrintf("qpTestLog_startCase(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Log end of test case
 * \param log qpTestLog instance
 * \param result Test result
 * \param description Description of a problem in case of error
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_endCase (qpTestLog* log, qpTestResult result, const char* resultDetails)
{
	const char*		statusStr		= QP_LOOKUP_STRING(s_qpTestResultMap, result);
	qpXmlAttribute	statusAttrib	= qpSetStringAttrib("StatusCode", statusStr);

	deMutex_lock(log->lock);

	DE_ASSERT(log->isCaseOpen);
	DE_ASSERT(ContainerStack_isEmpty(&log->containerStack));

	/* <Result StatusCode="Pass">Result details</Result>
	 * </TestCaseResult>
	 */
	if (!qpXmlWriter_startElement(log->writer, "Result", 1, &statusAttrib) ||
		(resultDetails && !qpXmlWriter_writeString(log->writer, resultDetails)) ||
		!qpXmlWriter_endElement(log->writer, "Result") ||
		!qpXmlWriter_endElement(log->writer, "TestCaseResult") ||
		!qpXmlWriter_endDocument(log->writer))		/* Close any XML elements still open */
	{
		qpPrintf("qpTestLog_endCase(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	/* Flush XML and write #endTestCaseResult. */
	qpXmlWriter_flush(log->writer);
	fprintf(log->outputFile, "\n#endTestCaseResult\n");
	if (!(log->flags & QP_TEST_LOG_NO_FLUSH))
		qpTestLog_flushFile(log);

	log->isCaseOpen = DE_FALSE;

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Abrupt termination of logging.
 * \param log		qpTestLog instance
 * \param result	Result code, only Crash and Timeout are allowed.
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_terminateCase (qpTestLog* log, qpTestResult result)
{
	const char* resultStr = QP_LOOKUP_STRING(s_qpTestResultMap, result);

	DE_ASSERT(log);
	DE_ASSERT(result == QP_TEST_RESULT_CRASH || result == QP_TEST_RESULT_TIMEOUT);

	deMutex_lock(log->lock);

	if (!log->isCaseOpen)
	{
		deMutex_unlock(log->lock);
		return DE_FALSE; /* Soft error. This is called from error handler. */
	}

	/* Flush XML and write #terminateTestCaseResult. */
	qpXmlWriter_flush(log->writer);
	fprintf(log->outputFile, "\n#terminateTestCaseResult %s\n", resultStr);
	qpTestLog_flushFile(log);

	log->isCaseOpen = DE_FALSE;

#if defined(DE_DEBUG)
	ContainerStack_reset(&log->containerStack);
#endif

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

static deBool qpTestLog_writeKeyValuePair (qpTestLog* log, const char* elementName, const char* name, const char* description, const char* unit, qpKeyValueTag tag, const char* text)
{
	const char*		tagString = QP_LOOKUP_STRING(s_qpTagMap, tag);
	qpXmlAttribute	attribs[8];
	int				numAttribs = 0;

	DE_ASSERT(log && elementName && text);
	deMutex_lock(log->lock);

	/* Fill in attributes. */
	if (name)			attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	if (description)	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
	if (tagString)		attribs[numAttribs++] = qpSetStringAttrib("Tag", tagString);
	if (unit)			attribs[numAttribs++] = qpSetStringAttrib("Unit", unit);

	if (!qpXmlWriter_startElement(log->writer, elementName, numAttribs, attribs) ||
		!qpXmlWriter_writeString(log->writer, text) ||
		!qpXmlWriter_endElement(log->writer, elementName))
	{
		qpPrintf("qpTestLog_writeKeyValuePair(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write a message to output log
 * \param log		qpTestLog instance
 * \param format	Format string of message
 * \param ...		Parameters for message
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeMessage (qpTestLog* log, const char* format, ...)
{
	char	buffer[1024];
	va_list	args;

	/* \todo [petri] Handle buffer overflows! */

	va_start(args, format);
	buffer[DE_LENGTH_OF_ARRAY(buffer) - 1] = 0;
	vsnprintf(buffer, sizeof(buffer), format, args);
	va_end(args);

	/* <Text>text</Text> */
	return qpTestLog_writeKeyValuePair(log, "Text", DE_NULL, DE_NULL, DE_NULL, QP_KEY_TAG_LAST, buffer);
}

/*--------------------------------------------------------------------*//*!
 * \brief Write key-value-pair into log
 * \param log			qpTestLog instance
 * \param name			Unique identifier for entry
 * \param description	Human readable description
 * \param tag			Optional tag
 * \param value			Value of the key-value-pair
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeText (qpTestLog* log, const char* name, const char* description, qpKeyValueTag tag, const char* text)
{
	/* <Text Name="name" Description="description" Tag="tag">text</Text> */
	return qpTestLog_writeKeyValuePair(log, "Text", name, description, DE_NULL, tag, text);
}

/*--------------------------------------------------------------------*//*!
 * \brief Write key-value-pair into log
 * \param log			qpTestLog instance
 * \param name			Unique identifier for entry
 * \param description	Human readable description
 * \param tag			Optional tag
 * \param value			Value of the key-value-pair
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeInteger (qpTestLog* log, const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value)
{
	char tmpString[64];
	int64ToString(value, tmpString);

	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
}

/*--------------------------------------------------------------------*//*!
 * \brief Write key-value-pair into log
 * \param log			qpTestLog instance
 * \param name			Unique identifier for entry
 * \param description	Human readable description
 * \param tag			Optional tag
 * \param value			Value of the key-value-pair
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeFloat (qpTestLog* log, const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value)
{
	char tmpString[64];
	floatToString(value, tmpString, sizeof(tmpString));

	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
}

typedef struct Buffer_s
{
	size_t		capacity;
	size_t		size;
	deUint8*	data;
} Buffer;

void Buffer_init (Buffer* buffer)
{
	buffer->capacity	= 0;
	buffer->size		= 0;
	buffer->data		= DE_NULL;
}

void Buffer_deinit (Buffer* buffer)
{
	deFree(buffer->data);
	Buffer_init(buffer);
}

deBool Buffer_resize (Buffer* buffer, size_t newSize)
{
	/* Grow buffer if necessary. */
	if (newSize > buffer->capacity)
	{
		size_t		newCapacity	= (size_t)deAlign32(deMax32(2*(int)buffer->capacity, (int)newSize), 512);
		deUint8*	newData		= (deUint8*)deMalloc(newCapacity);
		if (!newData)
			return DE_FALSE;

		memcpy(newData, buffer->data, buffer->size);
		deFree(buffer->data);
		buffer->data		= newData;
		buffer->capacity	= newCapacity;
	}

	buffer->size = newSize;
	return DE_TRUE;
}

deBool Buffer_append (Buffer* buffer, const deUint8* data, size_t numBytes)
{
	size_t offset = buffer->size;

	if (!Buffer_resize(buffer, buffer->size + numBytes))
		return DE_FALSE;

	/* Append bytes. */
	memcpy(&buffer->data[offset], data, numBytes);
	return DE_TRUE;
}

#if defined(QP_SUPPORT_PNG)
void pngWriteData (png_structp png, png_bytep dataPtr, png_size_t numBytes)
{
	Buffer* buffer = (Buffer*)png_get_io_ptr(png);
	if (!Buffer_append(buffer, (const deUint8*)dataPtr, numBytes))
		png_error(png, "unable to resize PNG write buffer!");
}

void pngFlushData (png_structp png)
{
	DE_UNREF(png);
	/* nada */
}

static deBool writeCompressedPNG (png_structp png, png_infop info, png_byte** rowPointers, int width, int height, int colorFormat)
{
	if (setjmp(png_jmpbuf(png)) == 0)
	{
		/* Write data. */
		png_set_IHDR(png, info, (png_uint_32)width, (png_uint_32)height,
			8,
			colorFormat,
			PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_BASE,
			PNG_FILTER_TYPE_BASE);
		png_write_info(png, info);
		png_write_image(png, rowPointers);
		png_write_end(png, NULL);

		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

static deBool compressImagePNG (Buffer* buffer, qpImageFormat imageFormat, int width, int height, int rowStride, const void* data)
{
	deBool			compressOk		= DE_FALSE;
	png_structp		png				= DE_NULL;
	png_infop		info			= DE_NULL;
	png_byte**		rowPointers		= DE_NULL;
	deBool			hasAlpha		= imageFormat == QP_IMAGE_FORMAT_RGBA8888;
	int				ndx;

	/* Handle format. */
	DE_ASSERT(imageFormat == QP_IMAGE_FORMAT_RGB888 || imageFormat == QP_IMAGE_FORMAT_RGBA8888);

	/* Allocate & set row pointers. */
	rowPointers = (png_byte**)deMalloc((size_t)height * sizeof(png_byte*));
	if (!rowPointers)
		return DE_FALSE;

	for (ndx = 0; ndx < height; ndx++)
		rowPointers[ndx] = (png_byte*)((const deUint8*)data + ndx*rowStride);

	/* Initialize PNG compressor. */
	png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	info = png ? png_create_info_struct(png) : DE_NULL;
	if (png && info)
	{
		/* Set our own write function. */
		png_set_write_fn(png, buffer, pngWriteData, pngFlushData);

		compressOk = writeCompressedPNG(png, info, rowPointers, width, height,
										hasAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB);
	}

	/* Cleanup & return. */
	if (png && info)
	{
		png_destroy_info_struct(png, &info);
		png_destroy_write_struct(&png, DE_NULL);
	}
	else if (png)
		png_destroy_write_struct(&png, &info);

	deFree(rowPointers);
	return compressOk;
}
#endif /* QP_SUPPORT_PNG */

/*--------------------------------------------------------------------*//*!
 * \brief Start image set
 * \param log			qpTestLog instance
 * \param name			Unique identifier for the set
 * \param description	Human readable description
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_startImageSet (qpTestLog* log, const char* name, const char* description)
{
	qpXmlAttribute	attribs[4];
	int				numAttribs = 0;

	DE_ASSERT(log && name);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	if (description)
		attribs[numAttribs++] = qpSetStringAttrib("Description", description);

	/* <ImageSet Name="<name>"> */
	if (!qpXmlWriter_startElement(log->writer, "ImageSet", numAttribs, attribs))
	{
		qpPrintf("qpTestLog_startImageSet(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_IMAGESET));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief End image set
 * \param log			qpTestLog instance
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_endImageSet (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	/* <ImageSet Name="<name>"> */
	if (!qpXmlWriter_endElement(log->writer, "ImageSet"))
	{
		qpPrintf("qpTestLog_endImageSet(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_IMAGESET);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write base64 encoded raw image data into log
 * \param log				qpTestLog instance
 * \param name				Unique name (matching names can be compared across BatchResults).
 * \param description		Textual description (shown in Candy).
 * \param compressionMode	Compression mode
 * \param imageFormat		Color format
 * \param width				Width in pixels
 * \param height			Height in pixels
 * \param stride			Data stride (offset between rows)
 * \param data				Pointer to pixel data
 * \return 0 if OK, otherwise <0
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeImage	(
	qpTestLog*				log,
	const char*				name,
	const char*				description,
	qpImageCompressionMode	compressionMode,
	qpImageFormat			imageFormat,
	int						width,
	int						height,
	int						stride,
	const void*				data)
{
	char			widthStr[32];
	char			heightStr[32];
	qpXmlAttribute	attribs[8];
	int				numAttribs			= 0;
	Buffer			compressedBuffer;
	const void*		writeDataPtr		= DE_NULL;
	size_t			writeDataBytes		= ~(size_t)0;

	DE_ASSERT(log && name);
	DE_ASSERT(deInRange32(width, 1, 16384));
	DE_ASSERT(deInRange32(height, 1, 16384));
	DE_ASSERT(data);

	if (log->flags & QP_TEST_LOG_EXCLUDE_IMAGES)
		return DE_TRUE; /* Image not logged. */

	Buffer_init(&compressedBuffer);

	/* BEST compression mode defaults to PNG. */
	if (compressionMode == QP_IMAGE_COMPRESSION_MODE_BEST)
	{
#if defined(QP_SUPPORT_PNG)
		compressionMode = QP_IMAGE_COMPRESSION_MODE_PNG;
#else
		compressionMode = QP_IMAGE_COMPRESSION_MODE_NONE;
#endif
	}

#if defined(QP_SUPPORT_PNG)
	/* Try storing with PNG compression. */
	if (compressionMode == QP_IMAGE_COMPRESSION_MODE_PNG)
	{
		deBool compressOk = compressImagePNG(&compressedBuffer, imageFormat, width, height, stride, data);
		if (compressOk)
		{
			writeDataPtr	= compressedBuffer.data;
			writeDataBytes	= compressedBuffer.size;
		}
		else
		{
			/* Fall-back to default compression. */
			qpPrintf("WARNING: PNG compression failed -- storing image uncompressed.\n");
			compressionMode	= QP_IMAGE_COMPRESSION_MODE_NONE;
		}
	}
#endif

	/* Handle image compression. */
	switch (compressionMode)
	{
		case QP_IMAGE_COMPRESSION_MODE_NONE:
		{
			int pixelSize		= imageFormat == QP_IMAGE_FORMAT_RGB888 ? 3 : 4;
			int packedStride	= pixelSize*width;

			if (packedStride == stride)
				writeDataPtr = data;
			else
			{
				/* Need to re-pack pixels. */
				if (Buffer_resize(&compressedBuffer, (size_t)(packedStride*height)))
				{
					int row;
					for (row = 0; row < height; row++)
						memcpy(&compressedBuffer.data[packedStride*row], &((const deUint8*)data)[row*stride], (size_t)(pixelSize*width));
				}
				else
				{
					qpPrintf("ERROR: Failed to pack pixels for writing.\n");
					Buffer_deinit(&compressedBuffer);
					return DE_FALSE;
				}
			}

			writeDataBytes = (size_t)(packedStride*height);
			break;
		}

#if defined(QP_SUPPORT_PNG)
		case QP_IMAGE_COMPRESSION_MODE_PNG:
			DE_ASSERT(writeDataPtr); /* Already handled. */
			break;
#endif

		default:
			qpPrintf("qpTestLog_writeImage(): Unknown compression mode: %s\n", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode));
			Buffer_deinit(&compressedBuffer);
			return DE_FALSE;
	}

	/* Fill in attributes. */
	int32ToString(width, widthStr);
	int32ToString(height, heightStr);
	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	attribs[numAttribs++] = qpSetStringAttrib("Width", widthStr);
	attribs[numAttribs++] = qpSetStringAttrib("Height", heightStr);
	attribs[numAttribs++] = qpSetStringAttrib("Format", QP_LOOKUP_STRING(s_qpImageFormatMap, imageFormat));
	attribs[numAttribs++] = qpSetStringAttrib("CompressionMode", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode));
	if (description) attribs[numAttribs++] = qpSetStringAttrib("Description", description);

	/* \note Log lock is acquired after compression! */
	deMutex_lock(log->lock);

	/* <Image ID="result" Name="Foobar" Width="640" Height="480" Format="RGB888" CompressionMode="None">base64 data</Image> */
	if (!qpXmlWriter_startElement(log->writer, "Image", numAttribs, attribs) ||
		!qpXmlWriter_writeBase64(log->writer, (const deUint8*)writeDataPtr, writeDataBytes) ||
		!qpXmlWriter_endElement(log->writer, "Image"))
	{
		qpPrintf("qpTestLog_writeImage(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		Buffer_deinit(&compressedBuffer);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);

	/* Free compressed data if allocated. */
	Buffer_deinit(&compressedBuffer);

	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write a OpenGL ES shader program into the log.
 * \param linkOk			Shader program link result, false on failure
 * \param linkInfoLog		Implementation provided linkage log
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_startShaderProgram (qpTestLog* log, deBool linkOk, const char* linkInfoLog)
{
	qpXmlAttribute	programAttribs[4];
	int				numProgramAttribs = 0;

	DE_ASSERT(log);
	deMutex_lock(log->lock);

	programAttribs[numProgramAttribs++] = qpSetStringAttrib("LinkStatus", linkOk ? "OK" : "Fail");

	if (!qpXmlWriter_startElement(log->writer, "ShaderProgram", numProgramAttribs, programAttribs) ||
		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", linkInfoLog))
	{
		qpPrintf("qpTestLog_startShaderProgram(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SHADERPROGRAM));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief End shader program
 * \param log			qpTestLog instance
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_endShaderProgram (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	/* </ShaderProgram> */
	if (!qpXmlWriter_endElement(log->writer, "ShaderProgram"))
	{
		qpPrintf("qpTestLog_endShaderProgram(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SHADERPROGRAM);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write a OpenGL ES shader into the log.
 * \param type				Shader type
 * \param source			Shader source
 * \param compileOk			Shader compilation result, false on failure
 * \param infoLog			Implementation provided shader compilation log
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeShader (qpTestLog* log, qpShaderType type, const char* source, deBool compileOk, const char* infoLog)
{
	const char*		tagName				= QP_LOOKUP_STRING(s_qpShaderTypeMap, type);
	const char*		sourceStr			= ((log->flags & QP_TEST_LOG_EXCLUDE_SHADER_SOURCES) == 0 || !compileOk) ? source : "";
	int				numShaderAttribs	= 0;
	qpXmlAttribute	shaderAttribs[4];

	deMutex_lock(log->lock);

	DE_ASSERT(source);
	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SHADERPROGRAM);

	shaderAttribs[numShaderAttribs++]	= qpSetStringAttrib("CompileStatus", compileOk ? "OK" : "Fail");

	if (!qpXmlWriter_startElement(log->writer, tagName, numShaderAttribs, shaderAttribs) ||
		!qpXmlWriter_writeStringElement(log->writer, "ShaderSource", sourceStr) ||
		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", infoLog) ||
		!qpXmlWriter_endElement(log->writer, tagName))
	{
		qpPrintf("qpTestLog_writeShader(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Start writing a set of EGL configurations into the log.
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_startEglConfigSet (qpTestLog* log, const char* name, const char* description)
{
	qpXmlAttribute	attribs[4];
	int				numAttribs = 0;

	DE_ASSERT(log && name);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	if (description)
		attribs[numAttribs++] = qpSetStringAttrib("Description", description);

	/* <EglConfigSet Name="<name>"> */
	if (!qpXmlWriter_startElement(log->writer, "EglConfigSet", numAttribs, attribs))
	{
		qpPrintf("qpTestLog_startEglImageSet(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_EGLCONFIGSET));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief End an EGL config set
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_endEglConfigSet (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	/* <EglConfigSet Name="<name>"> */
	if (!qpXmlWriter_endElement(log->writer, "EglConfigSet"))
	{
		qpPrintf("qpTestLog_endEglImageSet(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_EGLCONFIGSET);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write an EGL config inside an EGL config set
 * \see   qpElgConfigInfo for details
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeEglConfig (qpTestLog* log, const qpEglConfigInfo* config)
{
	qpXmlAttribute	attribs[64];
	int				numAttribs = 0;

	DE_ASSERT(log && config);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetIntAttrib		("BufferSize", config->bufferSize);
	attribs[numAttribs++] = qpSetIntAttrib		("RedSize", config->redSize);
	attribs[numAttribs++] = qpSetIntAttrib		("GreenSize", config->greenSize);
	attribs[numAttribs++] = qpSetIntAttrib		("BlueSize", config->blueSize);
	attribs[numAttribs++] = qpSetIntAttrib		("LuminanceSize", config->luminanceSize);
	attribs[numAttribs++] = qpSetIntAttrib		("AlphaSize", config->alphaSize);
	attribs[numAttribs++] = qpSetIntAttrib		("AlphaMaskSize", config->alphaMaskSize);
	attribs[numAttribs++] = qpSetBoolAttrib		("BindToTextureRGB", config->bindToTextureRGB);
	attribs[numAttribs++] = qpSetBoolAttrib		("BindToTextureRGBA", config->bindToTextureRGBA);
	attribs[numAttribs++] = qpSetStringAttrib	("ColorBufferType", config->colorBufferType);
	attribs[numAttribs++] = qpSetStringAttrib	("ConfigCaveat", config->configCaveat);
	attribs[numAttribs++] = qpSetIntAttrib		("ConfigID", config->configID);
	attribs[numAttribs++] = qpSetStringAttrib	("Conformant", config->conformant);
	attribs[numAttribs++] = qpSetIntAttrib		("DepthSize", config->depthSize);
	attribs[numAttribs++] = qpSetIntAttrib		("Level", config->level);
	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferWidth", config->maxPBufferWidth);
	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferHeight", config->maxPBufferHeight);
	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferPixels", config->maxPBufferPixels);
	attribs[numAttribs++] = qpSetIntAttrib		("MaxSwapInterval", config->maxSwapInterval);
	attribs[numAttribs++] = qpSetIntAttrib		("MinSwapInterval", config->minSwapInterval);
	attribs[numAttribs++] = qpSetBoolAttrib		("NativeRenderable", config->nativeRenderable);
	attribs[numAttribs++] = qpSetStringAttrib	("RenderableType", config->renderableType);
	attribs[numAttribs++] = qpSetIntAttrib		("SampleBuffers", config->sampleBuffers);
	attribs[numAttribs++] = qpSetIntAttrib		("Samples", config->samples);
	attribs[numAttribs++] = qpSetIntAttrib		("StencilSize", config->stencilSize);
	attribs[numAttribs++] = qpSetStringAttrib	("SurfaceTypes", config->surfaceTypes);
	attribs[numAttribs++] = qpSetStringAttrib	("TransparentType", config->transparentType);
	attribs[numAttribs++] = qpSetIntAttrib		("TransparentRedValue", config->transparentRedValue);
	attribs[numAttribs++] = qpSetIntAttrib		("TransparentGreenValue", config->transparentGreenValue);
	attribs[numAttribs++] = qpSetIntAttrib		("TransparentBlueValue", config->transparentBlueValue);
	DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));

	if (!qpXmlWriter_startElement(log->writer, "EglConfig", numAttribs, attribs) ||
		!qpXmlWriter_endElement(log->writer, "EglConfig"))
	{
		qpPrintf("qpTestLog_writeEglConfig(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Start section in log.
 * \param log			qpTestLog instance
 * \param name			Section name
 * \param description	Human readable description
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_startSection (qpTestLog* log, const char* name, const char* description)
{
	qpXmlAttribute	attribs[2];
	int				numAttribs = 0;

	DE_ASSERT(log && name);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	if (description)
		attribs[numAttribs++] = qpSetStringAttrib("Description", description);

	/* <Section Name="<name>" Description="<description>"> */
	if (!qpXmlWriter_startElement(log->writer, "Section", numAttribs, attribs))
	{
		qpPrintf("qpTestLog_startSection(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SECTION));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief End section in log.
 * \param log			qpTestLog instance
 * \return true if ok, false otherwise
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_endSection (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	/* </Section> */
	if (!qpXmlWriter_endElement(log->writer, "Section"))
	{
		qpPrintf("qpTestLog_endSection(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SECTION);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write OpenCL compute kernel source into the log.
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeKernelSource (qpTestLog* log, const char* source)
{
	const char*		sourceStr	= (log->flags & QP_TEST_LOG_EXCLUDE_SHADER_SOURCES) != 0 ? "" : source;

	DE_ASSERT(log);
	deMutex_lock(log->lock);

	if (!qpXmlWriter_writeStringElement(log->writer, "KernelSource", sourceStr))
	{
		qpPrintf("qpTestLog_writeKernelSource(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write a SPIR-V module assembly source into the log.
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeSpirVAssemblySource (qpTestLog* log, const char* source)
{
	const char* const	sourceStr	= (log->flags & QP_TEST_LOG_EXCLUDE_SHADER_SOURCES) != 0 ? "" : source;

	deMutex_lock(log->lock);

	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SHADERPROGRAM);

	if (!qpXmlWriter_writeStringElement(log->writer, "SpirVAssemblySource", sourceStr))
	{
		qpPrintf("qpTestLog_writeSpirVAssemblySource(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Write OpenCL kernel compilation results into the log
 *//*--------------------------------------------------------------------*/
deBool qpTestLog_writeCompileInfo (qpTestLog* log, const char* name, const char* description, deBool compileOk, const char* infoLog)
{
	int				numAttribs = 0;
	qpXmlAttribute	attribs[3];

	DE_ASSERT(log && name && description && infoLog);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
	attribs[numAttribs++] = qpSetStringAttrib("CompileStatus", compileOk ? "OK" : "Fail");

	if (!qpXmlWriter_startElement(log->writer, "CompileInfo", numAttribs, attribs) ||
		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", infoLog) ||
		!qpXmlWriter_endElement(log->writer, "CompileInfo"))
	{
		qpPrintf("qpTestLog_writeCompileInfo(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_startSampleList (qpTestLog* log, const char* name, const char* description)
{
	int				numAttribs = 0;
	qpXmlAttribute	attribs[2];

	DE_ASSERT(log && name && description);
	deMutex_lock(log->lock);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	attribs[numAttribs++] = qpSetStringAttrib("Description", description);

	if (!qpXmlWriter_startElement(log->writer, "SampleList", numAttribs, attribs))
	{
		qpPrintf("qpTestLog_startSampleList(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLELIST));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_startSampleInfo (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	if (!qpXmlWriter_startElement(log->writer, "SampleInfo", 0, DE_NULL))
	{
		qpPrintf("qpTestLog_startSampleInfo(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLEINFO));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_writeValueInfo (qpTestLog* log, const char* name, const char* description, const char* unit, qpSampleValueTag tag)
{
	const char*		tagName		= QP_LOOKUP_STRING(s_qpSampleValueTagMap, tag);
	int				numAttribs	= 0;
	qpXmlAttribute	attribs[4];

	DE_ASSERT(log && name && description && tagName);
	deMutex_lock(log->lock);

	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLEINFO);

	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
	attribs[numAttribs++] = qpSetStringAttrib("Tag", tagName);

	if (unit)
		attribs[numAttribs++] = qpSetStringAttrib("Unit", unit);

	if (!qpXmlWriter_startElement(log->writer, "ValueInfo", numAttribs, attribs) ||
		!qpXmlWriter_endElement(log->writer, "ValueInfo"))
	{
		qpPrintf("qpTestLog_writeValueInfo(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_endSampleInfo (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	if (!qpXmlWriter_endElement(log->writer, "SampleInfo"))
	{
		qpPrintf("qpTestLog_endSampleInfo(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLEINFO);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_startSample (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLELIST);

	if (!qpXmlWriter_startElement(log->writer, "Sample", 0, DE_NULL))
	{
		qpPrintf("qpTestLog_startSample(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLE));

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_writeValueFloat (qpTestLog* log, double value)
{
	char tmpString[512];
	doubleToString(value, tmpString, (int)sizeof(tmpString));

	deMutex_lock(log->lock);

	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLE);

	if (!qpXmlWriter_writeStringElement(log->writer, "Value", &tmpString[0]))
	{
		qpPrintf("qpTestLog_writeSampleValue(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_writeValueInteger (qpTestLog* log, deInt64 value)
{
	char tmpString[64];
	int64ToString(value, tmpString);

	deMutex_lock(log->lock);

	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLE);

	if (!qpXmlWriter_writeStringElement(log->writer, "Value", &tmpString[0]))
	{
		qpPrintf("qpTestLog_writeSampleValue(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_endSample (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	if (!qpXmlWriter_endElement(log->writer, "Sample"))
	{
		qpPrintf("qpTestLog_endSample(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLE);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deBool qpTestLog_endSampleList (qpTestLog* log)
{
	DE_ASSERT(log);
	deMutex_lock(log->lock);

	if (!qpXmlWriter_endElement(log->writer, "SampleList"))
	{
		qpPrintf("qpTestLog_endSampleList(): Writing XML failed\n");
		deMutex_unlock(log->lock);
		return DE_FALSE;
	}

	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLELIST);

	deMutex_unlock(log->lock);
	return DE_TRUE;
}

deUint32 qpTestLog_getLogFlags (const qpTestLog* log)
{
	DE_ASSERT(log);
	return log->flags;
}

const char* qpGetTestResultName (qpTestResult result)
{
	return QP_LOOKUP_STRING(s_qpTestResultMap, result);
}
