Reputation: 99
To compress/decompress data with zlib , first I need to set up a struct called z_stream
.
z_stream
has two non-const pointers called next_in
and next_out
.
If I want to do a function like this:
void ungzip(std::vector<unsigned char>& dst,const std::vector<unsigned char>& src)
{
z_stream strm;
// more code
}
and other like,
void gzip (std::vector<unsigned char>& dst,const std::vector<unsigned char>& src);
What I should do?
Copy src in a local std::vector<unsigned char>
std::vector<unsigned char> tmp(src);
and use it as source or setting pointer like this , strm.next_in = const_cast<char*>(&src[0])
?
Does zlib keep input data?
Upvotes: 4
Views: 1158
Reputation: 114481
Probably the cleanest way would be to just define ZLIB_CONST
when compiling so that the input pointer is defined to be a const unsigned char *
instead.
Note however that simply casting away const-ness is indeed going to work (it's legal if the character being pointed to is not actually constant). The code for this should be:
strm.next_in = (unsigned char *)&src[0];
or the uglier const_cast
variant if you are into that kind of things.
Note that default in zlib
is NOT to have ZLIB_CONST
defined and if you want to use a precompiled zlib
binary the casting solution is the best option. You should go for the ZLIB_CONST
solution only if you're compiling yourself the library too with the same define(1).
(1) Giving the compiler an header with different semantic meaning is a bad idea - and a formal breaking of C++ standard rules - and it could - at least in theory - create protability problems.
With X86 architecture this is probably not the case and the library compiled with or without ZLIB_CONST
would end up with the exact same bytes; however there are also different architectures.
For example I've been working with CPUs in which there were different pointer registers for different alignments. In that CPUs reading say an integer from an address that wasn't a multiple or 4 was an error generating an hardware trap (moreover something that at the time surprised me is that the error was triggered even by just assigning the pointer a non-aligned address, even if that misaligned address was never used for reading or writing).
With that compiler I didn't check (I was working only on high-level software) but I wouldn't be surprised if the system ABI specifed that a function void foo(char *)
and void bar(int *)
would have to receive the parameter in different registers.
More to the point, I never worked with but I can imagine may exist CPUs or VMs for which certain registers (let's name one as RW0
) can be used for reading/writing operations and other registers (e.g. R0
) can be used only for reading.
With such an architecture the ABI may specify that the first parameter of type const char *
must be passed in R0
and the first parameter of type char *
must be passed in RW0
instead.
If this is the case compiling a library with a function void foo(char *p){...}
and then compiling the calling code using as declaration void foo(const char *p);
would actually end up passing the address in the wrong register!
Upvotes: 3