Implement CDATA reader, fix bugs in Writer::insertBinFile
This commit is contained in:
@@ -257,13 +257,18 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
|
||||
void PropertyFileIncluded::Save (Base::Writer &writer) const
|
||||
{
|
||||
if (writer.isForceXML()) {
|
||||
writer.Stream() << writer.ind() << "<FileIncluded file=\"\">" << endl;
|
||||
|
||||
// write the file in the XML stream
|
||||
if (!_cValue.empty())
|
||||
if (!_cValue.empty()) {
|
||||
Base::FileInfo file(_cValue.c_str());
|
||||
writer.Stream() << writer.ind() << "<FileIncluded data=\"" <<
|
||||
file.fileName() << "\">" << std::endl;
|
||||
// write the file in the XML stream
|
||||
writer.incInd();
|
||||
writer.insertBinFile(_cValue.c_str());
|
||||
|
||||
writer.Stream() << writer.ind() <<"</FileIncluded>" << endl ;
|
||||
writer.decInd();
|
||||
writer.Stream() << writer.ind() <<"</FileIncluded>" << endl;
|
||||
}
|
||||
else
|
||||
writer.Stream() << writer.ind() << "<FileIncluded data=\"\"/>" << std::endl;
|
||||
}
|
||||
else {
|
||||
// instead initiate an extra file
|
||||
@@ -280,17 +285,30 @@ void PropertyFileIncluded::Save (Base::Writer &writer) const
|
||||
void PropertyFileIncluded::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
reader.readElement("FileIncluded");
|
||||
string file (reader.getAttribute("file") );
|
||||
|
||||
if (!file.empty()) {
|
||||
// initate a file read
|
||||
reader.addFile(file.c_str(),this);
|
||||
|
||||
// is in the document transient path
|
||||
aboutToSetValue();
|
||||
_cValue = getDocTransientPath() + "/" + file;
|
||||
_BaseFileName = file;
|
||||
hasSetValue();
|
||||
if (reader.hasAttribute("file")) {
|
||||
string file (reader.getAttribute("file") );
|
||||
if (!file.empty()) {
|
||||
// initate a file read
|
||||
reader.addFile(file.c_str(),this);
|
||||
// is in the document transient path
|
||||
aboutToSetValue();
|
||||
_cValue = getDocTransientPath() + "/" + file;
|
||||
_BaseFileName = file;
|
||||
hasSetValue();
|
||||
}
|
||||
}
|
||||
// section is XML stream
|
||||
else if (reader.hasAttribute("data")) {
|
||||
string file (reader.getAttribute("data") );
|
||||
if (!file.empty()) {
|
||||
// is in the document transient path
|
||||
aboutToSetValue();
|
||||
_cValue = getDocTransientPath() + "/" + file;
|
||||
reader.readBinFile(_cValue.c_str());
|
||||
reader.readEndElement("FileIncluded");
|
||||
_BaseFileName = file;
|
||||
hasSetValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
/// Here the FreeCAD includes sorted by Base,App,Gui......
|
||||
#include "Reader.h"
|
||||
#include "Base64.h"
|
||||
#include "Exception.h"
|
||||
#include "Persistence.h"
|
||||
#include "InputSource.h"
|
||||
@@ -79,6 +80,7 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
|
||||
//parser->setFeature(XMLUni::fgXercesDynamic, true);
|
||||
|
||||
parser->setContentHandler(this);
|
||||
parser->setLexicalHandler(this);
|
||||
parser->setErrorHandler(this);
|
||||
|
||||
try {
|
||||
@@ -127,7 +129,7 @@ long Base::XMLReader::getAttributeAsInteger(const char* AttrName) const
|
||||
if (pos != AttrMap.end())
|
||||
return atol(pos->second.c_str());
|
||||
else
|
||||
// wrong name, use hasAttribute if not shure!
|
||||
// wrong name, use hasAttribute if not sure!
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
@@ -140,7 +142,7 @@ unsigned long Base::XMLReader::getAttributeAsUnsigned(const char* AttrName) cons
|
||||
if (pos != AttrMap.end())
|
||||
return strtoul(pos->second.c_str(),0,10);
|
||||
else
|
||||
// wrong name, use hasAttribute if not shure!
|
||||
// wrong name, use hasAttribute if not sure!
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
@@ -153,7 +155,7 @@ double Base::XMLReader::getAttributeAsFloat (const char* AttrName) const
|
||||
if (pos != AttrMap.end())
|
||||
return atof(pos->second.c_str());
|
||||
else
|
||||
// wrong name, use hasAttribute if not shure!
|
||||
// wrong name, use hasAttribute if not sure!
|
||||
assert(0);
|
||||
|
||||
return 0.0;
|
||||
@@ -166,7 +168,7 @@ const char* Base::XMLReader::getAttribute (const char* AttrName) const
|
||||
if (pos != AttrMap.end())
|
||||
return pos->second.c_str();
|
||||
else
|
||||
// wrong name, use hasAttribute if not shure!
|
||||
// wrong name, use hasAttribute if not sure!
|
||||
assert(0);
|
||||
|
||||
return "";
|
||||
@@ -255,6 +257,22 @@ void Base::XMLReader::readCharacters(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Base::XMLReader::readBinFile(const char* filename)
|
||||
{
|
||||
Base::FileInfo fi(filename);
|
||||
Base::ofstream to(fi, std::ios::out | std::ios::binary);
|
||||
if (!to)
|
||||
throw Base::Exception("XMLReader::readBinFile() Could not open file!");
|
||||
|
||||
bool ok;
|
||||
do {
|
||||
ok = read(); if (!ok) break;
|
||||
} while (ReadType != EndCDATA);
|
||||
|
||||
to << Base::base64_decode(Characters);
|
||||
to.close();
|
||||
}
|
||||
|
||||
void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
|
||||
{
|
||||
// It's possible that not all objects inside the document could be created, e.g. if a module
|
||||
@@ -370,15 +388,32 @@ void Base::XMLReader::endElement (const XMLCh* const /*uri*/, const XMLCh *cons
|
||||
ReadType = EndElement;
|
||||
}
|
||||
|
||||
void Base::XMLReader::startCDATA ()
|
||||
{
|
||||
ReadType = StartCDATA;
|
||||
}
|
||||
|
||||
void Base::XMLReader::endCDATA ()
|
||||
{
|
||||
ReadType = EndCDATA;
|
||||
}
|
||||
|
||||
#if (XERCES_VERSION_MAJOR == 2)
|
||||
void Base::XMLReader::characters(const XMLCh* const chars, const unsigned int length)
|
||||
#else
|
||||
void Base::XMLReader::characters(const XMLCh* const chars, const XMLSize_t length)
|
||||
#endif
|
||||
{
|
||||
Characters = StrX(chars).c_str();
|
||||
ReadType = Chars;
|
||||
CharacterCount += length;
|
||||
}
|
||||
|
||||
#if (XERCES_VERSION_MAJOR == 2)
|
||||
void Base::XMLReader::ignorableWhitespace( const XMLCh* const /*chars*/, const unsigned int /*length*/)
|
||||
#else
|
||||
void Base::XMLReader::ignorableWhitespace( const XMLCh* const /*chars*/, const XMLSize_t /*length*/)
|
||||
#endif
|
||||
{
|
||||
//fSpaceCount += length;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,8 @@ public:
|
||||
void readEndElement(const char* ElementName=0);
|
||||
/// read until characters are found
|
||||
void readCharacters(void);
|
||||
/// read binary file
|
||||
void readBinFile(const char*);
|
||||
//@}
|
||||
|
||||
/** @name Attribute handling */
|
||||
@@ -171,8 +173,15 @@ protected:
|
||||
// -----------------------------------------------------------------------
|
||||
virtual void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs);
|
||||
virtual void endElement (const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname);
|
||||
virtual void characters (const XMLCh* const chars, const unsigned int length);
|
||||
virtual void startCDATA ();
|
||||
virtual void endCDATA ();
|
||||
#if (XERCES_VERSION_MAJOR == 2)
|
||||
virtual void characters (const XMLCh* const chars, const unsigned int length);
|
||||
virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
|
||||
#else
|
||||
virtual void characters (const XMLCh* const chars, const XMLSize_t length);
|
||||
virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length);
|
||||
#endif
|
||||
virtual void resetDocument();
|
||||
|
||||
|
||||
@@ -198,7 +207,9 @@ protected:
|
||||
Chars,
|
||||
StartElement,
|
||||
StartEndElement,
|
||||
EndElement
|
||||
EndElement,
|
||||
StartCDATA,
|
||||
EndCDATA
|
||||
} ReadType;
|
||||
|
||||
|
||||
|
||||
@@ -65,32 +65,26 @@ void Writer::insertAsciiFile(const char* FileName)
|
||||
if (!from)
|
||||
throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
|
||||
|
||||
Stream() << "<![CDATA[" << endl;
|
||||
Stream() << "<![CDATA[";
|
||||
char ch;
|
||||
while (from.get(ch))
|
||||
Stream().put(ch);
|
||||
Stream() << endl << "]]>" << endl;
|
||||
Stream() << "]]>" << endl;
|
||||
}
|
||||
|
||||
void Writer::insertBinFile(const char* FileName)
|
||||
{
|
||||
Base::FileInfo fi(FileName);
|
||||
Base::ifstream from(fi, std::ios::in | std::ios::binary);
|
||||
Base::ifstream from(fi, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!from)
|
||||
throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
|
||||
|
||||
Stream() << "<![CDATA[" << endl;
|
||||
|
||||
unsigned char buf[60];
|
||||
std::string encoded;
|
||||
unsigned int i;
|
||||
|
||||
while (from) {
|
||||
for (i=0 ; i<60 && from;i++)
|
||||
buf[i] = from.get();
|
||||
Stream() << Base::base64_encode(buf,i) << endl;
|
||||
}
|
||||
|
||||
Stream() << "<![CDATA[";
|
||||
std::ifstream::pos_type fileSize = from.tellg();
|
||||
from.seekg(0, std::ios::beg);
|
||||
std::vector<unsigned char> bytes(fileSize);
|
||||
from.read((char*)&bytes[0], fileSize);
|
||||
Stream() << Base::base64_encode(&bytes[0], fileSize);
|
||||
Stream() << "]]>" << endl;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user