1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Test Executor
3e5c31af7Sopenharmony_ci * ------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Test case result parser.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "xeTestResultParser.hpp"
25e5c31af7Sopenharmony_ci#include "xeTestCaseResult.hpp"
26e5c31af7Sopenharmony_ci#include "xeBatchResult.hpp"
27e5c31af7Sopenharmony_ci#include "deString.h"
28e5c31af7Sopenharmony_ci#include "deInt32.h"
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include <sstream>
31e5c31af7Sopenharmony_ci#include <stdlib.h>
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ciusing std::string;
34e5c31af7Sopenharmony_ciusing std::vector;
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cinamespace xe
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_cistatic inline int toInt (const char* str)
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci	return atoi(str);
42e5c31af7Sopenharmony_ci}
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_cistatic inline double toDouble (const char* str)
45e5c31af7Sopenharmony_ci{
46e5c31af7Sopenharmony_ci	return atof(str);
47e5c31af7Sopenharmony_ci}
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_cistatic inline deInt64 toInt64 (const char* str)
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_ci	std::istringstream	s	(str);
52e5c31af7Sopenharmony_ci	deInt64				val;
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_ci	s >> val;
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ci	return val;
57e5c31af7Sopenharmony_ci}
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_cistatic inline bool toBool (const char* str)
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_ci	return deStringEqual(str, "OK") || deStringEqual(str, "True");
62e5c31af7Sopenharmony_ci}
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_cistatic const char* stripLeadingWhitespace (const char* str)
65e5c31af7Sopenharmony_ci{
66e5c31af7Sopenharmony_ci	int whitespaceCount = 0;
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci	while (str[whitespaceCount]	!= 0	&&
69e5c31af7Sopenharmony_ci		   (str[whitespaceCount] == ' '		||
70e5c31af7Sopenharmony_ci			str[whitespaceCount] == '\t'	||
71e5c31af7Sopenharmony_ci			str[whitespaceCount] == '\r'	||
72e5c31af7Sopenharmony_ci			str[whitespaceCount] == '\n'))
73e5c31af7Sopenharmony_ci		whitespaceCount += 1;
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	return str + whitespaceCount;
76e5c31af7Sopenharmony_ci}
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_cistruct EnumMapEntry
79e5c31af7Sopenharmony_ci{
80e5c31af7Sopenharmony_ci	deUint32		hash;
81e5c31af7Sopenharmony_ci	const char*		name;
82e5c31af7Sopenharmony_ci	int				value;
83e5c31af7Sopenharmony_ci};
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_cistatic const EnumMapEntry s_statusCodeMap[] =
86e5c31af7Sopenharmony_ci{
87e5c31af7Sopenharmony_ci	{ 0x7c8a99bc,	"Pass",					TESTSTATUSCODE_PASS						},
88e5c31af7Sopenharmony_ci	{ 0x7c851ca1,	"Fail",					TESTSTATUSCODE_FAIL						},
89e5c31af7Sopenharmony_ci	{ 0x10ecd324,	"QualityWarning",		TESTSTATUSCODE_QUALITY_WARNING			},
90e5c31af7Sopenharmony_ci	{ 0x341ae835,	"CompatibilityWarning",	TESTSTATUSCODE_COMPATIBILITY_WARNING	},
91e5c31af7Sopenharmony_ci	{ 0x058acbca,	"Pending",				TESTSTATUSCODE_PENDING					},
92e5c31af7Sopenharmony_ci	{ 0xc4d74b26,	"Running",				TESTSTATUSCODE_RUNNING					},
93e5c31af7Sopenharmony_ci	{ 0x6409f93c,	"NotSupported",			TESTSTATUSCODE_NOT_SUPPORTED			},
94e5c31af7Sopenharmony_ci	{ 0xfa5a9ab7,	"ResourceError",		TESTSTATUSCODE_RESOURCE_ERROR			},
95e5c31af7Sopenharmony_ci	{ 0xad6793ec,	"InternalError",		TESTSTATUSCODE_INTERNAL_ERROR			},
96e5c31af7Sopenharmony_ci	{ 0x838f3034,	"Canceled",				TESTSTATUSCODE_CANCELED					},
97e5c31af7Sopenharmony_ci	{ 0x42b6efac,	"Timeout",				TESTSTATUSCODE_TIMEOUT					},
98e5c31af7Sopenharmony_ci	{ 0x0cfb98f6,	"Crash",				TESTSTATUSCODE_CRASH					},
99e5c31af7Sopenharmony_ci	{ 0xe326e01d,	"Disabled",				TESTSTATUSCODE_DISABLED					},
100e5c31af7Sopenharmony_ci	{ 0x77061af2,	"Terminated",			TESTSTATUSCODE_TERMINATED				},
101e5c31af7Sopenharmony_ci	{ 0xd9e6b393,	"Waiver",			    TESTSTATUSCODE_WAIVER				    }
102e5c31af7Sopenharmony_ci};
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_cistatic const EnumMapEntry s_resultItemMap[] =
105e5c31af7Sopenharmony_ci{
106e5c31af7Sopenharmony_ci	{ 0xce8ac2e4,	"Result",				ri::TYPE_RESULT			},
107e5c31af7Sopenharmony_ci	{ 0x7c8cdcea,	"Text",					ri::TYPE_TEXT			},
108e5c31af7Sopenharmony_ci	{ 0xc6540c6e,	"Number",				ri::TYPE_NUMBER			},
109e5c31af7Sopenharmony_ci	{ 0x0d656c88,	"Image",				ri::TYPE_IMAGE			},
110e5c31af7Sopenharmony_ci	{ 0x8ac9ee14,	"ImageSet",				ri::TYPE_IMAGESET		},
111e5c31af7Sopenharmony_ci	{ 0x1181fa5a,	"VertexShader",			ri::TYPE_SHADER			},
112e5c31af7Sopenharmony_ci	{ 0xa93daef0,	"FragmentShader",		ri::TYPE_SHADER			},
113e5c31af7Sopenharmony_ci	{ 0x8f066128,	"GeometryShader",		ri::TYPE_SHADER			},
114e5c31af7Sopenharmony_ci	{ 0x235a931c,	"TessControlShader",	ri::TYPE_SHADER			},
115e5c31af7Sopenharmony_ci	{ 0xa1bf7153,	"TessEvaluationShader",	ri::TYPE_SHADER			},
116e5c31af7Sopenharmony_ci	{ 0x6c1415d9,	"ComputeShader",		ri::TYPE_SHADER			},
117e5c31af7Sopenharmony_ci	{ 0x68738b22,	"RaygenShader",			ri::TYPE_SHADER			},
118e5c31af7Sopenharmony_ci	{ 0x51d29ce9,	"AnyHitShader",			ri::TYPE_SHADER			},
119e5c31af7Sopenharmony_ci	{ 0x8c64a6be,	"ClosestHitShader",		ri::TYPE_SHADER			},
120e5c31af7Sopenharmony_ci	{ 0xb30ed398,	"MissShader",			ri::TYPE_SHADER			},
121e5c31af7Sopenharmony_ci	{ 0x26150e53,	"IntersectionShader",	ri::TYPE_SHADER			},
122e5c31af7Sopenharmony_ci	{ 0x7e50944c,	"CallableShader",		ri::TYPE_SHADER			},
123e5c31af7Sopenharmony_ci	{ 0x925c7349,	"MeshShader",			ri::TYPE_SHADER			},
124e5c31af7Sopenharmony_ci	{ 0xc3a35d6f,	"TaskShader",			ri::TYPE_SHADER			},
125e5c31af7Sopenharmony_ci	{ 0x72863a54,	"ShaderProgram",		ri::TYPE_SHADERPROGRAM	},
126e5c31af7Sopenharmony_ci	{ 0xb4efc08d,	"ShaderSource",			ri::TYPE_SHADERSOURCE	},
127e5c31af7Sopenharmony_ci	{ 0xaee4380a,	"SpirVAssemblySource",	ri::TYPE_SPIRVSOURCE	},
128e5c31af7Sopenharmony_ci	{ 0xff265913,	"InfoLog",				ri::TYPE_INFOLOG		},
129e5c31af7Sopenharmony_ci	{ 0x84159b73,	"EglConfig",			ri::TYPE_EGLCONFIG		},
130e5c31af7Sopenharmony_ci	{ 0xdd34391f,	"EglConfigSet",			ri::TYPE_EGLCONFIGSET	},
131e5c31af7Sopenharmony_ci	{ 0xebbb3aba,	"Section",				ri::TYPE_SECTION		},
132e5c31af7Sopenharmony_ci	{ 0xa0f15677,	"KernelSource",			ri::TYPE_KERNELSOURCE	},
133e5c31af7Sopenharmony_ci	{ 0x1ee9083a,	"CompileInfo",			ri::TYPE_COMPILEINFO	},
134e5c31af7Sopenharmony_ci	{ 0xf1004023,	"SampleList",			ri::TYPE_SAMPLELIST		},
135e5c31af7Sopenharmony_ci	{ 0xf0feae93,	"SampleInfo",			ri::TYPE_SAMPLEINFO		},
136e5c31af7Sopenharmony_ci	{ 0x2aa6f14e,	"ValueInfo",			ri::TYPE_VALUEINFO		},
137e5c31af7Sopenharmony_ci	{ 0xd09429e7,	"Sample",				ri::TYPE_SAMPLE			},
138e5c31af7Sopenharmony_ci	{ 0x0e4a4722,	"Value",				ri::TYPE_SAMPLEVALUE	}
139e5c31af7Sopenharmony_ci};
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_cistatic const EnumMapEntry s_imageFormatMap[] =
142e5c31af7Sopenharmony_ci{
143e5c31af7Sopenharmony_ci	{ 0xcc4ffac8,	"RGB888",		ri::Image::FORMAT_RGB888	},
144e5c31af7Sopenharmony_ci	{ 0x20dcb0c1,	"RGBA8888",		ri::Image::FORMAT_RGBA8888	}
145e5c31af7Sopenharmony_ci};
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_cistatic const EnumMapEntry s_compressionMap[] =
148e5c31af7Sopenharmony_ci{
149e5c31af7Sopenharmony_ci	{ 0x7c89bbd5,	"None",			ri::Image::COMPRESSION_NONE	},
150e5c31af7Sopenharmony_ci	{ 0x0b88118a,	"PNG",			ri::Image::COMPRESSION_PNG	}
151e5c31af7Sopenharmony_ci};
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_cistatic const EnumMapEntry s_shaderTypeFromTagMap[] =
154e5c31af7Sopenharmony_ci{
155e5c31af7Sopenharmony_ci	{ 0x1181fa5a,	"VertexShader",			ri::Shader::SHADERTYPE_VERTEX			},
156e5c31af7Sopenharmony_ci	{ 0xa93daef0,	"FragmentShader",		ri::Shader::SHADERTYPE_FRAGMENT			},
157e5c31af7Sopenharmony_ci	{ 0x8f066128,	"GeometryShader",		ri::Shader::SHADERTYPE_GEOMETRY			},
158e5c31af7Sopenharmony_ci	{ 0x235a931c,	"TessControlShader",	ri::Shader::SHADERTYPE_TESS_CONTROL		},
159e5c31af7Sopenharmony_ci	{ 0xa1bf7153,	"TessEvaluationShader",	ri::Shader::SHADERTYPE_TESS_EVALUATION	},
160e5c31af7Sopenharmony_ci	{ 0x6c1415d9,	"ComputeShader",		ri::Shader::SHADERTYPE_COMPUTE			},
161e5c31af7Sopenharmony_ci	{ 0x68738b22,	"RaygenShader",			ri::Shader::SHADERTYPE_RAYGEN			},
162e5c31af7Sopenharmony_ci	{ 0x51d29ce9,	"AnyHitShader",			ri::Shader::SHADERTYPE_ANY_HIT			},
163e5c31af7Sopenharmony_ci	{ 0x8c64a6be,	"ClosestHitShader",		ri::Shader::SHADERTYPE_CLOSEST_HIT		},
164e5c31af7Sopenharmony_ci	{ 0xb30ed398,	"MissShader",			ri::Shader::SHADERTYPE_MISS				},
165e5c31af7Sopenharmony_ci	{ 0x26150e53,	"IntersectionShader",	ri::Shader::SHADERTYPE_INTERSECTION		},
166e5c31af7Sopenharmony_ci	{ 0x7e50944c,	"CallableShader",		ri::Shader::SHADERTYPE_CALLABLE			},
167e5c31af7Sopenharmony_ci	{ 0xc3a35d6f,	"TaskShader",			ri::Shader::SHADERTYPE_TASK				},
168e5c31af7Sopenharmony_ci	{ 0x925c7349,	"MeshShader",			ri::Shader::SHADERTYPE_MESH				},
169e5c31af7Sopenharmony_ci};
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_cistatic const EnumMapEntry s_testTypeMap[] =
172e5c31af7Sopenharmony_ci{
173e5c31af7Sopenharmony_ci	{ 0x7fa80959,	"SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
174e5c31af7Sopenharmony_ci	{ 0xdb797567,	"Capability",	TESTCASETYPE_CAPABILITY		},
175e5c31af7Sopenharmony_ci	{ 0x2ca3ec10,	"Accuracy",		TESTCASETYPE_ACCURACY		},
176e5c31af7Sopenharmony_ci	{ 0xa48ac277,	"Performance",	TESTCASETYPE_PERFORMANCE	}
177e5c31af7Sopenharmony_ci};
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_cistatic const EnumMapEntry s_logVersionMap[] =
180e5c31af7Sopenharmony_ci{
181e5c31af7Sopenharmony_ci	{ 0x0b7dac93,	"0.2.0",		TESTLOGVERSION_0_2_0	},
182e5c31af7Sopenharmony_ci	{ 0x0b7db0d4,	"0.3.0",		TESTLOGVERSION_0_3_0	},
183e5c31af7Sopenharmony_ci	{ 0x0b7db0d5,	"0.3.1",		TESTLOGVERSION_0_3_1	},
184e5c31af7Sopenharmony_ci	{ 0x0b7db0d6,	"0.3.2",		TESTLOGVERSION_0_3_2	},
185e5c31af7Sopenharmony_ci	{ 0x0b7db0d7,	"0.3.3",		TESTLOGVERSION_0_3_3	},
186e5c31af7Sopenharmony_ci	{ 0x0b7db0d8,	"0.3.4",		TESTLOGVERSION_0_3_4	}
187e5c31af7Sopenharmony_ci};
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_cistatic const EnumMapEntry s_sampleValueTagMap[] =
190e5c31af7Sopenharmony_ci{
191e5c31af7Sopenharmony_ci	{ 0xddf2d0d1,	"Predictor",	ri::ValueInfo::VALUETAG_PREDICTOR	},
192e5c31af7Sopenharmony_ci	{ 0x9bee2c34,	"Response",		ri::ValueInfo::VALUETAG_RESPONSE	},
193e5c31af7Sopenharmony_ci};
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci#if defined(DE_DEBUG)
196e5c31af7Sopenharmony_cistatic void printHashes (const char* name, const EnumMapEntry* entries, int numEntries)
197e5c31af7Sopenharmony_ci{
198e5c31af7Sopenharmony_ci	printf("%s:\n", name);
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numEntries; ndx++)
201e5c31af7Sopenharmony_ci		printf("0x%08x\t%s\n", deStringHash(entries[ndx].name), entries[ndx].name);
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	printf("\n");
204e5c31af7Sopenharmony_ci}
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci#define PRINT_HASHES(MAP) printHashes(#MAP, MAP, DE_LENGTH_OF_ARRAY(MAP))
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_civoid TestResultParser_printHashes (void)
209e5c31af7Sopenharmony_ci{
210e5c31af7Sopenharmony_ci	PRINT_HASHES(s_statusCodeMap);
211e5c31af7Sopenharmony_ci	PRINT_HASHES(s_resultItemMap);
212e5c31af7Sopenharmony_ci	PRINT_HASHES(s_imageFormatMap);
213e5c31af7Sopenharmony_ci	PRINT_HASHES(s_compressionMap);
214e5c31af7Sopenharmony_ci	PRINT_HASHES(s_shaderTypeFromTagMap);
215e5c31af7Sopenharmony_ci	PRINT_HASHES(s_testTypeMap);
216e5c31af7Sopenharmony_ci	PRINT_HASHES(s_logVersionMap);
217e5c31af7Sopenharmony_ci	PRINT_HASHES(s_sampleValueTagMap);
218e5c31af7Sopenharmony_ci}
219e5c31af7Sopenharmony_ci#endif
220e5c31af7Sopenharmony_ci
221e5c31af7Sopenharmony_cistatic inline int getEnumValue (const char* enumName, const EnumMapEntry* entries, int numEntries, const char* name)
222e5c31af7Sopenharmony_ci{
223e5c31af7Sopenharmony_ci	deUint32 hash = deStringHash(name);
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numEntries; ndx++)
226e5c31af7Sopenharmony_ci	{
227e5c31af7Sopenharmony_ci		if (entries[ndx].hash == hash && deStringEqual(entries[ndx].name, name))
228e5c31af7Sopenharmony_ci			return entries[ndx].value;
229e5c31af7Sopenharmony_ci	}
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci	throw TestResultParseError(string("Could not map '") + name + "' to " + enumName);
232e5c31af7Sopenharmony_ci}
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ciTestStatusCode getTestStatusCode (const char* statusCode)
235e5c31af7Sopenharmony_ci{
236e5c31af7Sopenharmony_ci	return (TestStatusCode)getEnumValue("status code", s_statusCodeMap, DE_LENGTH_OF_ARRAY(s_statusCodeMap), statusCode);
237e5c31af7Sopenharmony_ci}
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_cistatic ri::Type getResultItemType (const char* elemName)
240e5c31af7Sopenharmony_ci{
241e5c31af7Sopenharmony_ci	return (ri::Type)getEnumValue("result item type", s_resultItemMap, DE_LENGTH_OF_ARRAY(s_resultItemMap), elemName);
242e5c31af7Sopenharmony_ci}
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_cistatic ri::Image::Format getImageFormat (const char* imageFormat)
245e5c31af7Sopenharmony_ci{
246e5c31af7Sopenharmony_ci	return (ri::Image::Format)getEnumValue("image format", s_imageFormatMap, DE_LENGTH_OF_ARRAY(s_imageFormatMap), imageFormat);
247e5c31af7Sopenharmony_ci}
248e5c31af7Sopenharmony_ci
249e5c31af7Sopenharmony_cistatic ri::Image::Compression getImageCompression (const char* compression)
250e5c31af7Sopenharmony_ci{
251e5c31af7Sopenharmony_ci	return (ri::Image::Compression)getEnumValue("image compression", s_compressionMap, DE_LENGTH_OF_ARRAY(s_compressionMap), compression);
252e5c31af7Sopenharmony_ci}
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_cistatic ri::Shader::ShaderType getShaderTypeFromTagName (const char* shaderType)
255e5c31af7Sopenharmony_ci{
256e5c31af7Sopenharmony_ci	return (ri::Shader::ShaderType)getEnumValue("shader type", s_shaderTypeFromTagMap, DE_LENGTH_OF_ARRAY(s_shaderTypeFromTagMap), shaderType);
257e5c31af7Sopenharmony_ci}
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_cistatic TestCaseType getTestCaseType (const char* caseType)
260e5c31af7Sopenharmony_ci{
261e5c31af7Sopenharmony_ci	return (TestCaseType)getEnumValue("test case type", s_testTypeMap, DE_LENGTH_OF_ARRAY(s_testTypeMap), caseType);
262e5c31af7Sopenharmony_ci}
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_cistatic TestLogVersion getTestLogVersion (const char* logVersion)
265e5c31af7Sopenharmony_ci{
266e5c31af7Sopenharmony_ci	return (TestLogVersion)getEnumValue("test log version", s_logVersionMap, DE_LENGTH_OF_ARRAY(s_logVersionMap), logVersion);
267e5c31af7Sopenharmony_ci}
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_cistatic ri::ValueInfo::ValueTag getSampleValueTag (const char* tag)
270e5c31af7Sopenharmony_ci{
271e5c31af7Sopenharmony_ci	return (ri::ValueInfo::ValueTag)getEnumValue("sample value tag", s_sampleValueTagMap, DE_LENGTH_OF_ARRAY(s_sampleValueTagMap), tag);
272e5c31af7Sopenharmony_ci}
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_cistatic TestCaseType getTestCaseTypeFromPath (const char* casePath)
275e5c31af7Sopenharmony_ci{
276e5c31af7Sopenharmony_ci	if (deStringBeginsWith(casePath, "dEQP-GLES2."))
277e5c31af7Sopenharmony_ci	{
278e5c31af7Sopenharmony_ci		const char* group = casePath+11;
279e5c31af7Sopenharmony_ci		if (deStringBeginsWith(group, "capability."))
280e5c31af7Sopenharmony_ci			return TESTCASETYPE_CAPABILITY;
281e5c31af7Sopenharmony_ci		else if (deStringBeginsWith(group, "accuracy."))
282e5c31af7Sopenharmony_ci			return TESTCASETYPE_ACCURACY;
283e5c31af7Sopenharmony_ci		else if (deStringBeginsWith(group, "performance."))
284e5c31af7Sopenharmony_ci			return TESTCASETYPE_PERFORMANCE;
285e5c31af7Sopenharmony_ci	}
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci	return TESTCASETYPE_SELF_VALIDATE;
288e5c31af7Sopenharmony_ci}
289e5c31af7Sopenharmony_ci
290e5c31af7Sopenharmony_cistatic ri::NumericValue getNumericValue (const std::string& value)
291e5c31af7Sopenharmony_ci{
292e5c31af7Sopenharmony_ci	const bool	isFloat		= value.find('.') != std::string::npos || value.find('e') != std::string::npos;
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ci	if (isFloat)
295e5c31af7Sopenharmony_ci	{
296e5c31af7Sopenharmony_ci		const double num = toDouble(stripLeadingWhitespace(value.c_str()));
297e5c31af7Sopenharmony_ci		return ri::NumericValue(num);
298e5c31af7Sopenharmony_ci	}
299e5c31af7Sopenharmony_ci	else
300e5c31af7Sopenharmony_ci	{
301e5c31af7Sopenharmony_ci		const deInt64 num = toInt64(stripLeadingWhitespace(value.c_str()));
302e5c31af7Sopenharmony_ci		return ri::NumericValue(num);
303e5c31af7Sopenharmony_ci	}
304e5c31af7Sopenharmony_ci}
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ciTestResultParser::TestResultParser (void)
307e5c31af7Sopenharmony_ci	: m_result				(DE_NULL)
308e5c31af7Sopenharmony_ci	, m_state				(STATE_NOT_INITIALIZED)
309e5c31af7Sopenharmony_ci	, m_logVersion			(TESTLOGVERSION_LAST)
310e5c31af7Sopenharmony_ci	, m_curItemList			(DE_NULL)
311e5c31af7Sopenharmony_ci	, m_base64DecodeOffset	(0)
312e5c31af7Sopenharmony_ci{
313e5c31af7Sopenharmony_ci}
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ciTestResultParser::~TestResultParser (void)
316e5c31af7Sopenharmony_ci{
317e5c31af7Sopenharmony_ci}
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_civoid TestResultParser::clear (void)
320e5c31af7Sopenharmony_ci{
321e5c31af7Sopenharmony_ci	m_xmlParser.clear();
322e5c31af7Sopenharmony_ci	m_itemStack.clear();
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	m_result				= DE_NULL;
325e5c31af7Sopenharmony_ci	m_state					= STATE_NOT_INITIALIZED;
326e5c31af7Sopenharmony_ci	m_logVersion			= TESTLOGVERSION_LAST;
327e5c31af7Sopenharmony_ci	m_curItemList			= DE_NULL;
328e5c31af7Sopenharmony_ci	m_base64DecodeOffset	= 0;
329e5c31af7Sopenharmony_ci	m_curNumValue.clear();
330e5c31af7Sopenharmony_ci}
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_civoid TestResultParser::init (TestCaseResult* dstResult)
333e5c31af7Sopenharmony_ci{
334e5c31af7Sopenharmony_ci	clear();
335e5c31af7Sopenharmony_ci	m_result		= dstResult;
336e5c31af7Sopenharmony_ci	m_state			= STATE_INITIALIZED;
337e5c31af7Sopenharmony_ci	m_curItemList	= &dstResult->resultItems;
338e5c31af7Sopenharmony_ci}
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_ciTestResultParser::ParseResult TestResultParser::parse (const deUint8* bytes, int numBytes)
341e5c31af7Sopenharmony_ci{
342e5c31af7Sopenharmony_ci	DE_ASSERT(m_result && m_state != STATE_NOT_INITIALIZED);
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci	try
345e5c31af7Sopenharmony_ci	{
346e5c31af7Sopenharmony_ci		bool resultChanged = false;
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_ci		m_xmlParser.feed(bytes, numBytes);
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci		for (;;)
351e5c31af7Sopenharmony_ci		{
352e5c31af7Sopenharmony_ci			xml::Element curElement = m_xmlParser.getElement();
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci			if (curElement == xml::ELEMENT_INCOMPLETE	||
355e5c31af7Sopenharmony_ci				curElement == xml::ELEMENT_END_OF_STRING)
356e5c31af7Sopenharmony_ci				break;
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci			switch (curElement)
359e5c31af7Sopenharmony_ci			{
360e5c31af7Sopenharmony_ci				case xml::ELEMENT_START:	handleElementStart();		break;
361e5c31af7Sopenharmony_ci				case xml::ELEMENT_END:		handleElementEnd();			break;
362e5c31af7Sopenharmony_ci				case xml::ELEMENT_DATA:		handleData();				break;
363e5c31af7Sopenharmony_ci
364e5c31af7Sopenharmony_ci				default:
365e5c31af7Sopenharmony_ci					DE_ASSERT(false);
366e5c31af7Sopenharmony_ci			}
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci			resultChanged = true;
369e5c31af7Sopenharmony_ci			m_xmlParser.advance();
370e5c31af7Sopenharmony_ci		}
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_ci		if (m_xmlParser.getElement() == xml::ELEMENT_END_OF_STRING)
373e5c31af7Sopenharmony_ci		{
374e5c31af7Sopenharmony_ci			if (m_state != STATE_TEST_CASE_RESULT_ENDED)
375e5c31af7Sopenharmony_ci				throw TestResultParseError("Unexpected end of log data");
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci			return PARSERESULT_COMPLETE;
378e5c31af7Sopenharmony_ci		}
379e5c31af7Sopenharmony_ci		else
380e5c31af7Sopenharmony_ci			return resultChanged ? PARSERESULT_CHANGED
381e5c31af7Sopenharmony_ci								 : PARSERESULT_NOT_CHANGED;
382e5c31af7Sopenharmony_ci	}
383e5c31af7Sopenharmony_ci	catch (const TestResultParseError& e)
384e5c31af7Sopenharmony_ci	{
385e5c31af7Sopenharmony_ci		// Set error code to result.
386e5c31af7Sopenharmony_ci		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
387e5c31af7Sopenharmony_ci		m_result->statusDetails	= e.what();
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci		return PARSERESULT_ERROR;
390e5c31af7Sopenharmony_ci	}
391e5c31af7Sopenharmony_ci	catch (const xml::ParseError& e)
392e5c31af7Sopenharmony_ci	{
393e5c31af7Sopenharmony_ci		// Set error code to result.
394e5c31af7Sopenharmony_ci		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
395e5c31af7Sopenharmony_ci		m_result->statusDetails	= e.what();
396e5c31af7Sopenharmony_ci
397e5c31af7Sopenharmony_ci		return PARSERESULT_ERROR;
398e5c31af7Sopenharmony_ci	}
399e5c31af7Sopenharmony_ci}
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_ciconst char* TestResultParser::getAttribute (const char* name)
402e5c31af7Sopenharmony_ci{
403e5c31af7Sopenharmony_ci	if (!m_xmlParser.hasAttribute(name))
404e5c31af7Sopenharmony_ci		throw TestResultParseError(string("Missing attribute '") + name + "' in <" + m_xmlParser.getElementName() + ">");
405e5c31af7Sopenharmony_ci
406e5c31af7Sopenharmony_ci	return m_xmlParser.getAttribute(name);
407e5c31af7Sopenharmony_ci}
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ciri::Item* TestResultParser::getCurrentItem (void)
410e5c31af7Sopenharmony_ci{
411e5c31af7Sopenharmony_ci	return !m_itemStack.empty() ? m_itemStack.back() : DE_NULL;
412e5c31af7Sopenharmony_ci}
413e5c31af7Sopenharmony_ci
414e5c31af7Sopenharmony_ciri::List* TestResultParser::getCurrentItemList (void)
415e5c31af7Sopenharmony_ci{
416e5c31af7Sopenharmony_ci	DE_ASSERT(m_curItemList);
417e5c31af7Sopenharmony_ci	return m_curItemList;
418e5c31af7Sopenharmony_ci}
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_civoid TestResultParser::updateCurrentItemList (void)
421e5c31af7Sopenharmony_ci{
422e5c31af7Sopenharmony_ci	m_curItemList = DE_NULL;
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	for (vector<ri::Item*>::reverse_iterator i = m_itemStack.rbegin(); i != m_itemStack.rend(); i++)
425e5c31af7Sopenharmony_ci	{
426e5c31af7Sopenharmony_ci		ri::Item*	item	= *i;
427e5c31af7Sopenharmony_ci		ri::Type	type	= item->getType();
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci		if (type == ri::TYPE_IMAGESET)
430e5c31af7Sopenharmony_ci			m_curItemList = &static_cast<ri::ImageSet*>(item)->images;
431e5c31af7Sopenharmony_ci		else if (type == ri::TYPE_SECTION)
432e5c31af7Sopenharmony_ci			m_curItemList = &static_cast<ri::Section*>(item)->items;
433e5c31af7Sopenharmony_ci		else if (type == ri::TYPE_EGLCONFIGSET)
434e5c31af7Sopenharmony_ci			m_curItemList = &static_cast<ri::EglConfigSet*>(item)->configs;
435e5c31af7Sopenharmony_ci		else if (type == ri::TYPE_SHADERPROGRAM)
436e5c31af7Sopenharmony_ci			m_curItemList = &static_cast<ri::ShaderProgram*>(item)->shaders;
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_ci		if (m_curItemList)
439e5c31af7Sopenharmony_ci			break;
440e5c31af7Sopenharmony_ci	}
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_ci	if (!m_curItemList)
443e5c31af7Sopenharmony_ci		m_curItemList = &m_result->resultItems;
444e5c31af7Sopenharmony_ci}
445e5c31af7Sopenharmony_ci
446e5c31af7Sopenharmony_civoid TestResultParser::pushItem (ri::Item* item)
447e5c31af7Sopenharmony_ci{
448e5c31af7Sopenharmony_ci	m_itemStack.push_back(item);
449e5c31af7Sopenharmony_ci	updateCurrentItemList();
450e5c31af7Sopenharmony_ci}
451e5c31af7Sopenharmony_ci
452e5c31af7Sopenharmony_civoid TestResultParser::popItem (void)
453e5c31af7Sopenharmony_ci{
454e5c31af7Sopenharmony_ci	m_itemStack.pop_back();
455e5c31af7Sopenharmony_ci	updateCurrentItemList();
456e5c31af7Sopenharmony_ci}
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_civoid TestResultParser::handleElementStart (void)
459e5c31af7Sopenharmony_ci{
460e5c31af7Sopenharmony_ci	const char* elemName = m_xmlParser.getElementName();
461e5c31af7Sopenharmony_ci
462e5c31af7Sopenharmony_ci	if (m_state == STATE_INITIALIZED)
463e5c31af7Sopenharmony_ci	{
464e5c31af7Sopenharmony_ci		// Expect TestCaseResult.
465e5c31af7Sopenharmony_ci		if (!deStringEqual(elemName, "TestCaseResult"))
466e5c31af7Sopenharmony_ci			throw TestResultParseError(string("Expected <TestCaseResult>, got <") + elemName + ">");
467e5c31af7Sopenharmony_ci
468e5c31af7Sopenharmony_ci		const char* version = getAttribute("Version");
469e5c31af7Sopenharmony_ci		m_logVersion = getTestLogVersion(version);
470e5c31af7Sopenharmony_ci		// \note Currently assumed that all known log versions are supported.
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ci		m_result->caseVersion	= version;
473e5c31af7Sopenharmony_ci		m_result->casePath		= getAttribute("CasePath");
474e5c31af7Sopenharmony_ci		m_result->caseType		= TESTCASETYPE_SELF_VALIDATE;
475e5c31af7Sopenharmony_ci
476e5c31af7Sopenharmony_ci		if (m_xmlParser.hasAttribute("CaseType"))
477e5c31af7Sopenharmony_ci			m_result->caseType = getTestCaseType(m_xmlParser.getAttribute("CaseType"));
478e5c31af7Sopenharmony_ci		else
479e5c31af7Sopenharmony_ci		{
480e5c31af7Sopenharmony_ci			// Do guess based on path for legacy log files.
481e5c31af7Sopenharmony_ci			if (m_logVersion >= TESTLOGVERSION_0_3_2)
482e5c31af7Sopenharmony_ci				throw TestResultParseError("Missing CaseType attribute in <TestCaseResult>");
483e5c31af7Sopenharmony_ci			m_result->caseType = getTestCaseTypeFromPath(m_result->casePath.c_str());
484e5c31af7Sopenharmony_ci		}
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_ci		m_state = STATE_IN_TEST_CASE_RESULT;
487e5c31af7Sopenharmony_ci	}
488e5c31af7Sopenharmony_ci	else
489e5c31af7Sopenharmony_ci	{
490e5c31af7Sopenharmony_ci		ri::List*	curList		= getCurrentItemList();
491e5c31af7Sopenharmony_ci		ri::Type	itemType	= getResultItemType(elemName);
492e5c31af7Sopenharmony_ci		ri::Item*	item		= DE_NULL;
493e5c31af7Sopenharmony_ci		ri::Item*	parentItem	= getCurrentItem();
494e5c31af7Sopenharmony_ci		ri::Type	parentType	= parentItem ? parentItem->getType() : ri::TYPE_LAST;
495e5c31af7Sopenharmony_ci
496e5c31af7Sopenharmony_ci		switch (itemType)
497e5c31af7Sopenharmony_ci		{
498e5c31af7Sopenharmony_ci			case ri::TYPE_RESULT:
499e5c31af7Sopenharmony_ci			{
500e5c31af7Sopenharmony_ci				ri::Result* result = curList->allocItem<ri::Result>();
501e5c31af7Sopenharmony_ci				result->statusCode = getTestStatusCode(getAttribute("StatusCode"));
502e5c31af7Sopenharmony_ci				item = result;
503e5c31af7Sopenharmony_ci				break;
504e5c31af7Sopenharmony_ci			}
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci			case ri::TYPE_TEXT:
507e5c31af7Sopenharmony_ci				item = curList->allocItem<ri::Text>();
508e5c31af7Sopenharmony_ci				break;
509e5c31af7Sopenharmony_ci
510e5c31af7Sopenharmony_ci			case ri::TYPE_SECTION:
511e5c31af7Sopenharmony_ci			{
512e5c31af7Sopenharmony_ci				ri::Section* section = curList->allocItem<ri::Section>();
513e5c31af7Sopenharmony_ci				section->name			= getAttribute("Name");
514e5c31af7Sopenharmony_ci				section->description	= getAttribute("Description");
515e5c31af7Sopenharmony_ci				item = section;
516e5c31af7Sopenharmony_ci				break;
517e5c31af7Sopenharmony_ci			}
518e5c31af7Sopenharmony_ci
519e5c31af7Sopenharmony_ci			case ri::TYPE_NUMBER:
520e5c31af7Sopenharmony_ci			{
521e5c31af7Sopenharmony_ci				ri::Number* number = curList->allocItem<ri::Number>();
522e5c31af7Sopenharmony_ci				number->name		= getAttribute("Name");
523e5c31af7Sopenharmony_ci				number->description	= getAttribute("Description");
524e5c31af7Sopenharmony_ci				number->unit		= getAttribute("Unit");
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_ci				if (m_xmlParser.hasAttribute("Tag"))
527e5c31af7Sopenharmony_ci					number->tag = m_xmlParser.getAttribute("Tag");
528e5c31af7Sopenharmony_ci
529e5c31af7Sopenharmony_ci				item = number;
530e5c31af7Sopenharmony_ci
531e5c31af7Sopenharmony_ci				m_curNumValue.clear();
532e5c31af7Sopenharmony_ci				break;
533e5c31af7Sopenharmony_ci			}
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ci			case ri::TYPE_IMAGESET:
536e5c31af7Sopenharmony_ci			{
537e5c31af7Sopenharmony_ci				ri::ImageSet* imageSet = curList->allocItem<ri::ImageSet>();
538e5c31af7Sopenharmony_ci				imageSet->name			= getAttribute("Name");
539e5c31af7Sopenharmony_ci				imageSet->description	= getAttribute("Description");
540e5c31af7Sopenharmony_ci				item = imageSet;
541e5c31af7Sopenharmony_ci				break;
542e5c31af7Sopenharmony_ci			}
543e5c31af7Sopenharmony_ci
544e5c31af7Sopenharmony_ci			case ri::TYPE_IMAGE:
545e5c31af7Sopenharmony_ci			{
546e5c31af7Sopenharmony_ci				ri::Image* image = curList->allocItem<ri::Image>();
547e5c31af7Sopenharmony_ci				image->name			= getAttribute("Name");
548e5c31af7Sopenharmony_ci				image->description	= getAttribute("Description");
549e5c31af7Sopenharmony_ci				image->width		= toInt(getAttribute("Width"));
550e5c31af7Sopenharmony_ci				image->height		= toInt(getAttribute("Height"));
551e5c31af7Sopenharmony_ci				image->format		= getImageFormat(getAttribute("Format"));
552e5c31af7Sopenharmony_ci				image->compression	= getImageCompression(getAttribute("CompressionMode"));
553e5c31af7Sopenharmony_ci				item = image;
554e5c31af7Sopenharmony_ci				break;
555e5c31af7Sopenharmony_ci			}
556e5c31af7Sopenharmony_ci
557e5c31af7Sopenharmony_ci			case ri::TYPE_SHADERPROGRAM:
558e5c31af7Sopenharmony_ci			{
559e5c31af7Sopenharmony_ci				ri::ShaderProgram* shaderProgram = curList->allocItem<ri::ShaderProgram>();
560e5c31af7Sopenharmony_ci				shaderProgram->linkStatus = toBool(getAttribute("LinkStatus"));
561e5c31af7Sopenharmony_ci				item = shaderProgram;
562e5c31af7Sopenharmony_ci				break;
563e5c31af7Sopenharmony_ci			}
564e5c31af7Sopenharmony_ci
565e5c31af7Sopenharmony_ci			case ri::TYPE_SHADER:
566e5c31af7Sopenharmony_ci			{
567e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SHADERPROGRAM)
568e5c31af7Sopenharmony_ci					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_ci				ri::Shader* shader = curList->allocItem<ri::Shader>();
571e5c31af7Sopenharmony_ci
572e5c31af7Sopenharmony_ci				shader->shaderType		= getShaderTypeFromTagName(elemName);
573e5c31af7Sopenharmony_ci				shader->compileStatus	= toBool(getAttribute("CompileStatus"));
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ci				item = shader;
576e5c31af7Sopenharmony_ci				break;
577e5c31af7Sopenharmony_ci			}
578e5c31af7Sopenharmony_ci
579e5c31af7Sopenharmony_ci			case ri::TYPE_SPIRVSOURCE:
580e5c31af7Sopenharmony_ci			{
581e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SHADERPROGRAM)
582e5c31af7Sopenharmony_ci					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");
583e5c31af7Sopenharmony_ci				item = curList->allocItem<ri::SpirVSource>();
584e5c31af7Sopenharmony_ci				break;
585e5c31af7Sopenharmony_ci			}
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_ci			case ri::TYPE_SHADERSOURCE:
588e5c31af7Sopenharmony_ci				if (parentType == ri::TYPE_SHADER)
589e5c31af7Sopenharmony_ci					item = &static_cast<ri::Shader*>(parentItem)->source;
590e5c31af7Sopenharmony_ci				else
591e5c31af7Sopenharmony_ci					throw TestResultParseError("Unexpected <ShaderSource>");
592e5c31af7Sopenharmony_ci				break;
593e5c31af7Sopenharmony_ci
594e5c31af7Sopenharmony_ci			case ri::TYPE_INFOLOG:
595e5c31af7Sopenharmony_ci				if (parentType == ri::TYPE_SHADERPROGRAM)
596e5c31af7Sopenharmony_ci					item = &static_cast<ri::ShaderProgram*>(parentItem)->linkInfoLog;
597e5c31af7Sopenharmony_ci				else if (parentType == ri::TYPE_SHADER)
598e5c31af7Sopenharmony_ci					item = &static_cast<ri::Shader*>(parentItem)->infoLog;
599e5c31af7Sopenharmony_ci				else if (parentType == ri::TYPE_COMPILEINFO)
600e5c31af7Sopenharmony_ci					item = &static_cast<ri::CompileInfo*>(parentItem)->infoLog;
601e5c31af7Sopenharmony_ci				else
602e5c31af7Sopenharmony_ci					throw TestResultParseError("Unexpected <InfoLog>");
603e5c31af7Sopenharmony_ci				break;
604e5c31af7Sopenharmony_ci
605e5c31af7Sopenharmony_ci			case ri::TYPE_KERNELSOURCE:
606e5c31af7Sopenharmony_ci				item = curList->allocItem<ri::KernelSource>();
607e5c31af7Sopenharmony_ci				break;
608e5c31af7Sopenharmony_ci
609e5c31af7Sopenharmony_ci			case ri::TYPE_COMPILEINFO:
610e5c31af7Sopenharmony_ci			{
611e5c31af7Sopenharmony_ci				ri::CompileInfo* info = curList->allocItem<ri::CompileInfo>();
612e5c31af7Sopenharmony_ci				info->name			= getAttribute("Name");
613e5c31af7Sopenharmony_ci				info->description	= getAttribute("Description");
614e5c31af7Sopenharmony_ci				info->compileStatus	= toBool(getAttribute("CompileStatus"));
615e5c31af7Sopenharmony_ci				item = info;
616e5c31af7Sopenharmony_ci				break;
617e5c31af7Sopenharmony_ci			}
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci			case ri::TYPE_EGLCONFIGSET:
620e5c31af7Sopenharmony_ci			{
621e5c31af7Sopenharmony_ci				ri::EglConfigSet* set = curList->allocItem<ri::EglConfigSet>();
622e5c31af7Sopenharmony_ci				set->name			= getAttribute("Name");
623e5c31af7Sopenharmony_ci				set->description	= m_xmlParser.hasAttribute("Description") ? m_xmlParser.getAttribute("Description") : "";
624e5c31af7Sopenharmony_ci				item = set;
625e5c31af7Sopenharmony_ci				break;
626e5c31af7Sopenharmony_ci			}
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci			case ri::TYPE_EGLCONFIG:
629e5c31af7Sopenharmony_ci			{
630e5c31af7Sopenharmony_ci				ri::EglConfig* config = curList->allocItem<ri::EglConfig>();
631e5c31af7Sopenharmony_ci				config->bufferSize				= toInt(getAttribute("BufferSize"));
632e5c31af7Sopenharmony_ci				config->redSize					= toInt(getAttribute("RedSize"));
633e5c31af7Sopenharmony_ci				config->greenSize				= toInt(getAttribute("GreenSize"));
634e5c31af7Sopenharmony_ci				config->blueSize				= toInt(getAttribute("BlueSize"));
635e5c31af7Sopenharmony_ci				config->luminanceSize			= toInt(getAttribute("LuminanceSize"));
636e5c31af7Sopenharmony_ci				config->alphaSize				= toInt(getAttribute("AlphaSize"));
637e5c31af7Sopenharmony_ci				config->alphaMaskSize			= toInt(getAttribute("AlphaMaskSize"));
638e5c31af7Sopenharmony_ci				config->bindToTextureRGB		= toBool(getAttribute("BindToTextureRGB"));
639e5c31af7Sopenharmony_ci				config->bindToTextureRGBA		= toBool(getAttribute("BindToTextureRGBA"));
640e5c31af7Sopenharmony_ci				config->colorBufferType			= getAttribute("ColorBufferType");
641e5c31af7Sopenharmony_ci				config->configCaveat			= getAttribute("ConfigCaveat");
642e5c31af7Sopenharmony_ci				config->configID				= toInt(getAttribute("ConfigID"));
643e5c31af7Sopenharmony_ci				config->conformant				= getAttribute("Conformant");
644e5c31af7Sopenharmony_ci				config->depthSize				= toInt(getAttribute("DepthSize"));
645e5c31af7Sopenharmony_ci				config->level					= toInt(getAttribute("Level"));
646e5c31af7Sopenharmony_ci				config->maxPBufferWidth			= toInt(getAttribute("MaxPBufferWidth"));
647e5c31af7Sopenharmony_ci				config->maxPBufferHeight		= toInt(getAttribute("MaxPBufferHeight"));
648e5c31af7Sopenharmony_ci				config->maxPBufferPixels		= toInt(getAttribute("MaxPBufferPixels"));
649e5c31af7Sopenharmony_ci				config->maxSwapInterval			= toInt(getAttribute("MaxSwapInterval"));
650e5c31af7Sopenharmony_ci				config->minSwapInterval			= toInt(getAttribute("MinSwapInterval"));
651e5c31af7Sopenharmony_ci				config->nativeRenderable		= toBool(getAttribute("NativeRenderable"));
652e5c31af7Sopenharmony_ci				config->renderableType			= getAttribute("RenderableType");
653e5c31af7Sopenharmony_ci				config->sampleBuffers			= toInt(getAttribute("SampleBuffers"));
654e5c31af7Sopenharmony_ci				config->samples					= toInt(getAttribute("Samples"));
655e5c31af7Sopenharmony_ci				config->stencilSize				= toInt(getAttribute("StencilSize"));
656e5c31af7Sopenharmony_ci				config->surfaceTypes			= getAttribute("SurfaceTypes");
657e5c31af7Sopenharmony_ci				config->transparentType			= getAttribute("TransparentType");
658e5c31af7Sopenharmony_ci				config->transparentRedValue		= toInt(getAttribute("TransparentRedValue"));
659e5c31af7Sopenharmony_ci				config->transparentGreenValue	= toInt(getAttribute("TransparentGreenValue"));
660e5c31af7Sopenharmony_ci				config->transparentBlueValue	= toInt(getAttribute("TransparentBlueValue"));
661e5c31af7Sopenharmony_ci				item = config;
662e5c31af7Sopenharmony_ci				break;
663e5c31af7Sopenharmony_ci			}
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ci			case ri::TYPE_SAMPLELIST:
666e5c31af7Sopenharmony_ci			{
667e5c31af7Sopenharmony_ci				ri::SampleList* list = curList->allocItem<ri::SampleList>();
668e5c31af7Sopenharmony_ci				list->name			= getAttribute("Name");
669e5c31af7Sopenharmony_ci				list->description	= getAttribute("Description");
670e5c31af7Sopenharmony_ci				item = list;
671e5c31af7Sopenharmony_ci				break;
672e5c31af7Sopenharmony_ci			}
673e5c31af7Sopenharmony_ci
674e5c31af7Sopenharmony_ci			case ri::TYPE_SAMPLEINFO:
675e5c31af7Sopenharmony_ci			{
676e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SAMPLELIST)
677e5c31af7Sopenharmony_ci					throw TestResultParseError("<SampleInfo> outside of <SampleList>");
678e5c31af7Sopenharmony_ci
679e5c31af7Sopenharmony_ci				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
680e5c31af7Sopenharmony_ci				ri::SampleInfo*	info	= &list->sampleInfo;
681e5c31af7Sopenharmony_ci
682e5c31af7Sopenharmony_ci				item = info;
683e5c31af7Sopenharmony_ci				break;
684e5c31af7Sopenharmony_ci			}
685e5c31af7Sopenharmony_ci
686e5c31af7Sopenharmony_ci			case ri::TYPE_VALUEINFO:
687e5c31af7Sopenharmony_ci			{
688e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SAMPLEINFO)
689e5c31af7Sopenharmony_ci					throw TestResultParseError("<ValueInfo> outside of <SampleInfo>");
690e5c31af7Sopenharmony_ci
691e5c31af7Sopenharmony_ci				ri::SampleInfo*	sampleInfo	= static_cast<ri::SampleInfo*>(parentItem);
692e5c31af7Sopenharmony_ci				ri::ValueInfo*	valueInfo	= sampleInfo->valueInfos.allocItem<ri::ValueInfo>();
693e5c31af7Sopenharmony_ci
694e5c31af7Sopenharmony_ci				valueInfo->name			= getAttribute("Name");
695e5c31af7Sopenharmony_ci				valueInfo->description	= getAttribute("Description");
696e5c31af7Sopenharmony_ci				valueInfo->tag			= getSampleValueTag(getAttribute("Tag"));
697e5c31af7Sopenharmony_ci
698e5c31af7Sopenharmony_ci				if (m_xmlParser.hasAttribute("Unit"))
699e5c31af7Sopenharmony_ci					valueInfo->unit = getAttribute("Unit");
700e5c31af7Sopenharmony_ci
701e5c31af7Sopenharmony_ci				item = valueInfo;
702e5c31af7Sopenharmony_ci				break;
703e5c31af7Sopenharmony_ci			}
704e5c31af7Sopenharmony_ci
705e5c31af7Sopenharmony_ci			case ri::TYPE_SAMPLE:
706e5c31af7Sopenharmony_ci			{
707e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SAMPLELIST)
708e5c31af7Sopenharmony_ci					throw TestResultParseError("<Sample> outside of <SampleList>");
709e5c31af7Sopenharmony_ci
710e5c31af7Sopenharmony_ci				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
711e5c31af7Sopenharmony_ci				ri::Sample*		sample	= list->samples.allocItem<ri::Sample>();
712e5c31af7Sopenharmony_ci
713e5c31af7Sopenharmony_ci				item = sample;
714e5c31af7Sopenharmony_ci				break;
715e5c31af7Sopenharmony_ci			}
716e5c31af7Sopenharmony_ci
717e5c31af7Sopenharmony_ci			case ri::TYPE_SAMPLEVALUE:
718e5c31af7Sopenharmony_ci			{
719e5c31af7Sopenharmony_ci				if (parentType != ri::TYPE_SAMPLE)
720e5c31af7Sopenharmony_ci					throw TestResultParseError("<Value> outside of <Sample>");
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci				ri::Sample*			sample	= static_cast<ri::Sample*>(parentItem);
723e5c31af7Sopenharmony_ci				ri::SampleValue*	value	= sample->values.allocItem<ri::SampleValue>();
724e5c31af7Sopenharmony_ci
725e5c31af7Sopenharmony_ci				item = value;
726e5c31af7Sopenharmony_ci				break;
727e5c31af7Sopenharmony_ci			}
728e5c31af7Sopenharmony_ci
729e5c31af7Sopenharmony_ci			default:
730e5c31af7Sopenharmony_ci				throw TestResultParseError(string("Unsupported element '") + elemName + ("'"));
731e5c31af7Sopenharmony_ci		}
732e5c31af7Sopenharmony_ci
733e5c31af7Sopenharmony_ci		DE_ASSERT(item);
734e5c31af7Sopenharmony_ci		pushItem(item);
735e5c31af7Sopenharmony_ci
736e5c31af7Sopenharmony_ci		// Reset base64 decoding offset.
737e5c31af7Sopenharmony_ci		m_base64DecodeOffset = 0;
738e5c31af7Sopenharmony_ci	}
739e5c31af7Sopenharmony_ci}
740e5c31af7Sopenharmony_ci
741e5c31af7Sopenharmony_civoid TestResultParser::handleElementEnd (void)
742e5c31af7Sopenharmony_ci{
743e5c31af7Sopenharmony_ci	const char* elemName = m_xmlParser.getElementName();
744e5c31af7Sopenharmony_ci
745e5c31af7Sopenharmony_ci	if (m_state != STATE_IN_TEST_CASE_RESULT)
746e5c31af7Sopenharmony_ci		throw TestResultParseError(string("Unexpected </") + elemName + "> outside of <TestCaseResult>");
747e5c31af7Sopenharmony_ci
748e5c31af7Sopenharmony_ci	if (deStringEqual(elemName, "TestCaseResult"))
749e5c31af7Sopenharmony_ci	{
750e5c31af7Sopenharmony_ci		// Logs from buggy test cases may contain invalid XML.
751e5c31af7Sopenharmony_ci		// DE_ASSERT(getCurrentItem() == DE_NULL);
752e5c31af7Sopenharmony_ci		// \todo [2012-11-22 pyry] Log warning.
753e5c31af7Sopenharmony_ci
754e5c31af7Sopenharmony_ci		m_state = STATE_TEST_CASE_RESULT_ENDED;
755e5c31af7Sopenharmony_ci	}
756e5c31af7Sopenharmony_ci	else
757e5c31af7Sopenharmony_ci	{
758e5c31af7Sopenharmony_ci		ri::Type	itemType	= getResultItemType(elemName);
759e5c31af7Sopenharmony_ci		ri::Item*	curItem		= getCurrentItem();
760e5c31af7Sopenharmony_ci
761e5c31af7Sopenharmony_ci		if (!curItem || itemType != curItem->getType())
762e5c31af7Sopenharmony_ci			throw TestResultParseError(string("Unexpected </") + elemName + ">");
763e5c31af7Sopenharmony_ci
764e5c31af7Sopenharmony_ci		if (itemType == ri::TYPE_RESULT)
765e5c31af7Sopenharmony_ci		{
766e5c31af7Sopenharmony_ci			ri::Result* result = static_cast<ri::Result*>(curItem);
767e5c31af7Sopenharmony_ci			m_result->statusCode	= result->statusCode;
768e5c31af7Sopenharmony_ci			m_result->statusDetails	= result->details;
769e5c31af7Sopenharmony_ci		}
770e5c31af7Sopenharmony_ci		else if (itemType == ri::TYPE_NUMBER)
771e5c31af7Sopenharmony_ci		{
772e5c31af7Sopenharmony_ci			// Parse value for number.
773e5c31af7Sopenharmony_ci			ri::Number*	number	= static_cast<ri::Number*>(curItem);
774e5c31af7Sopenharmony_ci			number->value = getNumericValue(m_curNumValue);
775e5c31af7Sopenharmony_ci			m_curNumValue.clear();
776e5c31af7Sopenharmony_ci		}
777e5c31af7Sopenharmony_ci		else if (itemType == ri::TYPE_SAMPLEVALUE)
778e5c31af7Sopenharmony_ci		{
779e5c31af7Sopenharmony_ci			ri::SampleValue* value = static_cast<ri::SampleValue*>(curItem);
780e5c31af7Sopenharmony_ci			value->value = getNumericValue(m_curNumValue);
781e5c31af7Sopenharmony_ci			m_curNumValue.clear();
782e5c31af7Sopenharmony_ci		}
783e5c31af7Sopenharmony_ci
784e5c31af7Sopenharmony_ci		popItem();
785e5c31af7Sopenharmony_ci	}
786e5c31af7Sopenharmony_ci}
787e5c31af7Sopenharmony_ci
788e5c31af7Sopenharmony_civoid TestResultParser::handleData (void)
789e5c31af7Sopenharmony_ci{
790e5c31af7Sopenharmony_ci	ri::Item*	curItem		= getCurrentItem();
791e5c31af7Sopenharmony_ci	ri::Type	type		= curItem ? curItem->getType() : ri::TYPE_LAST;
792e5c31af7Sopenharmony_ci
793e5c31af7Sopenharmony_ci	switch (type)
794e5c31af7Sopenharmony_ci	{
795e5c31af7Sopenharmony_ci		case ri::TYPE_RESULT:
796e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::Result*>(curItem)->details);
797e5c31af7Sopenharmony_ci			break;
798e5c31af7Sopenharmony_ci
799e5c31af7Sopenharmony_ci		case ri::TYPE_TEXT:
800e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::Text*>(curItem)->text);
801e5c31af7Sopenharmony_ci			break;
802e5c31af7Sopenharmony_ci
803e5c31af7Sopenharmony_ci		case ri::TYPE_SHADERSOURCE:
804e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::ShaderSource*>(curItem)->source);
805e5c31af7Sopenharmony_ci			break;
806e5c31af7Sopenharmony_ci
807e5c31af7Sopenharmony_ci		case ri::TYPE_SPIRVSOURCE:
808e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::SpirVSource*>(curItem)->source);
809e5c31af7Sopenharmony_ci			break;
810e5c31af7Sopenharmony_ci
811e5c31af7Sopenharmony_ci		case ri::TYPE_INFOLOG:
812e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::InfoLog*>(curItem)->log);
813e5c31af7Sopenharmony_ci			break;
814e5c31af7Sopenharmony_ci
815e5c31af7Sopenharmony_ci		case ri::TYPE_KERNELSOURCE:
816e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(static_cast<ri::KernelSource*>(curItem)->source);
817e5c31af7Sopenharmony_ci			break;
818e5c31af7Sopenharmony_ci
819e5c31af7Sopenharmony_ci		case ri::TYPE_NUMBER:
820e5c31af7Sopenharmony_ci		case ri::TYPE_SAMPLEVALUE:
821e5c31af7Sopenharmony_ci			m_xmlParser.appendDataStr(m_curNumValue);
822e5c31af7Sopenharmony_ci			break;
823e5c31af7Sopenharmony_ci
824e5c31af7Sopenharmony_ci		case ri::TYPE_IMAGE:
825e5c31af7Sopenharmony_ci		{
826e5c31af7Sopenharmony_ci			ri::Image* image = static_cast<ri::Image*>(curItem);
827e5c31af7Sopenharmony_ci
828e5c31af7Sopenharmony_ci			// Base64 decode.
829e5c31af7Sopenharmony_ci			int numBytesIn = m_xmlParser.getDataSize();
830e5c31af7Sopenharmony_ci
831e5c31af7Sopenharmony_ci			for (int inNdx = 0; inNdx < numBytesIn; inNdx++)
832e5c31af7Sopenharmony_ci			{
833e5c31af7Sopenharmony_ci				deUint8		byte		= m_xmlParser.getDataByte(inNdx);
834e5c31af7Sopenharmony_ci				deUint8		decodedBits	= 0;
835e5c31af7Sopenharmony_ci
836e5c31af7Sopenharmony_ci				if (de::inRange<deInt8>(byte, 'A', 'Z'))
837e5c31af7Sopenharmony_ci					decodedBits = (deUint8)(byte - 'A');
838e5c31af7Sopenharmony_ci				else if (de::inRange<deInt8>(byte, 'a', 'z'))
839e5c31af7Sopenharmony_ci					decodedBits = (deUint8)(('Z'-'A'+1) + (byte-'a'));
840e5c31af7Sopenharmony_ci				else if (de::inRange<deInt8>(byte, '0', '9'))
841e5c31af7Sopenharmony_ci					decodedBits = (deUint8)(('Z'-'A'+1) + ('z'-'a'+1) + (byte-'0'));
842e5c31af7Sopenharmony_ci				else if (byte == '+')
843e5c31af7Sopenharmony_ci					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+1);
844e5c31af7Sopenharmony_ci				else if (byte == '/')
845e5c31af7Sopenharmony_ci					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+2);
846e5c31af7Sopenharmony_ci				else if (byte == '=')
847e5c31af7Sopenharmony_ci				{
848e5c31af7Sopenharmony_ci					// Padding at end - remove last byte.
849e5c31af7Sopenharmony_ci					if (image->data.empty())
850e5c31af7Sopenharmony_ci						throw TestResultParseError("Malformed base64 data");
851e5c31af7Sopenharmony_ci					image->data.pop_back();
852e5c31af7Sopenharmony_ci					continue;
853e5c31af7Sopenharmony_ci				}
854e5c31af7Sopenharmony_ci				else
855e5c31af7Sopenharmony_ci					continue; // Not an B64 input character.
856e5c31af7Sopenharmony_ci
857e5c31af7Sopenharmony_ci				int phase = m_base64DecodeOffset % 4;
858e5c31af7Sopenharmony_ci
859e5c31af7Sopenharmony_ci				if (phase == 0)
860e5c31af7Sopenharmony_ci					image->data.resize(image->data.size()+3, 0);
861e5c31af7Sopenharmony_ci
862e5c31af7Sopenharmony_ci				if ((int)image->data.size() < (m_base64DecodeOffset>>2)*3 + 3)
863e5c31af7Sopenharmony_ci					throw TestResultParseError("Malformed base64 data");
864e5c31af7Sopenharmony_ci				deUint8* outPtr = &image->data[(m_base64DecodeOffset>>2)*3];
865e5c31af7Sopenharmony_ci
866e5c31af7Sopenharmony_ci				switch (phase)
867e5c31af7Sopenharmony_ci				{
868e5c31af7Sopenharmony_ci					case 0: outPtr[0] |= (deUint8)(decodedBits<<2);																								break;
869e5c31af7Sopenharmony_ci					case 1: outPtr[0] = (deUint8)(outPtr[0] | (deUint8)(decodedBits>>4));	outPtr[1] = (deUint8)(outPtr[1] | (deUint8)((decodedBits&0xF)<<4));	break;
870e5c31af7Sopenharmony_ci					case 2: outPtr[1] = (deUint8)(outPtr[1] | (deUint8)(decodedBits>>2));	outPtr[2] = (deUint8)(outPtr[2] | (deUint8)((decodedBits&0x3)<<6));	break;
871e5c31af7Sopenharmony_ci					case 3: outPtr[2] |= decodedBits;																											break;
872e5c31af7Sopenharmony_ci					default:
873e5c31af7Sopenharmony_ci						DE_ASSERT(false);
874e5c31af7Sopenharmony_ci				}
875e5c31af7Sopenharmony_ci
876e5c31af7Sopenharmony_ci				m_base64DecodeOffset += 1;
877e5c31af7Sopenharmony_ci			}
878e5c31af7Sopenharmony_ci
879e5c31af7Sopenharmony_ci			break;
880e5c31af7Sopenharmony_ci		}
881e5c31af7Sopenharmony_ci
882e5c31af7Sopenharmony_ci		default:
883e5c31af7Sopenharmony_ci			// Just ignore data.
884e5c31af7Sopenharmony_ci			break;
885e5c31af7Sopenharmony_ci	}
886e5c31af7Sopenharmony_ci}
887e5c31af7Sopenharmony_ci
888e5c31af7Sopenharmony_ci//! Helper for parsing TestCaseResult from TestCaseResultData.
889e5c31af7Sopenharmony_civoid parseTestCaseResultFromData (TestResultParser* parser, TestCaseResult* result, const TestCaseResultData& data)
890e5c31af7Sopenharmony_ci{
891e5c31af7Sopenharmony_ci	DE_ASSERT(result->resultItems.getNumItems() == 0);
892e5c31af7Sopenharmony_ci
893e5c31af7Sopenharmony_ci	// Initialize status codes etc. from data.
894e5c31af7Sopenharmony_ci	result->casePath		= data.getTestCasePath();
895e5c31af7Sopenharmony_ci	result->caseType		= TESTCASETYPE_SELF_VALIDATE;
896e5c31af7Sopenharmony_ci	result->statusCode		= data.getStatusCode();
897e5c31af7Sopenharmony_ci	result->statusDetails	= data.getStatusDetails();
898e5c31af7Sopenharmony_ci
899e5c31af7Sopenharmony_ci	if (data.getDataSize() > 0)
900e5c31af7Sopenharmony_ci	{
901e5c31af7Sopenharmony_ci		parser->init(result);
902e5c31af7Sopenharmony_ci
903e5c31af7Sopenharmony_ci		const TestResultParser::ParseResult parseResult = parser->parse(data.getData(), data.getDataSize());
904e5c31af7Sopenharmony_ci
905e5c31af7Sopenharmony_ci		if (result->statusCode == TESTSTATUSCODE_LAST)
906e5c31af7Sopenharmony_ci		{
907e5c31af7Sopenharmony_ci			result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR;
908e5c31af7Sopenharmony_ci
909e5c31af7Sopenharmony_ci			if (parseResult == TestResultParser::PARSERESULT_ERROR)
910e5c31af7Sopenharmony_ci				result->statusDetails = "Test case result parsing failed";
911e5c31af7Sopenharmony_ci			else if (parseResult != TestResultParser::PARSERESULT_COMPLETE)
912e5c31af7Sopenharmony_ci				result->statusDetails = "Incomplete test case result";
913e5c31af7Sopenharmony_ci			else
914e5c31af7Sopenharmony_ci				result->statusDetails = "Test case result is missing <Result> item";
915e5c31af7Sopenharmony_ci		}
916e5c31af7Sopenharmony_ci	}
917e5c31af7Sopenharmony_ci	else if (result->statusCode == TESTSTATUSCODE_LAST)
918e5c31af7Sopenharmony_ci	{
919e5c31af7Sopenharmony_ci		result->statusCode		= TESTSTATUSCODE_TERMINATED;
920e5c31af7Sopenharmony_ci		result->statusDetails	= "Empty test case result";
921e5c31af7Sopenharmony_ci	}
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ci	if (result->casePath.empty())
924e5c31af7Sopenharmony_ci		throw Error("Empty test case path in result");
925e5c31af7Sopenharmony_ci
926e5c31af7Sopenharmony_ci	if (result->caseType == TESTCASETYPE_LAST)
927e5c31af7Sopenharmony_ci		throw Error("Invalid test case type in result");
928e5c31af7Sopenharmony_ci
929e5c31af7Sopenharmony_ci	DE_ASSERT(result->statusCode != TESTSTATUSCODE_LAST);
930e5c31af7Sopenharmony_ci}
931e5c31af7Sopenharmony_ci
932e5c31af7Sopenharmony_ci} // xe
933