mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0027077: OCAF: Implementation of streaming save/load (OCC26229) is incomplete/incorrect
XmlOcaf reading is non-seekable // 1. Read method of XmlLDrivers_DocumentRetrievalDriver extended to read complete document (with "document" tag) in compatible mode (when reading is performed from file) // 2. the empty statement removed // 3. the description of LDOMPARSER::parse method extended
This commit is contained in:
@@ -111,7 +111,9 @@ const TCollection_AsciiString& LDOMParser::GetError
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean LDOMParser::parse (istream& anInput)
|
||||
Standard_Boolean LDOMParser::parse (istream& anInput,
|
||||
const Standard_Boolean theTagPerStep,
|
||||
const Standard_Boolean theWithoutRoot)
|
||||
{
|
||||
// Open the DOM Document
|
||||
myDocument = new LDOM_MemManager (20000);
|
||||
@@ -119,10 +121,10 @@ Standard_Boolean LDOMParser::parse (istream& anInput)
|
||||
|
||||
// Create the Reader instance
|
||||
if (myReader) delete myReader;
|
||||
myReader = new LDOM_XmlReader (myDocument, myError);
|
||||
myReader = new LDOM_XmlReader (myDocument, myError, theTagPerStep);
|
||||
|
||||
// Parse
|
||||
return ParseDocument (anInput);
|
||||
return ParseDocument (anInput, theWithoutRoot);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -151,14 +153,18 @@ Standard_Boolean LDOMParser::parse (const char * const aFileName)
|
||||
//purpose : parse the whole document (abstracted from the XML source)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean LDOMParser::ParseDocument (istream& theIStream)
|
||||
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 = ReadRecord (*myReader, theIStream, myCurrentData);
|
||||
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) {
|
||||
@@ -195,7 +201,18 @@ Standard_Boolean LDOMParser::ParseDocument (istream& theIStream)
|
||||
case LDOM_XmlReader::XML_START_ELEMENT:
|
||||
if (isElement == Standard_False) {
|
||||
isElement = Standard_True;
|
||||
myDocument -> myRootElement = &myReader -> GetElement ();
|
||||
|
||||
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()";
|
||||
|
@@ -48,8 +48,16 @@ class LDOMParser
|
||||
// Returns True if error occurred, then GetError() can be called
|
||||
|
||||
Standard_EXPORT Standard_Boolean
|
||||
parse (istream& anInput);
|
||||
parse (istream& anInput,
|
||||
const Standard_Boolean theTagPerStep = Standard_False,
|
||||
const Standard_Boolean theWithoutRoot = Standard_False);
|
||||
// Parse a C++ stream
|
||||
// theTagPerStep - if true - extract characters from anInput until '>'
|
||||
// extracted character and parse only these characters.
|
||||
// if false - extract until eof
|
||||
// theWithoutRoot - if true - create fictive "document" element before parsing
|
||||
// and consider that document start element has been already read
|
||||
// - if false - parse a document as usual (parse header, document tag and etc)
|
||||
// Returns True if error occurred, then GetError() can be called
|
||||
|
||||
Standard_EXPORT const TCollection_AsciiString&
|
||||
@@ -73,7 +81,7 @@ class LDOMParser
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE METHODS ----------
|
||||
Standard_Boolean ParseDocument (Standard_IStream& theIStream);
|
||||
Standard_Boolean ParseDocument (Standard_IStream& theIStream, const Standard_Boolean theWithoutRoot = Standard_False);
|
||||
|
||||
Standard_Boolean ParseElement (Standard_IStream& theIStream);
|
||||
|
||||
|
@@ -64,14 +64,16 @@ static Standard_Boolean isName (const char * aString,
|
||||
|
||||
LDOM_XmlReader::LDOM_XmlReader (
|
||||
const Handle(LDOM_MemManager)& theDocument,
|
||||
TCollection_AsciiString& theErrorString)
|
||||
TCollection_AsciiString& theErrorString,
|
||||
const Standard_Boolean theTagPerStep)
|
||||
: myEOF (Standard_False),
|
||||
myError (theErrorString),
|
||||
myDocument (theDocument),
|
||||
myElement (NULL),
|
||||
myLastChild(NULL),
|
||||
myPtr (&myBuffer[0]),
|
||||
myEndPtr (&myBuffer[0])
|
||||
myEndPtr (&myBuffer[0]),
|
||||
myTagPerStep (theTagPerStep)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -89,17 +91,25 @@ LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord (Standard_IStream& theIStr
|
||||
const char * aStartData = NULL, * aNameEnd = NULL, * aPtr;
|
||||
LDOMBasicString anAttrName, anAttrValue;
|
||||
char anAttDelimiter = '\0';
|
||||
Standard_Boolean aHasRead = Standard_False;
|
||||
|
||||
for(;;) {
|
||||
// Check if the current file buffer is exhausted
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// There should always be some bytes available in the buffer for analysis
|
||||
Standard_Integer aBytesRest = (Standard_Integer)(myEndPtr - myPtr);
|
||||
if (aBytesRest < XML_MIN_BUFFER) {
|
||||
if (myEOF == Standard_True) {
|
||||
if (aBytesRest < XML_MIN_BUFFER)
|
||||
{
|
||||
if (myEOF == Standard_True)
|
||||
{
|
||||
if (aBytesRest <= 0)
|
||||
break; // END of processing
|
||||
} else {
|
||||
}
|
||||
else if (myTagPerStep && aHasRead)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are reading some data, save the beginning and preserve the state
|
||||
if (aStartData /* && aState != STATE_WAITING */) {
|
||||
if (myPtr > aStartData)
|
||||
@@ -113,11 +123,27 @@ LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord (Standard_IStream& theIStr
|
||||
// Read the full buffer and reset start and end buffer pointers
|
||||
myPtr = &myBuffer[0];
|
||||
Standard_Size aNBytes;
|
||||
theIStream.read (&myBuffer[aBytesRest],
|
||||
XML_BUFFER_SIZE - aBytesRest);
|
||||
aNBytes = (Standard_Size)theIStream.gcount();
|
||||
|
||||
if (myTagPerStep)
|
||||
{
|
||||
theIStream.getline (&myBuffer[aBytesRest], XML_BUFFER_SIZE - aBytesRest, '>');
|
||||
aHasRead = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
theIStream.read (&myBuffer[aBytesRest], XML_BUFFER_SIZE - aBytesRest);
|
||||
}
|
||||
aNBytes = (Standard_Size)theIStream.gcount();
|
||||
|
||||
if (aNBytes == 0)
|
||||
{
|
||||
myEOF = Standard_True; // END-OF-FILE
|
||||
}
|
||||
else if (myTagPerStep)
|
||||
{
|
||||
// replace \0 (being inserted by getline method) with >
|
||||
myBuffer[aBytesRest + aNBytes - 1] = '>';
|
||||
}
|
||||
myEndPtr = &myBuffer[aBytesRest + aNBytes];
|
||||
myBuffer[aBytesRest + aNBytes] = '\0';
|
||||
}
|
||||
@@ -536,6 +562,15 @@ static Standard_Boolean isName (const char * aString,
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CreateElement
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void LDOM_XmlReader::CreateElement( const char *theName, const Standard_Integer theLen )
|
||||
{
|
||||
myElement = &LDOM_BasicElement::Create (theName, theLen, myDocument);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : getInteger
|
||||
//purpose : Try to initialize theValue as Integer; return False on success
|
||||
|
@@ -48,7 +48,8 @@ class LDOM_XmlReader
|
||||
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
LDOM_XmlReader (const Handle(LDOM_MemManager)& aDocument,
|
||||
TCollection_AsciiString& anErrorString);
|
||||
TCollection_AsciiString& anErrorString,
|
||||
const Standard_Boolean theTagPerStep = Standard_False);
|
||||
// Constructor - takes a file descriptor for input
|
||||
// Constructor - takes an istream for input
|
||||
|
||||
@@ -58,6 +59,8 @@ class LDOM_XmlReader
|
||||
LDOM_BasicElement& GetElement () const { return * myElement; }
|
||||
// get the last element retrieved from the stream
|
||||
|
||||
void CreateElement (const char *theName, const Standard_Integer theLen);
|
||||
|
||||
static Standard_Boolean getInteger (LDOMBasicString& theValue,
|
||||
const char * theStart,
|
||||
const char * theEnd);
|
||||
@@ -82,6 +85,7 @@ class LDOM_XmlReader
|
||||
const char * myPtr;
|
||||
const char * myEndPtr;
|
||||
char myBuffer [XML_BUFFER_SIZE+4];
|
||||
Standard_Boolean myTagPerStep;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user