1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Test Executor
3  * ------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Test case list parser.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "xeTestCaseListParser.hpp"
25 #include "deString.h"
26 
27 using std::vector;
28 using std::string;
29 
30 namespace xe
31 {
32 
getTestCaseType(const char * caseType)33 static TestCaseType getTestCaseType (const char* caseType)
34 {
35 	// \todo [2012-06-11 pyry] Use hashes for speedup.
36 	static const struct
37 	{
38 		const char*		name;
39 		TestCaseType	caseType;
40 	} s_caseTypeMap[] =
41 	{
42 		{ "SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
43 		{ "Capability",		TESTCASETYPE_CAPABILITY		},
44 		{ "Accuracy",		TESTCASETYPE_ACCURACY		},
45 		{ "Performance",	TESTCASETYPE_PERFORMANCE	}
46 	};
47 
48 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_caseTypeMap); ndx++)
49 	{
50 		if (deStringEqual(caseType, s_caseTypeMap[ndx].name))
51 			return s_caseTypeMap[ndx].caseType;
52 	}
53 
54 	XE_FAIL((string("Unknown test case type '") + caseType + "'").c_str());
55 }
56 
TestCaseListParser(void)57 TestCaseListParser::TestCaseListParser (void)
58 	: m_root(DE_NULL)
59 {
60 }
61 
~TestCaseListParser(void)62 TestCaseListParser::~TestCaseListParser (void)
63 {
64 }
65 
clear(void)66 void TestCaseListParser::clear (void)
67 {
68 	m_xmlParser.clear();
69 	m_nodeStack.clear();
70 	m_root = DE_NULL;
71 }
72 
init(TestGroup * rootGroup)73 void TestCaseListParser::init (TestGroup* rootGroup)
74 {
75 	clear();
76 	m_root = rootGroup;
77 }
78 
parse(const deUint8 * bytes,int numBytes)79 void TestCaseListParser::parse (const deUint8* bytes, int numBytes)
80 {
81 	DE_ASSERT(m_root);
82 	m_xmlParser.feed(bytes, numBytes);
83 
84 	for (;;)
85 	{
86 		xml::Element element = m_xmlParser.getElement();
87 
88 		if (element == xml::ELEMENT_INCOMPLETE ||
89 			element == xml::ELEMENT_END_OF_STRING)
90 			break;
91 
92 		if (element == xml::ELEMENT_START || element == xml::ELEMENT_END)
93 		{
94 			bool		isStart		= element == xml::ELEMENT_START;
95 			const char* elemName	= m_xmlParser.getElementName();
96 
97 			if (deStringEqual(elemName, "TestCase"))
98 			{
99 				if (isStart)
100 				{
101 					XE_CHECK_MSG(!m_nodeStack.empty(), "<TestCase> outside of <TestCaseList>");
102 
103 					TestNode*		parent		= m_nodeStack.back();
104 					const char*		name		= m_xmlParser.hasAttribute("Name")			? m_xmlParser.getAttribute("Name")			: DE_NULL;
105 					const char*		description	= m_xmlParser.hasAttribute("Description")	? m_xmlParser.getAttribute("Description")	: DE_NULL;
106 					const char*		caseType	= m_xmlParser.hasAttribute("CaseType")		? m_xmlParser.getAttribute("CaseType")		: DE_NULL;
107 
108 					XE_CHECK_MSG(name && description && caseType, "Missing attribute in <TestCase>");
109 					XE_CHECK_MSG(parent->getNodeType() == TESTNODETYPE_GROUP, "Only TestGroups are allowed to have child nodes");
110 
111 					bool			isGroup		= deStringEqual(caseType, "TestGroup") == DE_TRUE;
112 					TestNode*		node		= isGroup ? static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createGroup(name, description))
113 														  : static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createCase(getTestCaseType(caseType), name, description));
114 
115 					m_nodeStack.push_back(node);
116 				}
117 				else
118 				{
119 					XE_CHECK_MSG(m_nodeStack.size() >= 2, "Unexpected </TestCase>");
120 					m_nodeStack.pop_back();
121 				}
122 			}
123 			else if (deStringEqual(elemName, "TestCaseList"))
124 			{
125 				if (isStart)
126 				{
127 					XE_CHECK_MSG(m_nodeStack.empty(), "Unexpected <TestCaseList>");
128 					m_nodeStack.push_back(m_root);
129 				}
130 				else
131 				{
132 					XE_CHECK_MSG(m_nodeStack.size() == 1, "Unexpected </TestCaseList>");
133 					m_nodeStack.pop_back();
134 				}
135 			}
136 			else
137 				XE_FAIL((string("Unexpected <") + elemName + ">").c_str());
138 		}
139 		else if (element != xml::ELEMENT_DATA)
140 			DE_ASSERT(false); // \note Data elements are just ignored, they should be whitespace anyway.
141 
142 		m_xmlParser.advance();
143 	}
144 }
145 
146 } // xe
147