xref: /aosp_15_r20/external/deqp/executor/xeContainerFormatParser.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 log container format parser.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xeContainerFormatParser.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
26*35238bceSAndroid Build Coastguard Worker 
27*35238bceSAndroid Build Coastguard Worker namespace xe
28*35238bceSAndroid Build Coastguard Worker {
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker enum
31*35238bceSAndroid Build Coastguard Worker {
32*35238bceSAndroid Build Coastguard Worker     CONTAINERFORMATPARSER_INITIAL_BUFFER_SIZE = 1024
33*35238bceSAndroid Build Coastguard Worker };
34*35238bceSAndroid Build Coastguard Worker 
getNextBufferSize(int curSize,int minNewSize)35*35238bceSAndroid Build Coastguard Worker static int getNextBufferSize(int curSize, int minNewSize)
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker     return de::max(curSize * 2, 1 << deLog2Ceil32(minNewSize));
38*35238bceSAndroid Build Coastguard Worker }
39*35238bceSAndroid Build Coastguard Worker 
ContainerFormatParser(void)40*35238bceSAndroid Build Coastguard Worker ContainerFormatParser::ContainerFormatParser(void)
41*35238bceSAndroid Build Coastguard Worker     : m_element(CONTAINERELEMENT_INCOMPLETE)
42*35238bceSAndroid Build Coastguard Worker     , m_elementLen(0)
43*35238bceSAndroid Build Coastguard Worker     , m_state(STATE_AT_LINE_START)
44*35238bceSAndroid Build Coastguard Worker     , m_buf(CONTAINERFORMATPARSER_INITIAL_BUFFER_SIZE)
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker }
47*35238bceSAndroid Build Coastguard Worker 
~ContainerFormatParser(void)48*35238bceSAndroid Build Coastguard Worker ContainerFormatParser::~ContainerFormatParser(void)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker 
clear(void)52*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::clear(void)
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker     m_element    = CONTAINERELEMENT_INCOMPLETE;
55*35238bceSAndroid Build Coastguard Worker     m_elementLen = 0;
56*35238bceSAndroid Build Coastguard Worker     m_state      = STATE_AT_LINE_START;
57*35238bceSAndroid Build Coastguard Worker     m_buf.clear();
58*35238bceSAndroid Build Coastguard Worker }
59*35238bceSAndroid Build Coastguard Worker 
error(const std::string & what)60*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::error(const std::string &what)
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker     throw ContainerParseError(what);
63*35238bceSAndroid Build Coastguard Worker }
64*35238bceSAndroid Build Coastguard Worker 
feed(const uint8_t * bytes,size_t numBytes)65*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::feed(const uint8_t *bytes, size_t numBytes)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker     // Grow buffer if necessary.
68*35238bceSAndroid Build Coastguard Worker     if (m_buf.getNumFree() < (int)numBytes)
69*35238bceSAndroid Build Coastguard Worker         m_buf.resize(getNextBufferSize(m_buf.getSize(), m_buf.getNumElements() + (int)numBytes));
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker     // Append to front.
72*35238bceSAndroid Build Coastguard Worker     m_buf.pushFront(bytes, (int)numBytes);
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker     // If we haven't parsed complete element, re-try after data feed.
75*35238bceSAndroid Build Coastguard Worker     if (m_element == CONTAINERELEMENT_INCOMPLETE)
76*35238bceSAndroid Build Coastguard Worker         advance();
77*35238bceSAndroid Build Coastguard Worker }
78*35238bceSAndroid Build Coastguard Worker 
getSessionInfoAttribute(void) const79*35238bceSAndroid Build Coastguard Worker const char *ContainerFormatParser::getSessionInfoAttribute(void) const
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_SESSION_INFO);
82*35238bceSAndroid Build Coastguard Worker     return m_attribute.c_str();
83*35238bceSAndroid Build Coastguard Worker }
84*35238bceSAndroid Build Coastguard Worker 
getSessionInfoValue(void) const85*35238bceSAndroid Build Coastguard Worker const char *ContainerFormatParser::getSessionInfoValue(void) const
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_SESSION_INFO);
88*35238bceSAndroid Build Coastguard Worker     return m_value.c_str();
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker 
getTestCasePath(void) const91*35238bceSAndroid Build Coastguard Worker const char *ContainerFormatParser::getTestCasePath(void) const
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT);
94*35238bceSAndroid Build Coastguard Worker     return m_value.c_str();
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker 
getTerminateReason(void) const97*35238bceSAndroid Build Coastguard Worker const char *ContainerFormatParser::getTerminateReason(void) const
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT);
100*35238bceSAndroid Build Coastguard Worker     return m_value.c_str();
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker 
getDataSize(void) const103*35238bceSAndroid Build Coastguard Worker int ContainerFormatParser::getDataSize(void) const
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_TEST_LOG_DATA);
106*35238bceSAndroid Build Coastguard Worker     return m_elementLen;
107*35238bceSAndroid Build Coastguard Worker }
108*35238bceSAndroid Build Coastguard Worker 
getData(uint8_t * dst,int numBytes,int offset)109*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::getData(uint8_t *dst, int numBytes, int offset)
110*35238bceSAndroid Build Coastguard Worker {
111*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inBounds(offset, 0, m_elementLen) && numBytes > 0 && de::inRange(numBytes + offset, 0, m_elementLen));
112*35238bceSAndroid Build Coastguard Worker 
113*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numBytes; ndx++)
114*35238bceSAndroid Build Coastguard Worker         dst[ndx] = m_buf.peekBack(offset + ndx);
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker 
getChar(int offset) const117*35238bceSAndroid Build Coastguard Worker int ContainerFormatParser::getChar(int offset) const
118*35238bceSAndroid Build Coastguard Worker {
119*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(offset, 0, m_buf.getNumElements()));
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker     if (offset < m_buf.getNumElements())
122*35238bceSAndroid Build Coastguard Worker         return m_buf.peekBack(offset);
123*35238bceSAndroid Build Coastguard Worker     else
124*35238bceSAndroid Build Coastguard Worker         return END_OF_BUFFER;
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker 
getTestRunsParams(void) const127*35238bceSAndroid Build Coastguard Worker const char *ContainerFormatParser::getTestRunsParams(void) const
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_element == CONTAINERELEMENT_TEST_RUN_PARAM_BEGIN);
130*35238bceSAndroid Build Coastguard Worker     return m_value.c_str();
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker 
advance(void)133*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::advance(void)
134*35238bceSAndroid Build Coastguard Worker {
135*35238bceSAndroid Build Coastguard Worker     if (m_element != CONTAINERELEMENT_INCOMPLETE)
136*35238bceSAndroid Build Coastguard Worker     {
137*35238bceSAndroid Build Coastguard Worker         m_buf.popBack(m_elementLen);
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker         m_element    = CONTAINERELEMENT_INCOMPLETE;
140*35238bceSAndroid Build Coastguard Worker         m_elementLen = 0;
141*35238bceSAndroid Build Coastguard Worker         m_attribute.clear();
142*35238bceSAndroid Build Coastguard Worker         m_value.clear();
143*35238bceSAndroid Build Coastguard Worker     }
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker     for (;;)
146*35238bceSAndroid Build Coastguard Worker     {
147*35238bceSAndroid Build Coastguard Worker         int curChar = getChar(m_elementLen);
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker         if (curChar != (int)END_OF_BUFFER)
150*35238bceSAndroid Build Coastguard Worker             m_elementLen += 1;
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker         if (curChar == END_OF_STRING)
153*35238bceSAndroid Build Coastguard Worker         {
154*35238bceSAndroid Build Coastguard Worker             if (m_elementLen == 1)
155*35238bceSAndroid Build Coastguard Worker                 m_element = CONTAINERELEMENT_END_OF_STRING;
156*35238bceSAndroid Build Coastguard Worker             else if (m_state == STATE_CONTAINER_LINE)
157*35238bceSAndroid Build Coastguard Worker                 parseContainerLine();
158*35238bceSAndroid Build Coastguard Worker             else
159*35238bceSAndroid Build Coastguard Worker                 m_element = CONTAINERELEMENT_TEST_LOG_DATA;
160*35238bceSAndroid Build Coastguard Worker 
161*35238bceSAndroid Build Coastguard Worker             break;
162*35238bceSAndroid Build Coastguard Worker         }
163*35238bceSAndroid Build Coastguard Worker         else if (curChar == (int)END_OF_BUFFER)
164*35238bceSAndroid Build Coastguard Worker         {
165*35238bceSAndroid Build Coastguard Worker             if (m_elementLen > 0 && m_state == STATE_DATA)
166*35238bceSAndroid Build Coastguard Worker                 m_element = CONTAINERELEMENT_TEST_LOG_DATA;
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker             break;
169*35238bceSAndroid Build Coastguard Worker         }
170*35238bceSAndroid Build Coastguard Worker         else if (curChar == '\r' || curChar == '\n')
171*35238bceSAndroid Build Coastguard Worker         {
172*35238bceSAndroid Build Coastguard Worker             // Check for \r\n
173*35238bceSAndroid Build Coastguard Worker             int nextChar = getChar(m_elementLen);
174*35238bceSAndroid Build Coastguard Worker             if (curChar == '\n' || (nextChar != (int)END_OF_BUFFER && nextChar != '\n'))
175*35238bceSAndroid Build Coastguard Worker             {
176*35238bceSAndroid Build Coastguard Worker                 if (m_state == STATE_CONTAINER_LINE)
177*35238bceSAndroid Build Coastguard Worker                     parseContainerLine();
178*35238bceSAndroid Build Coastguard Worker                 else
179*35238bceSAndroid Build Coastguard Worker                     m_element = CONTAINERELEMENT_TEST_LOG_DATA;
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker                 m_state = STATE_AT_LINE_START;
182*35238bceSAndroid Build Coastguard Worker                 break;
183*35238bceSAndroid Build Coastguard Worker             }
184*35238bceSAndroid Build Coastguard Worker             // else handle following end or \n in next iteration.
185*35238bceSAndroid Build Coastguard Worker         }
186*35238bceSAndroid Build Coastguard Worker         else if (m_state == STATE_AT_LINE_START)
187*35238bceSAndroid Build Coastguard Worker         {
188*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(m_elementLen == 1);
189*35238bceSAndroid Build Coastguard Worker             m_state = (curChar == '#') ? STATE_CONTAINER_LINE : STATE_DATA;
190*35238bceSAndroid Build Coastguard Worker         }
191*35238bceSAndroid Build Coastguard Worker     }
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker 
parseContainerLine(void)194*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::parseContainerLine(void)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker     static const struct
197*35238bceSAndroid Build Coastguard Worker     {
198*35238bceSAndroid Build Coastguard Worker         const char *name;
199*35238bceSAndroid Build Coastguard Worker         ContainerElement element;
200*35238bceSAndroid Build Coastguard Worker     } s_elements[] = {
201*35238bceSAndroid Build Coastguard Worker         {"beginTestCaseResult", CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT},
202*35238bceSAndroid Build Coastguard Worker         {"endTestCaseResult", CONTAINERELEMENT_END_TEST_CASE_RESULT},
203*35238bceSAndroid Build Coastguard Worker         {"terminateTestCaseResult", CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT},
204*35238bceSAndroid Build Coastguard Worker         {"sessionInfo", CONTAINERELEMENT_SESSION_INFO},
205*35238bceSAndroid Build Coastguard Worker         {"beginSession", CONTAINERELEMENT_BEGIN_SESSION},
206*35238bceSAndroid Build Coastguard Worker         {"endSession", CONTAINERELEMENT_END_SESSION},
207*35238bceSAndroid Build Coastguard Worker         {"beginTestRunParamsCollection", CONTAINERELEMENT_TEST_RUN_PARAM_SESSION_BEGIN},
208*35238bceSAndroid Build Coastguard Worker         {"endTestRunParamsCollection", CONTAINERELEMENT_TEST_RUN_PARAM_SESSION_END},
209*35238bceSAndroid Build Coastguard Worker         {"beginTestRunParams", CONTAINERELEMENT_TEST_RUN_PARAM_BEGIN},
210*35238bceSAndroid Build Coastguard Worker         {"endTestRunParams", CONTAINERELEMENT_TEST_RUN_PARAM_END},
211*35238bceSAndroid Build Coastguard Worker     };
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_elementLen >= 1);
214*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getChar(0) == '#');
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker     int offset = 1;
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < DE_LENGTH_OF_ARRAY(s_elements); elemNdx++)
219*35238bceSAndroid Build Coastguard Worker     {
220*35238bceSAndroid Build Coastguard Worker         bool isMatch = false;
221*35238bceSAndroid Build Coastguard Worker         int ndx      = 0;
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker         for (;;)
224*35238bceSAndroid Build Coastguard Worker         {
225*35238bceSAndroid Build Coastguard Worker             int bufChar = (offset + ndx < m_elementLen) ? getChar(offset + ndx) : 0;
226*35238bceSAndroid Build Coastguard Worker             bool bufEnd =
227*35238bceSAndroid Build Coastguard Worker                 bufChar == 0 || bufChar == ' ' || bufChar == '\r' || bufChar == '\n' || bufChar == (int)END_OF_BUFFER;
228*35238bceSAndroid Build Coastguard Worker             int elemChar = s_elements[elemNdx].name[ndx];
229*35238bceSAndroid Build Coastguard Worker             bool elemEnd = elemChar == 0;
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker             if (bufEnd || elemEnd)
232*35238bceSAndroid Build Coastguard Worker             {
233*35238bceSAndroid Build Coastguard Worker                 isMatch = bufEnd == elemEnd;
234*35238bceSAndroid Build Coastguard Worker                 break;
235*35238bceSAndroid Build Coastguard Worker             }
236*35238bceSAndroid Build Coastguard Worker             else if (bufChar != elemChar)
237*35238bceSAndroid Build Coastguard Worker                 break;
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker             ndx += 1;
240*35238bceSAndroid Build Coastguard Worker         }
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker         if (isMatch)
243*35238bceSAndroid Build Coastguard Worker         {
244*35238bceSAndroid Build Coastguard Worker             m_element = s_elements[elemNdx].element;
245*35238bceSAndroid Build Coastguard Worker             offset += ndx;
246*35238bceSAndroid Build Coastguard Worker             break;
247*35238bceSAndroid Build Coastguard Worker         }
248*35238bceSAndroid Build Coastguard Worker     }
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker     switch (m_element)
251*35238bceSAndroid Build Coastguard Worker     {
252*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_BEGIN_SESSION:
253*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_END_SESSION:
254*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_END_TEST_CASE_RESULT:
255*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_TEST_RUN_PARAM_SESSION_BEGIN:
256*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_TEST_RUN_PARAM_SESSION_END:
257*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_TEST_RUN_PARAM_END:
258*35238bceSAndroid Build Coastguard Worker         break; // No attribute or value.
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT:
261*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT:
262*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_TEST_RUN_PARAM_BEGIN:
263*35238bceSAndroid Build Coastguard Worker         if (getChar(offset) != ' ')
264*35238bceSAndroid Build Coastguard Worker             error("Expected value after instruction");
265*35238bceSAndroid Build Coastguard Worker         offset += 1;
266*35238bceSAndroid Build Coastguard Worker         parseContainerValue(m_value, offset);
267*35238bceSAndroid Build Coastguard Worker         break;
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker     case CONTAINERELEMENT_SESSION_INFO:
270*35238bceSAndroid Build Coastguard Worker         if (getChar(offset) != ' ')
271*35238bceSAndroid Build Coastguard Worker             error("Expected attribute name after #sessionInfo");
272*35238bceSAndroid Build Coastguard Worker         offset += 1;
273*35238bceSAndroid Build Coastguard Worker         parseContainerValue(m_attribute, offset);
274*35238bceSAndroid Build Coastguard Worker         if (getChar(offset) != ' ')
275*35238bceSAndroid Build Coastguard Worker             error("No value for #sessionInfo attribute");
276*35238bceSAndroid Build Coastguard Worker         offset += 1;
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker         if (m_attribute == "timestamp")
279*35238bceSAndroid Build Coastguard Worker         {
280*35238bceSAndroid Build Coastguard Worker             m_value.clear();
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker             // \note Candy produces unescaped timestamps.
283*35238bceSAndroid Build Coastguard Worker             for (;;)
284*35238bceSAndroid Build Coastguard Worker             {
285*35238bceSAndroid Build Coastguard Worker                 const int curChar = offset < m_elementLen ? getChar(offset) : 0;
286*35238bceSAndroid Build Coastguard Worker                 const bool isEnd  = curChar == 0 || curChar == (int)END_OF_BUFFER || curChar == '\n' || curChar == '\t';
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker                 if (isEnd)
289*35238bceSAndroid Build Coastguard Worker                     break;
290*35238bceSAndroid Build Coastguard Worker                 else
291*35238bceSAndroid Build Coastguard Worker                     m_value.push_back((char)curChar);
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker                 offset += 1;
294*35238bceSAndroid Build Coastguard Worker             }
295*35238bceSAndroid Build Coastguard Worker         }
296*35238bceSAndroid Build Coastguard Worker         else
297*35238bceSAndroid Build Coastguard Worker             parseContainerValue(m_value, offset);
298*35238bceSAndroid Build Coastguard Worker         break;
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker     default:
301*35238bceSAndroid Build Coastguard Worker         // \todo [2012-06-09 pyry] Implement better way to handle # at the beginning of log lines.
302*35238bceSAndroid Build Coastguard Worker         m_element = CONTAINERELEMENT_TEST_LOG_DATA;
303*35238bceSAndroid Build Coastguard Worker         break;
304*35238bceSAndroid Build Coastguard Worker     }
305*35238bceSAndroid Build Coastguard Worker }
306*35238bceSAndroid Build Coastguard Worker 
parseContainerValue(std::string & dst,int & offset) const307*35238bceSAndroid Build Coastguard Worker void ContainerFormatParser::parseContainerValue(std::string &dst, int &offset) const
308*35238bceSAndroid Build Coastguard Worker {
309*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset < m_elementLen);
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker     bool isString = getChar(offset) == '"' || getChar(offset) == '\'';
312*35238bceSAndroid Build Coastguard Worker     int quotChar  = isString ? getChar(offset) : 0;
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker     if (isString)
315*35238bceSAndroid Build Coastguard Worker         offset += 1;
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker     dst.clear();
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker     for (;;)
320*35238bceSAndroid Build Coastguard Worker     {
321*35238bceSAndroid Build Coastguard Worker         int curChar = offset < m_elementLen ? getChar(offset) : 0;
322*35238bceSAndroid Build Coastguard Worker         bool isEnd  = curChar == 0 || curChar == (int)END_OF_BUFFER ||
323*35238bceSAndroid Build Coastguard Worker                      (isString ? (curChar == quotChar) : (curChar == ' ' || curChar == '\n' || curChar == '\r'));
324*35238bceSAndroid Build Coastguard Worker 
325*35238bceSAndroid Build Coastguard Worker         if (isEnd)
326*35238bceSAndroid Build Coastguard Worker             break;
327*35238bceSAndroid Build Coastguard Worker         else
328*35238bceSAndroid Build Coastguard Worker         {
329*35238bceSAndroid Build Coastguard Worker             // \todo [2012-06-09 pyry] Escapes.
330*35238bceSAndroid Build Coastguard Worker             dst.push_back((char)curChar);
331*35238bceSAndroid Build Coastguard Worker         }
332*35238bceSAndroid Build Coastguard Worker 
333*35238bceSAndroid Build Coastguard Worker         offset += 1;
334*35238bceSAndroid Build Coastguard Worker     }
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker     if (isString && getChar(offset) == quotChar)
337*35238bceSAndroid Build Coastguard Worker         offset += 1;
338*35238bceSAndroid Build Coastguard Worker }
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker } // namespace xe
341