1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-06 10:36:12 +03:00
occt/src/LDOM/LDOMParser.cxx
abv b1811c1d2b 0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
New macro Standard_FALLTHROUGH is defined for use in a switch statement immediately before a case label, if code associated with the previous case label may fall through to that
next label (i.e. does not end with "break" or "return" etc.).
This macro indicates that the fall through is intentional and should not be diagnosed by a compiler that warns on fallthrough.

The macro is inserted in places that currently generate such warning message and where fallthrough is intentional.

Doxygen comments are provided for this and other macros in Standard_Macro.hxx.
2017-10-04 15:28:02 +03:00

395 lines
13 KiB
C++

// Created on: 2001-07-20
// Created by: Alexander GRIGORIEV
// Copyright (c) 2001-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//AGV 060302: Input from istream
// AGV 130302: Return error if there are data after the root element
//#define LDOM_PARSER_TRACE
#include <LDOMParser.hxx>
#include <LDOM_MemManager.hxx>
#include <LDOM_XmlReader.hxx>
#include <LDOM_BasicText.hxx>
#include <LDOM_CharReference.hxx>
#include <TCollection_ExtendedString.hxx>
#include <OSD_OpenFile.hxx>
#include <fcntl.h>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif
//=======================================================================
//function : ~LDOMParser
//purpose :
//=======================================================================
LDOMParser::~LDOMParser()
{
if (myReader) delete myReader;
}
//=======================================================================
//function : ReadRecord
//purpose : Take the next lexical element from XML stream
//=======================================================================
#ifdef LDOM_PARSER_TRACE
static
#else
inline
#endif
LDOM_XmlReader::RecordType ReadRecord (LDOM_XmlReader& aReader,
Standard_IStream& theIStream,
LDOM_OSStream& aData)
{
#ifdef LDOM_PARSER_TRACE
static aCounter = 0;
++ aCounter;
#endif
const LDOM_XmlReader::RecordType aType = aReader.ReadRecord (theIStream, aData);
#ifdef LDOM_PARSER_TRACE
static FILE * ff = NULL;
TCollection_AsciiString aTraceFileName;
#ifdef _WIN32
aTraceFileName = TCollection_AsciiString (getenv("TEMP")) + "\\ldom.trace";
#else
aTraceFileName = "/tmp/ldom.trace";
#endif
ff = fopen (aTraceFileName.ToCString(),ff ? "at": "wt");
const char * aDataType;
switch (aType) {
case LDOM_XmlReader::XML_UNKNOWN: aDataType= "XML_UNKNOWN "; break;
case LDOM_XmlReader::XML_HEADER: aDataType= "XML_HEADER "; break;
case LDOM_XmlReader::XML_DOCTYPE: aDataType= "XML_DOCTYPE "; break;
case LDOM_XmlReader::XML_COMMENT: aDataType= "XML_COMMENT "; break;
case LDOM_XmlReader::XML_START_ELEMENT: aDataType= "XML_START_ELEMENT"; break;
case LDOM_XmlReader::XML_END_ELEMENT: aDataType= "XML_END_ELEMENT "; break;
case LDOM_XmlReader::XML_FULL_ELEMENT: aDataType= "XML_FULL_ELEMENT "; break;
case LDOM_XmlReader::XML_TEXT: aDataType= "XML_TEXT "; break;
case LDOM_XmlReader::XML_CDATA: aDataType= "XML_CDATA "; break;
case LDOM_XmlReader::XML_EOF: aDataType= "XML_EOF ";
}
char * aStr = aData.str();
fprintf (ff, "%5d %s: %s\n", aCounter, aDataType, aStr);
delete [] aStr;
fclose (ff);
#endif
return aType;
}
//=======================================================================
//function : GetError
//purpose : Return text describing a parsing error
//=======================================================================
const TCollection_AsciiString& LDOMParser::GetError
(TCollection_AsciiString& aData) const
{
char * aStr =(char *)myCurrentData.str();
aData = aStr;
delete [] aStr;
return myError;
}
//=======================================================================
//function : parse
//purpose :
//=======================================================================
Standard_Boolean LDOMParser::parse (istream& anInput,
const Standard_Boolean theTagPerStep,
const Standard_Boolean theWithoutRoot)
{
// Open the DOM Document
myDocument = new LDOM_MemManager (20000);
myError.Clear();
// Create the Reader instance
if (myReader) delete myReader;
myReader = new LDOM_XmlReader (myDocument, myError, theTagPerStep);
// Parse
return ParseDocument (anInput, theWithoutRoot);
}
//=======================================================================
//function : parse
//purpose :
//=======================================================================
Standard_Boolean LDOMParser::parse (const char * const aFileName)
{
std::ifstream aFileStream;
OSD_OpenStream (aFileStream, aFileName, std::ios::in);
if (aFileStream.good())
{
return parse (aFileStream);
}
else
{
myError = "Fatal XML error: Cannot open XML file";
return Standard_True;
}
}
//=======================================================================
//function : ParseDocument
//purpose : parse the whole document (abstracted from the XML source)
//=======================================================================
Standard_Boolean LDOMParser::ParseDocument (istream& theIStream, const Standard_Boolean theWithoutRoot)
{
Standard_Boolean isError = Standard_False;
Standard_Boolean isElement = Standard_False;
Standard_Boolean isDoctype = Standard_False;
Standard_Boolean isInsertFictRootElement = Standard_False;
for(;;) {
LDOM_XmlReader::RecordType aType = (theWithoutRoot && !isInsertFictRootElement ?
LDOM_XmlReader::XML_START_ELEMENT :
ReadRecord (*myReader, theIStream, myCurrentData));
switch (aType) {
case LDOM_XmlReader::XML_HEADER:
if (isDoctype || isElement) {
myError = "Unexpected XML declaration";
isError = Standard_True;
break;
}
continue;
case LDOM_XmlReader::XML_DOCTYPE:
if (isElement) {
myError = "Unexpected DOCTYPE declaration";
isError = Standard_True;
break;
}
isDoctype = Standard_True;
continue;
case LDOM_XmlReader::XML_COMMENT:
continue;
case LDOM_XmlReader::XML_FULL_ELEMENT:
if (isElement == Standard_False) {
isElement = Standard_True;
myDocument -> myRootElement = &myReader -> GetElement ();
if (startElement()) {
isError = Standard_True;
myError = "User abort at startElement()";
break;
}
if (endElement()) {
isError = Standard_True;
myError = "User abort at endElement()";
break;
}
continue;
}
isError = Standard_True;
myError = "Expected comment or end-of-file";
break;
case LDOM_XmlReader::XML_START_ELEMENT:
if (isElement == Standard_False) {
isElement = Standard_True;
if (theWithoutRoot && !isInsertFictRootElement)
{
isInsertFictRootElement = Standard_True;
// create fiction root element
TCollection_AsciiString aFicName ("document");
myReader->CreateElement (aFicName.ToCString(), aFicName.Length());
}
myDocument->myRootElement = &myReader->GetElement();
if (startElement()) {
isError = Standard_True;
myError = "User abort at startElement()";
break;
}
isError = ParseElement (theIStream);
if (isError) break;
continue;
}
isError = Standard_True;
myError = "Expected comment or end-of-file";
break;
case LDOM_XmlReader::XML_END_ELEMENT:
if (endElement()) {
isError = Standard_True;
myError = "User abort at endElement()";
}
break;
case LDOM_XmlReader::XML_EOF:
break;
case LDOM_XmlReader::XML_UNKNOWN:
if (isElement) {
default:
myError = "Unexpected data beyond the Document Element";
}
isError = Standard_True;
}
break;
}
return isError;
}
//=======================================================================
//function : ParseElement
//purpose : parse one element, given the type of its XML presentation
//=======================================================================
Standard_Boolean LDOMParser::ParseElement (Standard_IStream& theIStream)
{
Standard_Boolean isError = Standard_False;
const LDOM_BasicElement * aParent = &myReader->GetElement();
const LDOM_BasicNode * aLastChild = NULL;
for(;;) {
LDOM_Node::NodeType aLocType;
LDOMBasicString aTextValue;
char *aTextStr;
LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, theIStream, myCurrentData);
switch (aType) {
case LDOM_XmlReader::XML_UNKNOWN:
isError = Standard_True;
break;
case LDOM_XmlReader::XML_FULL_ELEMENT:
aParent -> AppendChild (&myReader -> GetElement(), aLastChild);
if (startElement()) {
isError = Standard_True;
myError = "User abort at startElement()";
break;
}
if (endElement()) {
isError = Standard_True;
myError = "User abort at endElement()";
break;
}
break;
case LDOM_XmlReader::XML_START_ELEMENT:
aParent -> AppendChild (&myReader -> GetElement(), aLastChild);
if (startElement()) {
isError = Standard_True;
myError = "User abort at startElement()";
break;
}
isError = ParseElement (theIStream);
break;
case LDOM_XmlReader::XML_END_ELEMENT:
{
Standard_CString aParentName = Standard_CString(aParent->GetTagName());
aTextStr = (char *)myCurrentData.str();
if (strcmp(aTextStr, aParentName) != 0) {
myError = "Expected end tag \'";
myError += aParentName;
myError += "\'";
isError = Standard_True;
}
else if (endElement()) {
isError = Standard_True;
myError = "User abort at endElement()";
}
delete [] aTextStr;
}
return isError;
case LDOM_XmlReader::XML_TEXT:
aLocType = LDOM_Node::TEXT_NODE;
{
Standard_Integer aTextLen;
aTextStr = LDOM_CharReference::Decode ((char *)myCurrentData.str(), aTextLen);
// try to convert to integer
if (IsDigit(aTextStr[0])) {
if (LDOM_XmlReader::getInteger (aTextValue, aTextStr,
aTextStr + aTextLen))
aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
} else
aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
}
goto create_text_node;
case LDOM_XmlReader::XML_COMMENT:
aLocType = LDOM_Node::COMMENT_NODE;
{
Standard_Integer aTextLen;
aTextStr = LDOM_CharReference::Decode ((char *)myCurrentData.str(), aTextLen);
aTextValue = LDOMBasicString (aTextStr, aTextLen, myDocument);
}
goto create_text_node;
case LDOM_XmlReader::XML_CDATA:
aLocType = LDOM_Node::CDATA_SECTION_NODE;
aTextStr = (char *)myCurrentData.str();
aTextValue = LDOMBasicString(aTextStr,myCurrentData.Length(),myDocument);
create_text_node:
{
LDOM_BasicNode& aTextNode =
LDOM_BasicText::Create (aLocType, aTextValue, myDocument);
aParent -> AppendChild (&aTextNode, aLastChild);
}
delete [] aTextStr;
break;
case LDOM_XmlReader::XML_EOF:
myError = "Inexpected end of file";
isError = Standard_True;
break;
default: ;
}
if (isError) break;
}
return isError;
}
//=======================================================================
//function : startElement
//purpose : virtual hook on 'StartElement' event for descendant classes
//=======================================================================
Standard_Boolean LDOMParser::startElement ()
{
return Standard_False;
}
//=======================================================================
//function : endElement
//purpose : virtual hook on 'EndElement' event for descendant classes
//=======================================================================
Standard_Boolean LDOMParser::endElement ()
{
return Standard_False;
}
//=======================================================================
//function : getCurrentElement
//purpose :
//=======================================================================
LDOM_Element LDOMParser::getCurrentElement () const
{
return LDOM_Element (myReader -> GetElement(), myDocument);
}
//=======================================================================
//function : getDocument
//purpose :
//=======================================================================
LDOM_Document LDOMParser::getDocument ()
{
return myDocument -> Self();
}