Deserialization of compressed QByteAray fails
Using QxSerialize_QByteArray for serializing and deserializing QByteArray fails, if the QByteArray contains data generated via qCompress(data). Deserialization produces input stream error.
To solve this issue, the QByteArray should be BASE64 encoded via QByteArray::toBase64. I think, it would be safer, if this is already in the load / save function.
Hello,
Could you please provide an example to reproduce the issue ? Because there are already some examples in the ./test/ directory using qx::serialization::qt::to_file_compressed / qx::serialization::qt::from_file_compressed, and there is no issue.
I don't know what exactly you want to convert to BASE64, but I'm not sure this is a good solution in term of performance, and data size.
Hi,
I wanted to serialize an SVG image file into an boost XML archive. If I use your current QByteArray code, then I get an input stream error deserializing the SVG image later.
This is the SVG image:
I did the following:
QFile SvgFile(FileName);
SvgFile.open(QIODevice::ReadOnly);
QByteArray SvgIconData = SvgFile.readAll();
auto CompressedSvgData =qCompress(SvgIconData, 9);
ar << make_nvp("SvgIconData", CompressedSvgData); // this calls your QByteArray serialization code
This is the deserialization code:
QByteArray CompressedSvg;
ar >> make_nvp("SvgIconData", CompressedSvg);
QByteArray SvgIconData = qUncompress(CompressedSvg);
It fails with input stream error.
If I change the QByteArray serialization code this way, then it works:
template<class Archive>
void save(Archive & ar, const QByteArray& t, unsigned int version)
{
Q_UNUSED(version);
std::string SerializableString = t.toBase64().toStdString();
ar << make_nvp(NULL, SerializableString);
}
//============================================================================
template<class Archive>
void load(Archive & ar, QByteArray& t, unsigned int version)
{
Q_UNUSED(version);
std::string SerializableString;
ar >> make_nvp(NULL, SerializableString);
t = QByteArray::fromStdString(SerializableString);
t = QByteArray::fromBase64(t);
}
This is strange, a QByteArray should be serialized correctly. If you serialize it without using qCompress / qUncompress : is your image OK after deserialization ?
Yes
Hello,
FYI, I'm not able to reproduce your issue : for me this is working fine. You don't say what is the type of the variable ar in your examples :
ar << make_nvp("SvgIconData", CompressedSvgData); // this calls your QByteArray serialization code
ar >> make_nvp("SvgIconData", CompressedSvg);
Here is my test to try to reproduce :
- I copy your SVG file to the qxBlog example project (in the ./test/ directory of QxOrm package)
- Then in the main function of this project, I added these lines :
QFile SvgFile("./test.svg");
SvgFile.open(QIODevice::ReadOnly);
QByteArray SvgIconData = SvgFile.readAll();
auto CompressedSvgData = qCompress(SvgIconData, 9);
auto CloneCompressedSvgData = qx::clone(CompressedSvgData);
QByteArray SvgIconData2 = qUncompress(* CloneCompressedSvgData);
qAssert(SvgIconData == SvgIconData2);
I used qx::clone() to test : the implementation of qx::clone() calls ar << make_nvp and ar >> make_nvp, so I think this is equivalent to your code. And the qAssert at the end checks that the SVG content is the same.
Maybe the ar type you use doesn't support binary data ?