Reputation: 31
I've been trying to deflate and inflate a string, and this works:
char text[600] = "Testing deflating and inflating";
char out[600];
uLong ucompSize = strlen(text) + 1;
uLong compSize = compressBound(ucompSize);
// Deflate
compress((Bytef *)out, &compSize, (Bytef *)text, ucompSize);
But my problem is that the needed space for the out (and the string itself) can vary a lot, I tried using std::string 's but it doesn't work, I get the following error:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
_CrtIsValidHeapPointer(pUserData)
My current code with std::string is this one
char text[600] = "Testing deflating and inflating";
std::string out;
uLong ucompSize = strlen(text) + 1;
uLong compSize = compressBound(ucompSize);
// Deflate
compress((Bytef *)out.data(), &compSize, (Bytef *)text, ucompSize);
I've been searching in Google but I can't find a solution, I just need to inflate and deflate big strings. I'm not good in C++ (I always work with Ruby, where I can do this just with Zlib::Deflate.deflate(@string))
Can anyone help/teach me? Thanks you
Upvotes: 3
Views: 3169
Reputation: 6776
According to zlib manual the function compress
:
Compresses the source buffer into the destination buffer.
sourceLen
is the byte length of the source buffer. Upon entry,destLen
is the total size of the destination buffer, which must be at least the value returned bycompressBound(sourceLen)
. Upon exit, destLen is the actual size of the compressed buffer.
C++ std::string cannot be used for such buffer. The member function std::string::data()
returns read-only string buffer that should not be changed by external functions.
In C++11 it is possible to use std::vector::data()
for such buffer after allocating enough size for vector of bytes: std::vector<char> out(compressBound(sourceLen));
Here for C style functions it also might be simpler to allocate that buffer using malloc
. However, in that case the buffer should be manually freed (in case of C++ vector the buffer memory is deallocated when the vector instance is destroyed).
So, the C++11 code may look like:
{
char text[600] = "Testing deflating and inflating";
uLong ucompSize = strlen(text) + 1;
uLong compSize = compressBound(ucompSize);
std::vector<char> dest(compSize); // allocate enough size for output buffer
// Deflate
int error = compress((Bytef *)dest.data(), &compSize, (Bytef *)text, ucompSize);
// here if error code is Z_OK the variable compSize contains size of
// compressed data that is usually smaller than initial buffer size.
// vector size may be adjusted to actual size of compressed data
dest.resize(compSize);
// do something with compressed data
// ...
}
// here the vector 'dest' is out of block scope;
// it is automatically destroed and the buffer is not valid anymore.
Upvotes: 4