| /*------------------------------------------------------------------------- | 
 |  * 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 |