C++程序  |  147行  |  4.17 KB

/*-------------------------------------------------------------------------
 * 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 list parser.
 *//*--------------------------------------------------------------------*/

#include "xeTestCaseListParser.hpp"
#include "deString.h"

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

namespace xe
{

static TestCaseType getTestCaseType (const char* caseType)
{
	// \todo [2012-06-11 pyry] Use hashes for speedup.
	static const struct
	{
		const char*		name;
		TestCaseType	caseType;
	} s_caseTypeMap[] =
	{
		{ "SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
		{ "Capability",		TESTCASETYPE_CAPABILITY		},
		{ "Accuracy",		TESTCASETYPE_ACCURACY		},
		{ "Performance",	TESTCASETYPE_PERFORMANCE	}
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_caseTypeMap); ndx++)
	{
		if (deStringEqual(caseType, s_caseTypeMap[ndx].name))
			return s_caseTypeMap[ndx].caseType;
	}

	XE_FAIL((string("Unknown test case type '") + caseType + "'").c_str());
}

TestCaseListParser::TestCaseListParser (void)
	: m_root(DE_NULL)
{
}

TestCaseListParser::~TestCaseListParser (void)
{
}

void TestCaseListParser::clear (void)
{
	m_xmlParser.clear();
	m_nodeStack.clear();
	m_root = DE_NULL;
}

void TestCaseListParser::init (TestGroup* rootGroup)
{
	clear();
	m_root = rootGroup;
}

void TestCaseListParser::parse (const deUint8* bytes, int numBytes)
{
	DE_ASSERT(m_root);
	m_xmlParser.feed(bytes, numBytes);

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

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

		if (element == xml::ELEMENT_START || element == xml::ELEMENT_END)
		{
			bool		isStart		= element == xml::ELEMENT_START;
			const char* elemName	= m_xmlParser.getElementName();

			if (deStringEqual(elemName, "TestCase"))
			{
				if (isStart)
				{
					XE_CHECK_MSG(!m_nodeStack.empty(), "<TestCase> outside of <TestCaseList>");

					TestNode*		parent		= m_nodeStack.back();
					const char*		name		= m_xmlParser.hasAttribute("Name")			? m_xmlParser.getAttribute("Name")			: DE_NULL;
					const char*		description	= m_xmlParser.hasAttribute("Description")	? m_xmlParser.getAttribute("Description")	: DE_NULL;
					const char*		caseType	= m_xmlParser.hasAttribute("CaseType")		? m_xmlParser.getAttribute("CaseType")		: DE_NULL;

					XE_CHECK_MSG(name && description && caseType, "Missing attribute in <TestCase>");
					XE_CHECK_MSG(parent->getNodeType() == TESTNODETYPE_GROUP, "Only TestGroups are allowed to have child nodes");

					bool			isGroup		= deStringEqual(caseType, "TestGroup") == DE_TRUE;
					TestNode*		node		= isGroup ? static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createGroup(name, description))
														  : static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createCase(getTestCaseType(caseType), name, description));

					m_nodeStack.push_back(node);
				}
				else
				{
					XE_CHECK_MSG(m_nodeStack.size() >= 2, "Unexpected </TestCase>");
					m_nodeStack.pop_back();
				}
			}
			else if (deStringEqual(elemName, "TestCaseList"))
			{
				if (isStart)
				{
					XE_CHECK_MSG(m_nodeStack.empty(), "Unexpected <TestCaseList>");
					m_nodeStack.push_back(m_root);
				}
				else
				{
					XE_CHECK_MSG(m_nodeStack.size() == 1, "Unexpected </TestCaseList>");
					m_nodeStack.pop_back();
				}
			}
			else
				XE_FAIL((string("Unexpected <") + elemName + ">").c_str());
		}
		else if (element != xml::ELEMENT_DATA)
			DE_ASSERT(false); // \note Data elements are just ignored, they should be whitespace anyway.

		m_xmlParser.advance();
	}
}

} // xe