diff --git a/src/Base/PersistencePy.xml b/src/Base/PersistencePy.xml
index 0408f0d15f..cf10cd72a3 100644
--- a/src/Base/PersistencePy.xml
+++ b/src/Base/PersistencePy.xml
@@ -14,7 +14,7 @@
This is the Persistence class
This is a persistence class
-
+
Content of the object in XML representation
@@ -26,5 +26,22 @@
+
+
+ Dumps the content of the object, both the XML representation as well as the additional datafiles
+ required, into a byte representation. It will be returned as byte array.
+ dumpContent() -- returns a byte array with full content
+ dumpContent(Compression=1-9) -- Sets the data compression from 0 (no) to 9 (max)
+
+
+
+
+
+ Restore the content of the object from a byte representation as stored by \"dumpContent\".
+ It could be restored from any python object implementing the buffer protocol.
+ restoreContent(buffer) -- restores from the given byte array
+
+
+
-
+
diff --git a/src/Base/PersistencePyImp.cpp b/src/Base/PersistencePyImp.cpp
index ac2d4c79b0..890773996b 100644
--- a/src/Base/PersistencePyImp.cpp
+++ b/src/Base/PersistencePyImp.cpp
@@ -23,6 +23,7 @@
#include "PreCompiled.h"
#include "Writer.h"
+#include "Reader.h"
#include "Persistence.h"
// inclution of the generated files (generated By PersitancePy.xml)
@@ -48,16 +49,117 @@ Py::String PersistencePy::getContent(void) const
return Py::String (writer.getString());
}
-void PersistencePy::setContent(Py::String /*arg*/)
-{
- throw Py::AttributeError(std::string("Attribute 'Content' of object 'Persistence' is read-only"));
-}
-
Py::Int PersistencePy::getMemSize(void) const
{
return Py::Int((long)getPersistencePtr()->getMemSize());
}
+PyObject* PersistencePy::dumpContent(PyObject *args, PyObject *kwds) {
+
+ int compression = 3;
+ static char* kwds_def[] = {"Compression",NULL};
+ PyErr_Clear();
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwds_def, &compression)) {
+ return NULL;
+ }
+
+ //setup the streams
+ std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
+
+ //we need to close the zipstream to get a good result, the only way to do this is to delete the ZipWriter.
+ //Hence the scope...
+ {
+ //create the writer
+ Base::ZipWriter writer(stream);
+ writer.setLevel(compression);
+ writer.putNextEntry("Document.xml");
+ writer.setMode("BinaryBrep");
+
+ //save the content
+ getPersistencePtr()->Save(writer);
+ writer.writeFiles();
+ }
+
+ //build the byte array with correct size
+ if(!stream.seekp(0, stream.end)) {
+ PyErr_SetString(PyExc_IOError, "Unable to find end of stream");
+ return NULL;
+ }
+ std::stringstream::pos_type offset = stream.tellp();
+ if(!stream.seekg(0, stream.beg)) {
+ PyErr_SetString(PyExc_IOError, "Unable to find begin of stream");
+ return NULL;
+ }
+
+ PyObject* ba = PyByteArray_FromStringAndSize(NULL, offset);
+
+ //use the buffer protocol to access the underlying array and write into it
+ Py_buffer buf = Py_buffer();
+ PyObject_GetBuffer(ba, &buf, PyBUF_WRITABLE);
+ try {
+ if(!stream.read((char*)buf.buf, offset)) {
+ PyErr_SetString(PyExc_IOError, "Error copying data into byte array");
+ return NULL;
+ }
+ PyBuffer_Release(&buf);
+ }
+ catch(...) {
+ PyBuffer_Release(&buf);
+ PyErr_SetString(PyExc_IOError, "Error copying data into byte array");
+ return NULL;
+ }
+
+ return ba;
+}
+
+PyObject* PersistencePy::restoreContent(PyObject *args) {
+
+ PyObject* buffer;
+ if( !PyArg_ParseTuple(args, "O", &buffer) )
+ return NULL;
+
+ //check if it really is a buffer
+ if( !PyObject_CheckBuffer(buffer) ) {
+ PyErr_SetString(PyExc_TypeError, "Must be a buffer object");
+ return NULL;
+ }
+
+ Py_buffer buf;
+ if(PyObject_GetBuffer(buffer, &buf, PyBUF_SIMPLE) < 0)
+ return NULL;
+
+ if(!PyBuffer_IsContiguous(&buf, 'C')) {
+ PyErr_SetString(PyExc_TypeError, "Buffer must be contiguous");
+ return NULL;
+ }
+
+ try {
+
+ //TODO: this mkes a stupid copy, we should make a stream directly from the buffer
+ std::stringstream stream(std::string((char*)buf.buf, buf.len), std::stringstream::in | std::stringstream::binary);
+
+ zipios::ZipInputStream zipstream(stream);
+ Base::XMLReader reader("", zipstream);
+
+ if (!reader.isValid()) {
+ PyErr_SetString(PyExc_IOError, "Unable to read file");
+ return NULL;
+ }
+
+ getPersistencePtr()->Restore(reader);
+ reader.readFiles(zipstream);
+ }
+ catch (const Base::Exception& e) {
+ PyErr_SetString(PyExc_IOError, e.what());
+ return NULL;
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_IOError, e.what());
+ return NULL;
+ }
+
+ return Py_None;
+}
PyObject *PersistencePy::getCustomAttributes(const char*) const
{