mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0026229: Add the possibility in OCAF to open/save a document from/to a stream object
TDocStd_Application class extended to open/save a document of XmlOcaf and BinOcaf format from/to standard SEEKABLE stream object which should support SEEK functionality. Open and SaveAs DRAW commands got new additional argument "-stream" to turn on using of stream functionality. The main changes for BinOcaf format applied in: FSD_BinaryFile class (static method using standard stream added) BinLDrivers_DocumentRetrievalDriver and BinLDrivers_DocumentStorageDriver classes use standard stream object as an argument The main changes for XmlOcaf format applied in: LDOMParser and LDOM_XmlWriter classes use standard stream object as an argument Unused class FSD_Archive and its siblings removed from MFC samples.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include <LDOM_BasicText.hxx>
|
||||
#include <LDOM_CharReference.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
#include <OSD_OpenFile.hxx>
|
||||
|
||||
#include <fcntl.h>
|
||||
#ifdef _MSC_VER
|
||||
@@ -53,13 +54,14 @@ static
|
||||
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 (aData);
|
||||
const LDOM_XmlReader::RecordType aType = aReader.ReadRecord (theIStream, aData);
|
||||
#ifdef LDOM_PARSER_TRACE
|
||||
static FILE * ff = NULL;
|
||||
TCollection_AsciiString aTraceFileName;
|
||||
@@ -117,10 +119,10 @@ Standard_Boolean LDOMParser::parse (istream& anInput)
|
||||
|
||||
// Create the Reader instance
|
||||
if (myReader) delete myReader;
|
||||
myReader = new LDOM_XmlReader (anInput, myDocument, myError);
|
||||
myReader = new LDOM_XmlReader (myDocument, myError);
|
||||
|
||||
// Parse
|
||||
return ParseDocument();
|
||||
return ParseDocument (anInput);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -130,30 +132,18 @@ Standard_Boolean LDOMParser::parse (istream& anInput)
|
||||
|
||||
Standard_Boolean LDOMParser::parse (const char * const aFileName)
|
||||
{
|
||||
// Open the DOM Document
|
||||
myDocument = new LDOM_MemManager (20000);
|
||||
myError.Clear ();
|
||||
std::ifstream aFileStream;
|
||||
OSD_OpenStream (aFileStream, aFileName, std::ios::in);
|
||||
|
||||
// Open the file
|
||||
#ifdef _WIN32
|
||||
TCollection_ExtendedString aFileNameW(aFileName, Standard_True);
|
||||
int aFile = _wopen ((const wchar_t*) aFileNameW.ToExtString(), O_RDONLY);
|
||||
#else
|
||||
int aFile = open (aFileName, O_RDONLY);
|
||||
#endif
|
||||
if (aFile < 0) {
|
||||
if (aFileStream.good())
|
||||
{
|
||||
return parse (aFileStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
myError = "Fatal XML error: Cannot open XML file";
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// Create the Reader instance
|
||||
if (myReader) delete myReader;
|
||||
myReader = new LDOM_XmlReader (aFile, myDocument, myError);
|
||||
|
||||
// Parse
|
||||
Standard_Boolean isError = ParseDocument();
|
||||
close (aFile);
|
||||
return isError;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -161,14 +151,14 @@ Standard_Boolean LDOMParser::parse (const char * const aFileName)
|
||||
//purpose : parse the whole document (abstracted from the XML source)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean LDOMParser::ParseDocument ()
|
||||
Standard_Boolean LDOMParser::ParseDocument (istream& theIStream)
|
||||
{
|
||||
Standard_Boolean isError = Standard_False;
|
||||
Standard_Boolean isElement = Standard_False;
|
||||
Standard_Boolean isDoctype = Standard_False;
|
||||
|
||||
for(;;) {
|
||||
LDOM_XmlReader::RecordType aType = ReadRecord (*myReader, myCurrentData);
|
||||
LDOM_XmlReader::RecordType aType = ReadRecord (*myReader, theIStream, myCurrentData);
|
||||
switch (aType) {
|
||||
case LDOM_XmlReader::XML_HEADER:
|
||||
if (isDoctype || isElement) {
|
||||
@@ -211,7 +201,7 @@ Standard_Boolean LDOMParser::ParseDocument ()
|
||||
myError = "User abort at startElement()";
|
||||
break;
|
||||
}
|
||||
isError = ParseElement ();
|
||||
isError = ParseElement (theIStream);
|
||||
if (isError) break;
|
||||
continue;
|
||||
}
|
||||
@@ -241,7 +231,7 @@ Standard_Boolean LDOMParser::ParseDocument ()
|
||||
//purpose : parse one element, given the type of its XML presentation
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean LDOMParser::ParseElement ()
|
||||
Standard_Boolean LDOMParser::ParseElement (Standard_IStream& theIStream)
|
||||
{
|
||||
Standard_Boolean isError = Standard_False;
|
||||
const LDOM_BasicElement * aParent = &myReader->GetElement();
|
||||
@@ -250,7 +240,7 @@ Standard_Boolean LDOMParser::ParseElement ()
|
||||
LDOM_Node::NodeType aLocType;
|
||||
LDOMBasicString aTextValue;
|
||||
char *aTextStr;
|
||||
LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, myCurrentData);
|
||||
LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, theIStream, myCurrentData);
|
||||
switch (aType) {
|
||||
case LDOM_XmlReader::XML_UNKNOWN:
|
||||
isError = Standard_True;
|
||||
@@ -275,7 +265,7 @@ Standard_Boolean LDOMParser::ParseElement ()
|
||||
myError = "User abort at startElement()";
|
||||
break;
|
||||
}
|
||||
isError = ParseElement ();
|
||||
isError = ParseElement (theIStream);
|
||||
break;
|
||||
case LDOM_XmlReader::XML_END_ELEMENT:
|
||||
{
|
||||
|
@@ -73,9 +73,9 @@ class LDOMParser
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE METHODS ----------
|
||||
Standard_Boolean ParseDocument ();
|
||||
Standard_Boolean ParseDocument (Standard_IStream& theIStream);
|
||||
|
||||
Standard_Boolean ParseElement ();
|
||||
Standard_Boolean ParseElement (Standard_IStream& theIStream);
|
||||
|
||||
// ---------- PRIVATE (PROHIBITED) METHODS ----------
|
||||
|
||||
|
@@ -63,32 +63,10 @@ static Standard_Boolean isName (const char * aString,
|
||||
//purpose : Constructor (file descriptor)
|
||||
//=======================================================================
|
||||
|
||||
LDOM_XmlReader::LDOM_XmlReader (const int theFileDes,
|
||||
LDOM_XmlReader::LDOM_XmlReader (
|
||||
const Handle(LDOM_MemManager)& theDocument,
|
||||
TCollection_AsciiString& theErrorString)
|
||||
: myEOF (Standard_False),
|
||||
myFileDes (theFileDes),
|
||||
myIStream (cin), // just a placeholder, myIStream will never be used anyway
|
||||
myError (theErrorString),
|
||||
myDocument (theDocument),
|
||||
myElement (NULL),
|
||||
myLastChild(NULL),
|
||||
myPtr (&myBuffer[0]),
|
||||
myEndPtr (&myBuffer[0])
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LDOM_XmlReader()
|
||||
//purpose : Constructor (istream)
|
||||
//=======================================================================
|
||||
|
||||
LDOM_XmlReader::LDOM_XmlReader (istream& theInput,
|
||||
const Handle(LDOM_MemManager)& theDocument,
|
||||
TCollection_AsciiString& theErrorString)
|
||||
: myEOF (Standard_False),
|
||||
myFileDes (FILE_NONVALUE),
|
||||
myIStream (theInput),
|
||||
myError (theErrorString),
|
||||
myDocument (theDocument),
|
||||
myElement (NULL),
|
||||
@@ -103,8 +81,8 @@ LDOM_XmlReader::LDOM_XmlReader (istream& theInput,
|
||||
//purpose : Read a record from XML file
|
||||
//=======================================================================
|
||||
|
||||
LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord
|
||||
(LDOM_OSStream& theData)
|
||||
LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord (Standard_IStream& theIStream,
|
||||
LDOM_OSStream& theData)
|
||||
{
|
||||
theData.Clear();
|
||||
myError.Clear();
|
||||
@@ -136,14 +114,9 @@ LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord
|
||||
// Read the full buffer and reset start and end buffer pointers
|
||||
myPtr = &myBuffer[0];
|
||||
Standard_Size aNBytes;
|
||||
if (myFileDes != FILE_NONVALUE)
|
||||
aNBytes = read (myFileDes, &myBuffer[aBytesRest],
|
||||
theIStream.read (&myBuffer[aBytesRest],
|
||||
XML_BUFFER_SIZE - aBytesRest);
|
||||
else {
|
||||
myIStream.read (&myBuffer[aBytesRest],
|
||||
XML_BUFFER_SIZE - aBytesRest);
|
||||
aNBytes = (Standard_Size)myIStream.gcount();
|
||||
}
|
||||
aNBytes = (Standard_Size)theIStream.gcount();
|
||||
if (aNBytes == 0)
|
||||
myEOF = Standard_True; // END-OF-FILE
|
||||
myEndPtr = &myBuffer[aBytesRest + aNBytes];
|
||||
|
@@ -47,15 +47,12 @@ class LDOM_XmlReader
|
||||
};
|
||||
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
LDOM_XmlReader (const int aFileDes, const Handle(LDOM_MemManager)& aDocument,
|
||||
LDOM_XmlReader (const Handle(LDOM_MemManager)& aDocument,
|
||||
TCollection_AsciiString& anErrorString);
|
||||
// Constructor - takes a file descriptor for input
|
||||
|
||||
LDOM_XmlReader (istream& anInput, const Handle(LDOM_MemManager)& aDocument,
|
||||
TCollection_AsciiString& anErrorString);
|
||||
// Constructor - takes an istream for input
|
||||
|
||||
RecordType ReadRecord (LDOM_OSStream& theData);
|
||||
RecordType ReadRecord (Standard_IStream& theIStream, LDOM_OSStream& theData);
|
||||
// reading a markup or other element of XML format
|
||||
|
||||
LDOM_BasicElement& GetElement () const { return * myElement; }
|
||||
@@ -78,8 +75,6 @@ class LDOM_XmlReader
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Standard_Boolean myEOF;
|
||||
int myFileDes; // alternative 1: file descriptor
|
||||
istream& myIStream; // alternative 2: istream
|
||||
TCollection_AsciiString & myError;
|
||||
Handle(LDOM_MemManager) myDocument;
|
||||
LDOM_BasicElement * myElement;
|
||||
|
@@ -93,326 +93,373 @@
|
||||
#define chLatin_Y 'Y'
|
||||
#define chLatin_Z 'Z'
|
||||
|
||||
static const LXMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
|
||||
static const LXMLCh gEndElement1[]= { chForwardSlash, chNull };
|
||||
//static const LXMLCh gEndPI[] = { chQuestion, chCloseAngle, chNull };
|
||||
//static const LXMLCh gStartPI[] = { chOpenAngle, chQuestion, chNull };
|
||||
static const LXMLCh gXMLDecl1[] =
|
||||
static const char gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
|
||||
static const char gEndElement1[]= { chForwardSlash, chNull };
|
||||
|
||||
static const char gXMLDecl1[] =
|
||||
{ chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l
|
||||
, chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i
|
||||
, chLatin_o, chLatin_n, chEqual, chDoubleQuote, chNull
|
||||
};
|
||||
static const LXMLCh gXMLDecl2[] =
|
||||
static const char gXMLDecl2[] =
|
||||
{ chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c
|
||||
, chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual
|
||||
, chDoubleQuote, chNull
|
||||
};
|
||||
/*
|
||||
static const LXMLCh gXMLDecl3[] =
|
||||
{ chDoubleQuote, chSpace, chLatin_s, chLatin_t, chLatin_a
|
||||
, chLatin_n, chLatin_d, chLatin_a, chLatin_l, chLatin_o
|
||||
, chLatin_n, chLatin_e, chEqual, chDoubleQuote, chNull
|
||||
};
|
||||
*/
|
||||
static const LXMLCh gXMLDecl4[] =
|
||||
|
||||
static const char gXMLDecl4[] =
|
||||
{ chDoubleQuote, chQuestion, chCloseAngle
|
||||
, chLF, chNull
|
||||
};
|
||||
static const LXMLCh gStartCDATA[] =
|
||||
static const char gStartCDATA[] =
|
||||
{ chOpenAngle, chBang, chOpenSquare, chLatin_C, chLatin_D,
|
||||
chLatin_A, chLatin_T, chLatin_A, chOpenSquare, chNull
|
||||
};
|
||||
static const LXMLCh gEndCDATA[] =
|
||||
static const char gEndCDATA[] =
|
||||
{ chCloseSquare, chCloseSquare, chCloseAngle, chNull };
|
||||
static const LXMLCh gStartComment[] =
|
||||
static const char gStartComment[] =
|
||||
{ chOpenAngle, chBang, chDash, chDash, chNull };
|
||||
static const LXMLCh gEndComment[] =
|
||||
static const char gEndComment[] =
|
||||
{ chDash, chDash, chCloseAngle, chNull };
|
||||
/*
|
||||
static const LXMLCh gStartDoctype[] =
|
||||
{ chOpenAngle, chBang, chLatin_D, chLatin_O, chLatin_C, chLatin_T,
|
||||
chLatin_Y, chLatin_P, chLatin_E, chSpace, chNull
|
||||
};
|
||||
static const LXMLCh gPublic[] =
|
||||
{ chLatin_P, chLatin_U, chLatin_B, chLatin_L, chLatin_I,
|
||||
chLatin_C, chSpace, chDoubleQuote, chNull
|
||||
};
|
||||
static const LXMLCh gSystem[] =
|
||||
{ chLatin_S, chLatin_Y, chLatin_S, chLatin_T, chLatin_E,
|
||||
chLatin_M, chSpace, chDoubleQuote, chNull
|
||||
};
|
||||
static const LXMLCh gStartEntity[] =
|
||||
{ chOpenAngle, chBang, chLatin_E, chLatin_N, chLatin_T, chLatin_I,
|
||||
chLatin_T, chLatin_Y, chSpace, chNull
|
||||
};
|
||||
static const LXMLCh gNotation[] =
|
||||
{ chLatin_N, chLatin_D, chLatin_A, chLatin_T, chLatin_A,
|
||||
chSpace, chDoubleQuote, chNull
|
||||
};
|
||||
*/
|
||||
|
||||
static LXMLCh * getEncodingName (const LXMLCh * theEncodingName)
|
||||
static char* getEncodingName (const char* theEncodingName)
|
||||
{
|
||||
const LXMLCh * anEncoding = theEncodingName;
|
||||
const char* anEncoding = theEncodingName;
|
||||
if (theEncodingName == NULL)
|
||||
{
|
||||
// anEncoding = // US-ASCII
|
||||
// { chLatin_U, chLatin_S, chDash, chLatin_A, chLatin_S, chLatin_C, chLatin_I,
|
||||
// chLatin_I, chNull };
|
||||
static const LXMLCh anUTFEncoding [] = // UTF-8
|
||||
{ chLatin_U, chLatin_T, chLatin_F, chDash, chEight, chNull };
|
||||
static const char anUTFEncoding [] = {chLatin_U, chLatin_T, chLatin_F, chDash, chEight, chNull};
|
||||
anEncoding = anUTFEncoding;
|
||||
}
|
||||
|
||||
Standard_Integer aLen = 0;
|
||||
while (anEncoding[aLen++] != chNull);
|
||||
LXMLCh * aResult = new LXMLCh [aLen];
|
||||
memcpy (aResult, anEncoding, aLen * sizeof (LXMLCh));
|
||||
|
||||
char * aResult = new char [aLen];
|
||||
memcpy (aResult, anEncoding, aLen * sizeof (char));
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LH3D_LXMLWriter()
|
||||
//purpose : Constructor
|
||||
//function : LDOM_XmlWriter
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
LDOM_XmlWriter::LDOM_XmlWriter (FILE * aFile,
|
||||
const LXMLCh * theEncoding)
|
||||
: myFile (aFile),
|
||||
myEncodingName (::getEncodingName (theEncoding)),
|
||||
myIndent (0),
|
||||
myCurIndent (0),
|
||||
myABuffer (NULL),
|
||||
myABufferLen (0)
|
||||
{}
|
||||
LDOM_XmlWriter::LDOM_XmlWriter (const char * theEncoding)
|
||||
: myEncodingName (::getEncodingName (theEncoding)),
|
||||
myIndent (0),
|
||||
myCurIndent (0),
|
||||
myABuffer (NULL),
|
||||
myABufferLen (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ~LDOM_XmlWriter
|
||||
//purpose : Destructor
|
||||
//=======================================================================
|
||||
|
||||
LDOM_XmlWriter::~LDOM_XmlWriter ()
|
||||
{
|
||||
delete [] myEncodingName;
|
||||
if (myABuffer != NULL) delete [] myABuffer;
|
||||
|
||||
if (myABuffer != NULL)
|
||||
{
|
||||
delete [] myABuffer;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : operator <<
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LDOM_Document& aDoc)
|
||||
void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOM_Document& aDoc)
|
||||
{
|
||||
const char * anXMLversion = "1.0";
|
||||
* this << gXMLDecl1 << anXMLversion
|
||||
<< gXMLDecl2 << myEncodingName << gXMLDecl4;
|
||||
Write (theOStream, gXMLDecl1);
|
||||
|
||||
return (* this << aDoc.getDocumentElement());
|
||||
const char * anXMLversion = "1.0";
|
||||
Write (theOStream, anXMLversion);
|
||||
|
||||
Write (theOStream, gXMLDecl2);
|
||||
Write (theOStream, myEncodingName);
|
||||
Write (theOStream, gXMLDecl4);
|
||||
|
||||
Write (theOStream, aDoc.getDocumentElement());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : operator <<
|
||||
//purpose : Stream out an LDOMString
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline LDOM_XmlWriter& LDOM_XmlWriter::operator <<
|
||||
(const LDOMBasicString& aString)
|
||||
{
|
||||
switch (aString.Type()) {
|
||||
case LDOMBasicString::LDOM_Integer:
|
||||
{
|
||||
Standard_Integer aValue;
|
||||
aString.GetInteger (aValue);
|
||||
fprintf (myFile, "%d", aValue);
|
||||
break;
|
||||
}
|
||||
case LDOMBasicString::LDOM_AsciiHashed: // attr names and element tags
|
||||
case LDOMBasicString::LDOM_AsciiDocClear:
|
||||
{
|
||||
const char * str = aString.GetString();
|
||||
if (str) {
|
||||
const Standard_Size aLen = strlen (str);
|
||||
if (aLen > 0) fwrite (str, aLen, 1, myFile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LDOMBasicString::LDOM_AsciiFree:
|
||||
case LDOMBasicString::LDOM_AsciiDoc:
|
||||
{
|
||||
const char * str = aString.GetString();
|
||||
if (str) {
|
||||
Standard_Integer aLen;
|
||||
char * encStr = LDOM_CharReference::Encode(str, aLen, Standard_False);
|
||||
if (aLen > 0) fwrite (encStr, aLen, 1, myFile);
|
||||
if (encStr != str) delete [] encStr;
|
||||
}
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
return * this;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : operator<<()
|
||||
//purpose : Stream out a char *.
|
||||
//=======================================================================
|
||||
inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh * aString)
|
||||
{
|
||||
Standard_Size aLength = strlen (aString);
|
||||
if (aLength > 0) fwrite ((void *) aString, aLength, 1, myFile);
|
||||
return * this;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : operator<<()
|
||||
//purpose : Stream out a character.
|
||||
//=======================================================================
|
||||
inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh aChar)
|
||||
{
|
||||
fputc (aChar, myFile);
|
||||
return * this;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WriteAttribute()
|
||||
//purpose : Stream out an XML attribute.
|
||||
//=======================================================================
|
||||
void LDOM_XmlWriter::WriteAttribute (const LDOM_Node& theAtt)
|
||||
{
|
||||
int aLength;
|
||||
const char * aName = theAtt.getNodeName().GetString();
|
||||
const LDOMString aValueStr = theAtt.getNodeValue();
|
||||
|
||||
// Integer attribute value
|
||||
if (aValueStr.Type() == LDOMBasicString::LDOM_Integer) {
|
||||
Standard_Integer anIntValue;
|
||||
aValueStr.GetInteger (anIntValue);
|
||||
aLength = (Standard_Integer) (20 + strlen (aName));
|
||||
if (aLength > myABufferLen) {
|
||||
if (myABuffer != NULL) delete [] myABuffer;
|
||||
myABuffer = new char [aLength+1];
|
||||
myABufferLen = aLength;
|
||||
}
|
||||
sprintf (myABuffer, "%c%s%c%c%d%c", chSpace, aName,
|
||||
chEqual, chDoubleQuote, anIntValue, chDoubleQuote);
|
||||
aLength = (Standard_Integer) strlen (myABuffer);
|
||||
|
||||
// String attribute value
|
||||
} else {
|
||||
const char * aValue = aValueStr.GetString();
|
||||
char * encStr;
|
||||
if (aValueStr.Type() == LDOMBasicString::LDOM_AsciiDocClear) {
|
||||
encStr = (char *) aValue;
|
||||
aLength = (Standard_Integer) (4 + strlen (aValue) + strlen (aName));
|
||||
} else {
|
||||
encStr = LDOM_CharReference::Encode (aValue, aLength, Standard_True);
|
||||
aLength += (Standard_Integer) (4 + strlen (aName));
|
||||
}
|
||||
if (aLength > myABufferLen) {
|
||||
if (myABuffer != NULL) delete [] myABuffer;
|
||||
myABuffer = new char [aLength+1];
|
||||
myABufferLen = aLength;
|
||||
}
|
||||
sprintf (myABuffer, "%c%s%c%c%s%c", chSpace, aName,
|
||||
chEqual, chDoubleQuote, encStr, chDoubleQuote);
|
||||
if (encStr != aValue) delete [] encStr;
|
||||
}
|
||||
fwrite ((void *) myABuffer, aLength, 1, myFile);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : operator<<()
|
||||
//purpose : Stream out a DOM node, and, recursively, all of its children.
|
||||
// This function is the heart of writing a DOM tree out as XML source.
|
||||
// Give it a document node and it will do the whole thing.
|
||||
//=======================================================================
|
||||
LDOM_XmlWriter& LDOM_XmlWriter::operator<< (const LDOM_Node& theNodeToWrite)
|
||||
void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOM_Node& theNode)
|
||||
{
|
||||
// Get the name and value out for convenience
|
||||
LDOMString aNodeName = theNodeToWrite.getNodeName();
|
||||
LDOMString aNodeValue = theNodeToWrite.getNodeValue();
|
||||
// unsigned long dwLent = aNodeValue.length();
|
||||
LDOMString aNodeName = theNode.getNodeName();
|
||||
LDOMString aNodeValue = theNode.getNodeValue();
|
||||
|
||||
switch (theNodeToWrite.getNodeType())
|
||||
switch (theNode.getNodeType())
|
||||
{
|
||||
case LDOM_Node::TEXT_NODE :
|
||||
* this << aNodeValue;
|
||||
case LDOM_Node::TEXT_NODE :
|
||||
Write (theOStream, aNodeValue);
|
||||
break;
|
||||
case LDOM_Node::ELEMENT_NODE :
|
||||
case LDOM_Node::ELEMENT_NODE :
|
||||
{
|
||||
const int aMaxNSpaces = 40;
|
||||
static LXMLCh aSpaces [] = {
|
||||
static char aSpaces [] = {
|
||||
chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
|
||||
chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
|
||||
chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
|
||||
chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
|
||||
chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
|
||||
chOpenAngle, chNull };
|
||||
const LXMLCh * anIndentString = &aSpaces [aMaxNSpaces - myCurIndent];
|
||||
if (anIndentString < &aSpaces[0]) anIndentString = &aSpaces[0];
|
||||
const char * anIndentString = &aSpaces [aMaxNSpaces - myCurIndent];
|
||||
|
||||
if (anIndentString < &aSpaces[0])
|
||||
{
|
||||
anIndentString = &aSpaces[0];
|
||||
}
|
||||
|
||||
// Output the element start tag.
|
||||
* this << anIndentString << aNodeName.GetString();
|
||||
Write (theOStream, anIndentString);
|
||||
Write (theOStream, aNodeName.GetString());
|
||||
|
||||
// Output any attributes of this element
|
||||
const LDOM_Element& anElemToWrite = (const LDOM_Element&) theNodeToWrite;
|
||||
LDOM_NodeList aListAtt = anElemToWrite.GetAttributesList ();
|
||||
// Output any attributes of this element
|
||||
const LDOM_Element& anElemToWrite = (const LDOM_Element&)theNode;
|
||||
LDOM_NodeList aListAtt = anElemToWrite.GetAttributesList();
|
||||
Standard_Integer aListInd = aListAtt.getLength();
|
||||
while (aListInd--) {
|
||||
|
||||
while (aListInd--)
|
||||
{
|
||||
LDOM_Node aChild = aListAtt.item (aListInd);
|
||||
WriteAttribute (aChild);
|
||||
WriteAttribute (theOStream, aChild);
|
||||
}
|
||||
|
||||
// Test for the presence of children
|
||||
LDOM_Node aChild = theNodeToWrite.getFirstChild();
|
||||
LDOM_Node aChild = theNode.getFirstChild();
|
||||
if (aChild != 0)
|
||||
{
|
||||
// There are children. Close start-tag, and output children.
|
||||
* this << chCloseAngle;
|
||||
Write (theOStream, chCloseAngle);
|
||||
if (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE && myIndent > 0)
|
||||
* this << chLF;
|
||||
{
|
||||
Write(theOStream, chLF);
|
||||
}
|
||||
|
||||
Standard_Boolean isChildElem = Standard_False;
|
||||
while( aChild != 0)
|
||||
{
|
||||
isChildElem = (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE);
|
||||
if (isChildElem) myCurIndent += myIndent;
|
||||
*this << aChild;
|
||||
if (isChildElem) myCurIndent -= myIndent;
|
||||
do aChild = aChild.getNextSibling();
|
||||
while (aChild.getNodeType() == LDOM_Node::ATTRIBUTE_NODE);
|
||||
if (isChildElem)
|
||||
{
|
||||
myCurIndent += myIndent;
|
||||
}
|
||||
|
||||
Write(theOStream, aChild);
|
||||
|
||||
if (isChildElem)
|
||||
{
|
||||
myCurIndent -= myIndent;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
aChild = aChild.getNextSibling();
|
||||
} while (aChild.getNodeType() == LDOM_Node::ATTRIBUTE_NODE);
|
||||
}
|
||||
|
||||
// Done with children. Output the end tag.
|
||||
//
|
||||
if (isChildElem)
|
||||
* this << anIndentString
|
||||
<< gEndElement1 << aNodeName.GetString() << chCloseAngle;
|
||||
{
|
||||
Write (theOStream, anIndentString);
|
||||
Write (theOStream, gEndElement1);
|
||||
Write (theOStream, aNodeName.GetString());
|
||||
Write (theOStream, chCloseAngle);
|
||||
}
|
||||
else
|
||||
* this << gEndElement << aNodeName.GetString() << chCloseAngle;
|
||||
{
|
||||
Write (theOStream, gEndElement);
|
||||
Write (theOStream, aNodeName.GetString());
|
||||
Write (theOStream, chCloseAngle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// There were no children. Output the short form close of
|
||||
// the element start tag, making it an empty-element tag.
|
||||
* this << chForwardSlash << chCloseAngle;
|
||||
Write (theOStream, chForwardSlash);
|
||||
Write (theOStream, chCloseAngle);
|
||||
}
|
||||
|
||||
if (myIndent > 0)
|
||||
* this << chLF;
|
||||
{
|
||||
Write (theOStream, chLF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LDOM_Node::CDATA_SECTION_NODE:
|
||||
{
|
||||
* this << gStartCDATA << aNodeValue << gEndCDATA;
|
||||
Write (theOStream, gStartCDATA);
|
||||
Write (theOStream, aNodeValue);
|
||||
Write (theOStream, gEndCDATA);
|
||||
break;
|
||||
}
|
||||
case LDOM_Node::COMMENT_NODE:
|
||||
{
|
||||
* this << gStartComment << aNodeValue << gEndComment;
|
||||
Write (theOStream, gStartComment);
|
||||
Write (theOStream, aNodeValue);
|
||||
Write (theOStream, gEndComment);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
#ifndef _MSC_VER
|
||||
cerr << "Unrecognized node type = "
|
||||
<< (long)theNodeToWrite.getNodeType() << endl
|
||||
<< (long)theNode.getNodeType() << endl
|
||||
#endif
|
||||
; }
|
||||
return *this;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function :
|
||||
//purpose : Stream out an LDOMString
|
||||
//=======================================================================
|
||||
void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOMBasicString& theString)
|
||||
{
|
||||
switch (theString.Type())
|
||||
{
|
||||
case LDOMBasicString::LDOM_Integer:
|
||||
{
|
||||
Standard_Integer aValue;
|
||||
theString.GetInteger (aValue);
|
||||
|
||||
TCollection_AsciiString aStrValue (aValue);
|
||||
theOStream.write(aStrValue.ToCString(), strlen (aStrValue.ToCString()));
|
||||
|
||||
break;
|
||||
}
|
||||
case LDOMBasicString::LDOM_AsciiHashed: // attr names and element tags
|
||||
case LDOMBasicString::LDOM_AsciiDocClear:
|
||||
{
|
||||
const char* aStr = theString.GetString();
|
||||
if (aStr)
|
||||
{
|
||||
const Standard_Size aLen = strlen (aStr);
|
||||
if (aLen > 0)
|
||||
{
|
||||
theOStream.write(aStr, aLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LDOMBasicString::LDOM_AsciiFree:
|
||||
case LDOMBasicString::LDOM_AsciiDoc:
|
||||
{
|
||||
const char* aStr = theString.GetString();
|
||||
if (aStr)
|
||||
{
|
||||
Standard_Integer aLen;
|
||||
char* encStr = LDOM_CharReference::Encode (aStr, aLen, Standard_False);
|
||||
if (aLen > 0)
|
||||
{
|
||||
theOStream.write(encStr, aLen);
|
||||
}
|
||||
|
||||
if (encStr != aStr)
|
||||
{
|
||||
delete [] encStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Write
|
||||
//purpose : Stream out a char
|
||||
//=======================================================================
|
||||
void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const char theChar)
|
||||
{
|
||||
theOStream.write (&theChar, sizeof(char));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Write
|
||||
//purpose : Stream out a char *
|
||||
//=======================================================================
|
||||
void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const char * theString)
|
||||
{
|
||||
Standard_Size aLength = strlen (theString);
|
||||
if (aLength > 0)
|
||||
{
|
||||
theOStream.write (theString, aLength);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WriteAttribute()
|
||||
//purpose : Stream out an XML attribute.
|
||||
//=======================================================================
|
||||
void LDOM_XmlWriter::WriteAttribute (Standard_OStream& theOStream, const LDOM_Node& theAtt)
|
||||
{
|
||||
const char* aName = theAtt.getNodeName().GetString();
|
||||
const LDOMString aValueStr = theAtt.getNodeValue();
|
||||
|
||||
int aLength = 0;
|
||||
|
||||
// Integer attribute value
|
||||
if (aValueStr.Type() == LDOMBasicString::LDOM_Integer)
|
||||
{
|
||||
Standard_Integer anIntValue;
|
||||
aValueStr.GetInteger (anIntValue);
|
||||
|
||||
aLength = (Standard_Integer)(20 + strlen (aName));
|
||||
if (aLength > myABufferLen)
|
||||
{
|
||||
if (myABuffer != NULL)
|
||||
{
|
||||
delete [] myABuffer;
|
||||
}
|
||||
|
||||
myABuffer = new char [aLength+1];
|
||||
myABufferLen = aLength;
|
||||
}
|
||||
sprintf (myABuffer, "%c%s%c%c%d%c", chSpace, aName, chEqual, chDoubleQuote, anIntValue, chDoubleQuote);
|
||||
aLength = (Standard_Integer)strlen (myABuffer);
|
||||
|
||||
|
||||
}
|
||||
else // String attribute value
|
||||
{
|
||||
char* encStr;
|
||||
const char* aValue = aValueStr.GetString();
|
||||
if (aValueStr.Type() == LDOMBasicString::LDOM_AsciiDocClear)
|
||||
{
|
||||
encStr = (char *) aValue;
|
||||
aLength = (Standard_Integer) (4 + strlen (aValue) + strlen (aName));
|
||||
}
|
||||
else
|
||||
{
|
||||
encStr = LDOM_CharReference::Encode (aValue, aLength, Standard_True);
|
||||
aLength += (Standard_Integer) (4 + strlen (aName));
|
||||
}
|
||||
|
||||
if (aLength > myABufferLen)
|
||||
{
|
||||
if (myABuffer != NULL)
|
||||
{
|
||||
delete [] myABuffer;
|
||||
}
|
||||
|
||||
myABuffer = new char [aLength+1];
|
||||
myABufferLen = aLength;
|
||||
}
|
||||
|
||||
sprintf (myABuffer, "%c%s%c%c%s%c", chSpace, aName, chEqual, chDoubleQuote, encStr, chDoubleQuote);
|
||||
|
||||
if (encStr != aValue)
|
||||
{
|
||||
delete [] encStr;
|
||||
}
|
||||
}
|
||||
|
||||
theOStream.write (myABuffer, aLength);
|
||||
}
|
||||
|
@@ -16,63 +16,51 @@
|
||||
#ifndef LDOM_XmlWriter_HeaderFile
|
||||
#define LDOM_XmlWriter_HeaderFile
|
||||
|
||||
#include <Standard_OStream.hxx>
|
||||
#include <Standard_TypeDef.hxx>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef char LXMLCh;
|
||||
|
||||
class LDOM_Document;
|
||||
class LDOM_Node;
|
||||
class LDOMBasicString;
|
||||
|
||||
class LDOM_XmlWriter
|
||||
{
|
||||
public:
|
||||
|
||||
Standard_EXPORT LDOM_XmlWriter (FILE * aFile, const char * theEncoding= NULL);
|
||||
// Constructor
|
||||
public:
|
||||
|
||||
Standard_EXPORT LDOM_XmlWriter (const char* theEncoding = NULL);
|
||||
|
||||
Standard_EXPORT ~LDOM_XmlWriter ();
|
||||
// Destructor
|
||||
|
||||
void SetIndentation (const Standard_Integer theIndent) { myIndent=theIndent; }
|
||||
// Set indentation for output (by default 0)
|
||||
void SetIndentation (const Standard_Integer theIndent) { myIndent = theIndent; }
|
||||
|
||||
Standard_EXPORT LDOM_XmlWriter& operator<< (const LDOM_Document& aDoc);
|
||||
Standard_EXPORT void Write (Standard_OStream& theOStream, const LDOM_Document& theDoc);
|
||||
|
||||
Standard_EXPORT LDOM_XmlWriter& operator<< (const LDOM_Node& toWrite);
|
||||
// ostream << DOM_Node
|
||||
// Stream out a DOM node, and, recursively, all of its children. This
|
||||
// function is the heart of writing a DOM tree out as XML source. Give it
|
||||
// a document node and it will do the whole thing.
|
||||
Standard_EXPORT void Write (Standard_OStream& theOStream, const LDOM_Node& theNode);
|
||||
|
||||
private:
|
||||
|
||||
void WriteAttribute (const LDOM_Node& theAtt);
|
||||
|
||||
LDOM_XmlWriter& operator<< (const LDOMBasicString&);
|
||||
// Stream out LDOM String
|
||||
|
||||
inline LDOM_XmlWriter& operator<< (const LXMLCh * toWrite);
|
||||
// Stream out a character string. Doing this requires that we first transcode
|
||||
// to char * form in the default code page for the system
|
||||
|
||||
inline LDOM_XmlWriter& operator << (const LXMLCh aChar);
|
||||
private:
|
||||
|
||||
LDOM_XmlWriter (const LDOM_XmlWriter& anOther);
|
||||
// Copy constructor - prohibited
|
||||
|
||||
LDOM_XmlWriter& operator = (const LDOM_XmlWriter& anOther);
|
||||
// Assignment operator - prohibited
|
||||
|
||||
void Write (Standard_OStream& theOStream, const LDOMBasicString& theString);
|
||||
void Write (Standard_OStream& theOStream, const char* theString);
|
||||
void Write (Standard_OStream& theOStream, const char theChar);
|
||||
|
||||
void WriteAttribute (Standard_OStream& theOStream, const LDOM_Node& theAtt);
|
||||
|
||||
private:
|
||||
|
||||
FILE * myFile;
|
||||
LXMLCh * myEncodingName;
|
||||
Standard_Integer myIndent;
|
||||
Standard_Integer myCurIndent;
|
||||
char * myABuffer; // for WriteAttribute()
|
||||
Standard_Integer myABufferLen; // for WriteAttribute()
|
||||
char* myEncodingName;
|
||||
Standard_Integer myIndent;
|
||||
Standard_Integer myCurIndent;
|
||||
char* myABuffer;
|
||||
Standard_Integer myABufferLen;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user