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
27using std::vector;
28using std::string;
29
30namespace xe
31{
32
33static 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
57TestCaseListParser::TestCaseListParser (void)
58	: m_root(DE_NULL)
59{
60}
61
62TestCaseListParser::~TestCaseListParser (void)
63{
64}
65
66void TestCaseListParser::clear (void)
67{
68	m_xmlParser.clear();
69	m_nodeStack.clear();
70	m_root = DE_NULL;
71}
72
73void TestCaseListParser::init (TestGroup* rootGroup)
74{
75	clear();
76	m_root = rootGroup;
77}
78
79void 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))
113														  : static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createCase(getTestCaseType(caseType), name));
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