diff --git a/src/App/PropertyFile.cpp b/src/App/PropertyFile.cpp
index 13599c88a6..52278ea991 100644
--- a/src/App/PropertyFile.cpp
+++ b/src/App/PropertyFile.cpp
@@ -257,13 +257,18 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
void PropertyFileIncluded::Save (Base::Writer &writer) const
{
if (writer.isForceXML()) {
- writer.Stream() << writer.ind() << "" << endl;
-
- // write the file in the XML stream
- if (!_cValue.empty())
+ if (!_cValue.empty()) {
+ Base::FileInfo file(_cValue.c_str());
+ writer.Stream() << writer.ind() << "" << std::endl;
+ // write the file in the XML stream
+ writer.incInd();
writer.insertBinFile(_cValue.c_str());
-
- writer.Stream() << writer.ind() <<"" << endl ;
+ writer.decInd();
+ writer.Stream() << writer.ind() <<"" << endl;
+ }
+ else
+ writer.Stream() << writer.ind() << "" << 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();
+ }
}
}
diff --git a/src/Base/Reader.cpp b/src/Base/Reader.cpp
index db355f723f..6791b99f62 100644
--- a/src/Base/Reader.cpp
+++ b/src/Base/Reader.cpp
@@ -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;
}
diff --git a/src/Base/Reader.h b/src/Base/Reader.h
index 3ced7241b5..7e55575d42 100644
--- a/src/Base/Reader.h
+++ b/src/Base/Reader.h
@@ -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;
diff --git a/src/Base/Writer.cpp b/src/Base/Writer.cpp
index 01eecef6b5..621893a8a3 100644
--- a/src/Base/Writer.cpp
+++ b/src/Base/Writer.cpp
@@ -65,32 +65,26 @@ void Writer::insertAsciiFile(const char* FileName)
if (!from)
throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
- Stream() << "" << 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() << " bytes(fileSize);
+ from.read((char*)&bytes[0], fileSize);
+ Stream() << Base::base64_encode(&bytes[0], fileSize);
Stream() << "]]>" << endl;
}