Persistence: Incorporate review feedback
This commit is contained in:
@@ -60,17 +60,17 @@ If the list contains 'Hidden' then the item even doesn't appear in the property
|
||||
<Methode Name="dumpPropertyContent" Keyword="true" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Dumps the content of the property, both the XML representation as well as the additional datafiles
|
||||
required, into a byte representation. It will be returned as byte array.
|
||||
dumpPropertyContent(propertyname) -- returns a byte array with full content
|
||||
dumpPropertyContent(propertyname, [Compression=1-9]) -- Sets the data compression from 0 (no) to 9 (max)
|
||||
required, into a byte representation. It will be returned as byte array.
|
||||
dumpPropertyContent(propertyname) -- returns a byte array with full content
|
||||
dumpPropertyContent(propertyname, [Compression=1-9]) -- Sets the data compression from 0 (no) to 9 (max)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="restorePropertyContent">
|
||||
<Documentation>
|
||||
<UserDocu>Restore the content of given property from a byte representation as stored by \"dumpContent\".
|
||||
It could be restored from any python object implementing the buffer protocol.
|
||||
restorePropertyContent(propertyname, buffer) -- restores from the given byte array
|
||||
It could be restored from any python object implementing the buffer protocol.
|
||||
restorePropertyContent(propertyname, buffer) -- restores from the given byte array
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#include "Property.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
// inclution of the generated files (generated out of PropertyContainerPy.xml)
|
||||
#include "PropertyContainerPy.h"
|
||||
#include "PropertyContainerPy.cpp"
|
||||
@@ -241,9 +244,48 @@ PyObject* PropertyContainerPy::dumpPropertyContent(PyObject *args, PyObject *kwd
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", property);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
|
||||
try {
|
||||
prop->dumpToStream(stream, compression);
|
||||
}
|
||||
catch(...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable parse content into binary representation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
return prop->dumpToPython(compression);
|
||||
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* PropertyContainerPy::restorePropertyContent(PyObject *args) {
|
||||
@@ -259,7 +301,33 @@ PyObject* PropertyContainerPy::restorePropertyContent(PyObject *args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prop->restoreFromPython(buffer);
|
||||
//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;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
try {
|
||||
typedef boost::iostreams::basic_array_source<char> Device;
|
||||
boost::iostreams::stream<Device> stream((char*)buf.buf, buf.len);
|
||||
prop->restoreFromStream(stream);
|
||||
}
|
||||
catch(...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to restore content");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
#include "Reader.h"
|
||||
#include "PyObjectBase.h"
|
||||
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
@@ -102,10 +99,7 @@ std::string Persistence::encodeAttribute(const std::string& str)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
PyObject* Persistence::dumpToPython(int compression) {
|
||||
|
||||
//setup the stream. the in flag is needed to make "read" work^
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
|
||||
void Persistence::dumpToStream(std::ostream& stream, int compression) {
|
||||
|
||||
//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...
|
||||
@@ -113,7 +107,7 @@ PyObject* Persistence::dumpToPython(int compression) {
|
||||
//create the writer
|
||||
Base::ZipWriter writer(stream);
|
||||
writer.setLevel(compression);
|
||||
writer.putNextEntry("Document.xml");
|
||||
writer.putNextEntry("Persistence.xml");
|
||||
writer.setMode("BinaryBrep");
|
||||
|
||||
//save the content (we need to encapsulte it with xml tags to be able to read single element xmls like happen for properties)
|
||||
@@ -122,81 +116,17 @@ PyObject* Persistence::dumpToPython(int compression) {
|
||||
writer.Stream() << "</Content>";
|
||||
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* Persistence::restoreFromPython(PyObject *buffer) {
|
||||
void Persistence::restoreFromStream(std::istream& stream) {
|
||||
|
||||
zipios::ZipInputStream zipstream(stream);
|
||||
Base::XMLReader reader("", zipstream);
|
||||
|
||||
//check if it really is a buffer
|
||||
if( !PyObject_CheckBuffer(buffer) ) {
|
||||
PyErr_SetString(PyExc_TypeError, "Must be a buffer object");
|
||||
return NULL;
|
||||
}
|
||||
if (!reader.isValid())
|
||||
throw Base::ValueError("Unable to construct reader");
|
||||
|
||||
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 {
|
||||
|
||||
typedef boost::iostreams::basic_array_source<char> Device;
|
||||
boost::iostreams::stream<Device> stream((char*)buf.buf, buf.len);
|
||||
|
||||
zipios::ZipInputStream zipstream(stream);
|
||||
Base::XMLReader reader("", zipstream);
|
||||
|
||||
if (!reader.isValid()) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to read file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reader.readElement("Content");
|
||||
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;
|
||||
reader.readElement("Content");
|
||||
Restore(reader);
|
||||
reader.readFiles(zipstream);
|
||||
}
|
||||
|
||||
@@ -149,11 +149,11 @@ public:
|
||||
/// Encodes an attribute upon saving.
|
||||
static std::string encodeAttribute(const std::string&);
|
||||
|
||||
//dump the persistence data into a python byte array data structure
|
||||
PyObject* dumpToPython(int compression);
|
||||
//dump the binary persistence data into into the stream
|
||||
void dumpToStream(std::ostream& stream, int compression);
|
||||
|
||||
//restore the persistence data from a python data structure that supports the buffer protocol
|
||||
PyObject* restoreFromPython(PyObject*);
|
||||
//restore the binary persistence data from a stream. Must have the format used by dumpToStream
|
||||
void restoreFromStream(std::istream& stream);
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
|
||||
@@ -29,17 +29,17 @@
|
||||
<Methode Name="dumpContent" Keyword="true" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>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)
|
||||
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)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="restoreContent">
|
||||
<Documentation>
|
||||
<UserDocu>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
|
||||
It could be restored from any python object implementing the buffer protocol.
|
||||
restoreContent(buffer) -- restores from the given byte array
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "PreCompiled.h"
|
||||
#include "Writer.h"
|
||||
#include "Persistence.h"
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
// inclution of the generated files (generated By PersitancePy.xml)
|
||||
#include "PersistencePy.h"
|
||||
@@ -62,7 +64,46 @@ PyObject* PersistencePy::dumpContent(PyObject *args, PyObject *kwds) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getPersistencePtr()->dumpToPython(compression);
|
||||
//setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
|
||||
try {
|
||||
getPersistencePtr()->dumpToStream(stream, compression);
|
||||
}
|
||||
catch(...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable parse content into binary representation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//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) {
|
||||
@@ -70,9 +111,34 @@ 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;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
return getPersistencePtr()->restoreFromPython(buffer);
|
||||
try {
|
||||
typedef boost::iostreams::basic_array_source<char> Device;
|
||||
boost::iostreams::stream<Device> stream((char*)buf.buf, buf.len);
|
||||
getPersistencePtr()->restoreFromStream(stream);
|
||||
}
|
||||
catch(...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to restore content");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *PersistencePy::getCustomAttributes(const char*) const
|
||||
|
||||
Reference in New Issue
Block a user