Synchronize with tizen 2.4
[platform/core/security/drm-service-core-tizen.git] / tadcore / XMLParser / CXMLFile.cpp
1 /*
2  * Copyright (c) 2000-2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "CXMLFile.h"
18 #include "TADC_IF.h"
19 #include "TADC_ErrorCode.h"
20
21 #define _tcsstr strstr
22 #define _tcschr strchr
23
24 #define _MAX_NAME_LENGTH  4096
25 #define _MAX_VALUE_LENGTH 4096
26
27
28 #define         _SKIP_WHITESPACE()                      while(  ( *m_pszXML == ' ' ) || \
29                                                                                                 ( *m_pszXML == '\n' ) || \
30                                                                                                 ( *m_pszXML == '\r' ) || \
31                                                                                                 ( *m_pszXML == 0x09 ) ) m_pszXML++
32
33 typedef struct _tagESCAPE_CHARSET
34 {
35         LPCTSTR                 pszEscape;
36         TCHAR                   chReplace;
37 } T_ESCAPE_CHARSET;
38
39 //////////////////////////////////////////////////////////////////////
40 // Construction/Destruction
41 //////////////////////////////////////////////////////////////////////
42
43 CXMLFile::CXMLFile()
44 {
45         m_nQueueIndex = 0;
46         m_pRoot = NULL;
47
48         for (int i = 0; i < ELEMENT_QUEUE_MAX; ++i)
49                 m_paElementQueue[i] = NULL;
50         
51         m_pszXML = NULL;
52 }
53
54 CXMLFile::~CXMLFile()
55 {
56         if (m_pRoot)
57                 delete m_pRoot;
58 }
59
60 int CXMLFile::LoadFromStream(LPCTSTR pszXML)
61 {
62         int nResult = 0;
63
64         m_nQueueIndex = 0;
65
66         if (m_pRoot)
67                 delete m_pRoot;
68
69         m_pRoot = NULL;
70         m_pszXML = pszXML;
71
72         nResult = _Parse();
73
74         if (nResult)
75                 goto finish;
76
77 finish:
78         if (nResult)
79                 DRM_TAPPS_EXCEPTION("CXMLFile::LoadFromStream() Error! \n");
80
81         return nResult;
82 }
83
84 int CXMLFile::LoadFromFile(LPCTSTR pszFileName)
85 {
86         int                                     nResult;
87         FILE*                           hFile = NULL;
88         DWORD                           dwFileSize, dwReadBytes;
89         LPBYTE                          pbBuffer = NULL;
90         LPTSTR                          pszXML = NULL;
91
92         hFile = fopen(pszFileName, "rb");
93
94         if (!hFile) {
95                 nResult = -1;
96                 goto finish;
97         }
98
99         fseek(hFile, 0, SEEK_END);
100         dwFileSize = ftell(hFile);
101         fseek(hFile, 0, SEEK_SET);
102
103         pbBuffer = new BYTE[ dwFileSize + 1 ];
104         IF_TRUE_GOTO( pbBuffer == NULL, TADC_MEMAlOC_ERROR );
105
106         dwReadBytes = fread ( pbBuffer, 1, dwFileSize + 1, hFile);
107
108         IF_TRUE_GOTO( dwFileSize != dwReadBytes, TADC_PARAMETER_ERROR );
109
110         pbBuffer[ dwFileSize ] = 0;
111
112         pszXML = new CHAR[ dwFileSize + 256 ];
113         IF_TRUE_GOTO( pszXML == NULL, TADC_MEMAlOC_ERROR );
114
115 #ifdef _UNICODE
116         nResult = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)pbBuffer, -1, pszXML, dwFileSize + 256 );
117 #else
118         memcpy(pszXML, pbBuffer, dwFileSize + 1);
119 #endif
120
121         nResult = LoadFromStream(pszXML);
122
123         if (nResult)
124                 goto finish;
125
126         nResult = 0;
127
128 finish:
129         if (hFile)
130                 fclose(hFile);
131         
132         if (nResult)
133                 DRM_TAPPS_EXCEPTION("CXMLFile::LoadFromFile() Error! \n");
134
135         if (pbBuffer)
136                 delete []pbBuffer;
137
138         if (pszXML)
139                 delete []pszXML;
140
141         return nResult;
142 }
143
144 int CXMLFile::_Parse()
145 {
146         int                                     nResult, i;
147         CXMLElement*            pXMLElement = NULL;
148         CXMLElement*            pCurrentElement = NULL;
149         CXMLElement*            pTemp = NULL;
150         TCHAR                           szElementName[_MAX_NAME_LENGTH];
151         TCHAR                           szValue[_MAX_VALUE_LENGTH];
152         LPCTSTR                         psz;
153         size_t                          orig_pszXML_len = strlen(m_pszXML);
154         size_t                          tmp_pszXML_len = orig_pszXML_len;
155
156         _SKIP_WHITESPACE();
157
158         while (*m_pszXML != 0) {
159                 _SKIP_WHITESPACE();
160
161                 if (*m_pszXML == 0)
162                         break;
163
164                 if (*m_pszXML == '<') {
165                         m_pszXML++;
166                         
167                         _SKIP_WHITESPACE();
168
169                         if (*m_pszXML == '!') {
170                                 //------------------------------------------------------------------------
171                                 //
172                                 // Comment
173                                 //
174                                 //------------------------------------------------------------------------
175                         }
176                         else if (*m_pszXML == '?') {
177                                 //------------------------------------------------------------------------
178                                 //
179                                 // <? ... ?>
180                                 //
181                                 //------------------------------------------------------------------------
182                                 psz = _tcsstr(m_pszXML, _T( "?>" ));
183                                 if (!psz) {
184                                         nResult = -1;
185                                         goto finish;
186                                 }
187                                 
188                                 m_pszXML = psz + 2;
189                         }
190                         else if (*m_pszXML == '/') {
191                                 m_pszXML++;
192                                 //------------------------------------------------------------------------
193                                 //
194                                 // End Tag
195                                 //
196                                 //------------------------------------------------------------------------
197                                 nResult = _GetElementName((LPTSTR)szElementName);
198
199                                 if (nResult != 0)
200                                         goto finish;
201                                 
202                                 //2011.04.27
203                                 if (!pCurrentElement) {
204                                         nResult = -1;
205                                         goto finish;
206                                 }
207                                 
208                                 if (TADC_IF_StrCmp(pCurrentElement->GetName(), (LPTSTR)szElementName) != 0) {
209                                         nResult = -1;
210                                         goto finish;
211                                 }
212
213                                 tmp_pszXML_len = orig_pszXML_len;
214                                 while (*m_pszXML != '>' && tmp_pszXML_len > 0) {
215                                         tmp_pszXML_len--;
216                                         m_pszXML++;
217                                 }
218
219                                 m_pszXML++;
220
221                                 pTemp = _Pop();
222
223                                 if (pTemp)
224                                         pCurrentElement = pTemp;
225                                 else
226                                         pCurrentElement = m_pRoot;
227                         }
228                         else {
229                                 pXMLElement = new CXMLElement;                  
230                                 IF_TRUE_GOTO(pXMLElement == NULL, TADC_MEMAlOC_ERROR);
231                                 
232                                 nResult = _GetElementName((LPTSTR)szElementName);
233                                 if (nResult)
234                                         goto finish;
235
236                                 pXMLElement->SetName((LPTSTR)szElementName);
237
238                                 if (!m_pRoot)
239                                         m_pRoot = pXMLElement;
240                                 
241                                 if (pCurrentElement) {
242                                         pCurrentElement->AddChild(pXMLElement);
243                                         _Push(pCurrentElement);
244                                 }
245
246                                 pCurrentElement = pXMLElement;
247                         }
248                 }
249                 else if (*m_pszXML == '/') {
250                         m_pszXML++;
251
252                         if (*m_pszXML != '>') {
253                                 nResult = -1;
254                                 goto finish;
255                         }
256
257                         pCurrentElement = _Pop();
258                 }
259                 else if (*m_pszXML == '>') {
260                         m_pszXML++;
261                         _SKIP_WHITESPACE();
262
263                         i = 0;
264
265                         tmp_pszXML_len = orig_pszXML_len;
266                         while (*m_pszXML != '<' && tmp_pszXML_len > 0) {
267                                 tmp_pszXML_len--;
268                                 szValue[i] = *m_pszXML;
269                                 i++;
270                                 m_pszXML++;
271                         }
272
273                         szValue[i] = 0;
274                         if (pCurrentElement)
275                                 pCurrentElement->SetValue((LPTSTR)szValue);
276                 }
277                 else {
278                         _SKIP_WHITESPACE();
279
280                         nResult = _GetAttributeNameAndValue((LPTSTR)szElementName, (LPTSTR)szValue);
281
282                         if (nResult)
283                                 goto finish;
284
285                         if (pCurrentElement)
286                                 pCurrentElement->AddAttribute((LPTSTR)szElementName, (LPTSTR)szValue);
287                 }
288         }
289
290         nResult = 0;
291
292 finish:
293         if (nResult)
294                 DRM_TAPPS_EXCEPTION("CXMLFile::_Parse() Error!. nResult[%d]", nResult);
295
296         return nResult;
297 }
298
299 int CXMLFile::_GetElementName(LPTSTR pszElementName)
300 {
301         _SKIP_WHITESPACE();
302
303         while ((*m_pszXML != 0 )
304                 && (*m_pszXML != ' ')
305                 && (*m_pszXML != '>')
306                 && (*m_pszXML != '/')) {
307                 *pszElementName = *m_pszXML;
308                 m_pszXML++;
309                 pszElementName++;
310         }
311         
312         *pszElementName = 0;
313
314         return 0;
315 }
316
317 CXMLElement* CXMLFile::_Pop()
318 {
319         if (m_nQueueIndex < 1)
320                 return NULL;
321
322         return m_paElementQueue[--m_nQueueIndex];
323 }
324
325 int CXMLFile::_Push(IN CXMLElement* p)
326 {
327         if (m_nQueueIndex >= (int)sizeof(m_paElementQueue) / (int)sizeof(m_paElementQueue[0]))
328                 return ERROR_INSUFFICIENT_BUFFER;
329
330         m_paElementQueue[m_nQueueIndex++] = p;
331
332         return 0;
333 }
334
335 int CXMLFile::_GetAttributeNameAndValue(LPTSTR pszName, LPTSTR pszValue)
336 {
337         int                                                     nResult, nLength, i;
338         LPCTSTR                                         psz;
339         TCHAR                                           chQuotation;
340         bool                                            isFound;
341     LPTSTR                      origValueAddr = pszValue;
342         static T_ESCAPE_CHARSET         stEscape[] = {  { _T( "&amp" ), _T( '&' ) },
343                                                                                                 { _T( "&qt" ), _T( '>' ) },
344                                                                                                 { _T( "&lt" ), _T( '<' ) },
345                                                                                                 { _T( "&quot" ), _T( '"' ) },
346                                                                                                 { _T( "&apos" ), _T( '\'' ) } };
347
348         _SKIP_WHITESPACE();
349
350         psz = _tcschr( m_pszXML, '=' );
351         if (!psz) {
352                 nResult = -1;//ERRORMSG( ERROR_SXS_XML_E_BADXMLDECL, NULL );
353                 goto finish;
354         }
355
356         nLength = (int)(psz - m_pszXML);
357     if( _MAX_NAME_LENGTH < nLength + 1) {
358         nResult = -1;
359         goto finish;
360     }
361         memcpy(pszName, m_pszXML, nLength + 1);
362
363         m_pszXML = psz + 1;
364
365         _SKIP_WHITESPACE();
366
367         if (( *m_pszXML == '\'' ) || ( *m_pszXML == '"' )) {
368                 chQuotation = *m_pszXML;
369                 m_pszXML++;
370         }
371         else {
372                 chQuotation = ' ';
373         }
374
375         while (*m_pszXML != 0 && ((pszValue - origValueAddr)< _MAX_VALUE_LENGTH) ) {
376                 if (*m_pszXML == '&') {
377                         isFound = FALSE;
378                         for (i = 0; i < (int)sizeof(stEscape) / (int)sizeof(stEscape[0]); i++) {
379                                 if (TADC_IF_StrNCmp(m_pszXML, stEscape[i].pszEscape, TADC_IF_StrLen(stEscape[i].pszEscape)) == 0) {
380                                         *pszValue = stEscape[i].chReplace;
381                                         pszValue++;
382                                         m_pszXML += TADC_IF_StrLen(stEscape[i].pszEscape);
383                                         isFound = TRUE;
384
385                                         break;
386                                 }
387                         }
388
389                         if (isFound == FALSE) {
390                                 *pszValue = *m_pszXML;
391                                 pszValue++;
392                                 m_pszXML++;
393                         }
394                 }
395                 else if (*m_pszXML == chQuotation) {
396                         m_pszXML++;
397                         break;
398                 }
399                 else if (*m_pszXML == '/' || *m_pszXML == '>')
400                 {
401                         if (chQuotation == ' ')
402                                 break;
403
404                         *pszValue = *m_pszXML;
405                         pszValue++;
406                         m_pszXML++;
407                 }
408                 else
409                 {
410                         *pszValue = *m_pszXML;
411                         pszValue++;
412                         m_pszXML++;
413                 }
414         }
415
416         *pszValue = 0;
417         nResult = 0;
418
419 finish:
420         if (nResult)
421                 DRM_TAPPS_EXCEPTION("CXMLFile::_GetAttributeNameAndValue() Error!");
422
423         return nResult;
424 }