Persistence: Implement dumping of binary content
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user