0024510: Remove unused local variables
[occt.git] / src / LDOM / LDOMParser.cxx
CommitLineData
b311480e 1// Created on: 2001-07-20
2// Created by: Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
16//AGV 060302: Input from istream
7fd59977 17// AGV 130302: Return error if there are data after the root element
18
19//#define LDOM_PARSER_TRACE
20
21#include <LDOMParser.hxx>
22#include <LDOM_MemManager.hxx>
23#include <LDOM_XmlReader.hxx>
24#include <LDOM_BasicText.hxx>
25#include <LDOM_CharReference.hxx>
26
27#include <fcntl.h>
28#ifdef WNT
29#include <io.h>
30#else
31#include <unistd.h>
32#endif
33
34//=======================================================================
35//function : ~LDOMParser
36//purpose :
37//=======================================================================
38
39LDOMParser::~LDOMParser()
40{
41 if (myReader) delete myReader;
42}
43
44//=======================================================================
45//function : ReadRecord
46//purpose : Take the next lexical element from XML stream
47//=======================================================================
48
49#ifdef LDOM_PARSER_TRACE
50static
51#else
52inline
53#endif
54 LDOM_XmlReader::RecordType ReadRecord (LDOM_XmlReader& aReader,
55 LDOM_OSStream& aData)
56{
57#ifdef LDOM_PARSER_TRACE
58 static aCounter = 0;
59 ++ aCounter;
60#endif
61 const LDOM_XmlReader::RecordType aType = aReader.ReadRecord (aData);
62#ifdef LDOM_PARSER_TRACE
63 static FILE * ff = NULL;
64 TCollection_AsciiString aTraceFileName;
65#ifdef WNT
66 aTraceFileName = TCollection_AsciiString (getenv("TEMP")) + "\\ldom.trace";
67#else
68 aTraceFileName = "/tmp/ldom.trace";
69#endif
70 ff = fopen (aTraceFileName.ToCString(),ff ? "at": "wt");
71 const char * aDataType;
72 switch (aType) {
73 case LDOM_XmlReader::XML_UNKNOWN: aDataType= "XML_UNKNOWN "; break;
74 case LDOM_XmlReader::XML_HEADER: aDataType= "XML_HEADER "; break;
75 case LDOM_XmlReader::XML_DOCTYPE: aDataType= "XML_DOCTYPE "; break;
76 case LDOM_XmlReader::XML_COMMENT: aDataType= "XML_COMMENT "; break;
77 case LDOM_XmlReader::XML_START_ELEMENT: aDataType= "XML_START_ELEMENT"; break;
78 case LDOM_XmlReader::XML_END_ELEMENT: aDataType= "XML_END_ELEMENT "; break;
79 case LDOM_XmlReader::XML_FULL_ELEMENT: aDataType= "XML_FULL_ELEMENT "; break;
80 case LDOM_XmlReader::XML_TEXT: aDataType= "XML_TEXT "; break;
81 case LDOM_XmlReader::XML_CDATA: aDataType= "XML_CDATA "; break;
82 case LDOM_XmlReader::XML_EOF: aDataType= "XML_EOF ";
83 }
84 char * aStr = aData.str();
85 fprintf (ff, "%5d %s: %s\n", aCounter, aDataType, aStr);
86 delete [] aStr;
87 fclose (ff);
88#endif
89 return aType;
90}
91
92//=======================================================================
93//function : GetError
94//purpose : Return text describing a parsing error
95//=======================================================================
96
97const TCollection_AsciiString& LDOMParser::GetError
98 (TCollection_AsciiString& aData) const
99{
100 char * aStr =(char *)myCurrentData.str();
101 aData = aStr;
102 delete [] aStr;
103 return myError;
104}
105
106//=======================================================================
107//function : parse
108//purpose :
109//=======================================================================
110
111Standard_Boolean LDOMParser::parse (istream& anInput)
112{
113 // Open the DOM Document
114 myDocument = new LDOM_MemManager (20000);
115 myError.Clear();
116
117 // Create the Reader instance
118 if (myReader) delete myReader;
119 myReader = new LDOM_XmlReader (anInput, myDocument, myError);
120
121 // Parse
122 return ParseDocument();
123}
124
125//=======================================================================
126//function : parse
127//purpose :
128//=======================================================================
129
130Standard_Boolean LDOMParser::parse (const char * const aFileName)
131{
132 // Open the DOM Document
133 myDocument = new LDOM_MemManager (20000);
134 myError.Clear ();
135
136 // Open the file
137 int aFile = open (aFileName, O_RDONLY);
138 if (aFile < 0) {
139 myError = "Fatal XML error: Cannot open XML file";
140 return Standard_True;
141 }
142
143 // Create the Reader instance
144 if (myReader) delete myReader;
145 myReader = new LDOM_XmlReader (aFile, myDocument, myError);
146
147 // Parse
148 Standard_Boolean isError = ParseDocument();
149 close (aFile);
150 return isError;
151}
152
153//=======================================================================
154//function : ParseDocument
155//purpose : parse the whole document (abstracted from the XML source)
156//=======================================================================
157
158Standard_Boolean LDOMParser::ParseDocument ()
159{
160 Standard_Boolean isError = Standard_False;
161 Standard_Boolean isElement = Standard_False;
7fd59977 162 Standard_Boolean isDoctype = Standard_False;
163
302f96fb 164 for(;;) {
7fd59977 165 LDOM_XmlReader::RecordType aType = ReadRecord (*myReader, myCurrentData);
166 switch (aType) {
167 case LDOM_XmlReader::XML_HEADER:
168 if (isDoctype || isElement) {
169 myError = "Unexpected XML declaration";
170 isError = Standard_True;
171 break;
172 }
7fd59977 173 continue;
174 case LDOM_XmlReader::XML_DOCTYPE:
175 if (isElement) {
176 myError = "Unexpected DOCTYPE declaration";
177 isError = Standard_True;
178 break;
179 }
180 isDoctype = Standard_True;
181 case LDOM_XmlReader::XML_COMMENT:
182 continue;
183 case LDOM_XmlReader::XML_FULL_ELEMENT:
184 if (isElement == Standard_False) {
185 isElement = Standard_True;
186 myDocument -> myRootElement = &myReader -> GetElement ();
187 if (startElement()) {
188 isError = Standard_True;
189 myError = "User abort at startElement()";
190 break;
191 }
192 if (endElement()) {
193 isError = Standard_True;
194 myError = "User abort at endElement()";
195 break;
196 }
197 continue;
198 }
199 case LDOM_XmlReader::XML_START_ELEMENT:
200 if (isElement == Standard_False) {
201 isElement = Standard_True;
202 myDocument -> myRootElement = &myReader -> GetElement ();
203 if (startElement()) {
204 isError = Standard_True;
205 myError = "User abort at startElement()";
206 break;
207 }
208 isError = ParseElement ();
209 if (isError) break;
210 continue;
211 }
212 isError = Standard_True;
213 myError = "Expected comment or end-of-file";
214 case LDOM_XmlReader::XML_END_ELEMENT:
215 if (endElement()) {
216 isError = Standard_True;
217 myError = "User abort at endElement()";
218 }
219 case LDOM_XmlReader::XML_EOF:
220 break;
221 case LDOM_XmlReader::XML_UNKNOWN:
222 if (isElement) {
223 default:
224 myError = "Unexpected data beyond the Document Element";
225 }
226 isError = Standard_True;
227 }
228 break;
229 }
230 return isError;
231}
232
233//=======================================================================
234//function : ParseElement
235//purpose : parse one element, given the type of its XML presentation
236//=======================================================================
237
238Standard_Boolean LDOMParser::ParseElement ()
239{
240 Standard_Boolean isError = Standard_False;
241 const LDOM_BasicElement * aParent = &myReader->GetElement();
242 const LDOM_BasicNode * aLastChild = NULL;
302f96fb 243 for(;;) {
7fd59977 244 LDOM_Node::NodeType aLocType;
245 LDOMBasicString aTextValue;
246 char *aTextStr;
247 LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, myCurrentData);
248 switch (aType) {
249 case LDOM_XmlReader::XML_UNKNOWN:
250 isError = Standard_True;
251 break;
252 case LDOM_XmlReader::XML_FULL_ELEMENT:
253 aParent -> AppendChild (&myReader -> GetElement(), aLastChild);
254 if (startElement()) {
255 isError = Standard_True;
256 myError = "User abort at startElement()";
257 break;
258 }
259 if (endElement()) {
260 isError = Standard_True;
261 myError = "User abort at endElement()";
262 break;
263 }
264 break;
265 case LDOM_XmlReader::XML_START_ELEMENT:
266 aParent -> AppendChild (&myReader -> GetElement(), aLastChild);
267 if (startElement()) {
268 isError = Standard_True;
269 myError = "User abort at startElement()";
270 break;
271 }
272 isError = ParseElement ();
273 break;
274 case LDOM_XmlReader::XML_END_ELEMENT:
275 {
276 Standard_CString aParentName = Standard_CString(aParent->GetTagName());
277 aTextStr = (char *)myCurrentData.str();
278 if (strcmp(aTextStr, aParentName) != 0) {
279 myError = "Expected end tag \'";
280 myError += aParentName;
281 myError += "\'";
282 isError = Standard_True;
283 }
284 else if (endElement()) {
285 isError = Standard_True;
286 myError = "User abort at endElement()";
287 }
288 delete [] aTextStr;
289 }
290 return isError;
291 case LDOM_XmlReader::XML_TEXT:
292 aLocType = LDOM_Node::TEXT_NODE;
293 {
294 Standard_Integer aTextLen;
295 aTextStr = LDOM_CharReference::Decode ((char *)myCurrentData.str(), aTextLen);
296 // try to convert to integer
297 if (IsDigit(aTextStr[0])) {
298 if (LDOM_XmlReader::getInteger (aTextValue, aTextStr,
299 aTextStr + aTextLen))
300 aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
301 } else
302 aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
303 }
304 goto create_text_node;
305 case LDOM_XmlReader::XML_COMMENT:
306 aLocType = LDOM_Node::COMMENT_NODE;
307 {
308 Standard_Integer aTextLen;
309 aTextStr = LDOM_CharReference::Decode ((char *)myCurrentData.str(), aTextLen);
310 aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
311 }
312 goto create_text_node;
313 case LDOM_XmlReader::XML_CDATA:
314 aLocType = LDOM_Node::CDATA_SECTION_NODE;
315 aTextStr = (char *)myCurrentData.str();
316 aTextValue = LDOMBasicString(aTextStr,myCurrentData.Length(),myDocument);
317 create_text_node:
318 {
319 LDOM_BasicNode& aTextNode =
320 LDOM_BasicText::Create (aLocType, aTextValue, myDocument);
321 aParent -> AppendChild (&aTextNode, aLastChild);
322 }
323 delete [] aTextStr;
324 break;
325 case LDOM_XmlReader::XML_EOF:
326 myError = "Inexpected end of file";
327 isError = Standard_True;
328 break;
329 default: ;
330 }
331 if (isError) break;
332 }
333 return isError;
334}
335
336//=======================================================================
337//function : startElement
338//purpose : virtual hook on 'StartElement' event for descendant classes
339//=======================================================================
340
341Standard_Boolean LDOMParser::startElement ()
342{
343 return Standard_False;
344}
345
346//=======================================================================
347//function : endElement
348//purpose : virtual hook on 'EndElement' event for descendant classes
349//=======================================================================
350
351Standard_Boolean LDOMParser::endElement ()
352{
353 return Standard_False;
354}
355
356//=======================================================================
357//function : getCurrentElement
358//purpose :
359//=======================================================================
360
361LDOM_Element LDOMParser::getCurrentElement () const
362{
363 return LDOM_Element (myReader -> GetElement(), myDocument);
364}
365
366//=======================================================================
367//function : getDocument
368//purpose :
369//=======================================================================
370
371LDOM_Document LDOMParser::getDocument ()
372{
373 return myDocument -> Self();
374}
375