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