mirror of https://github.com/madler/zlib.git
parent
13a294f044
commit
8e34b3a802
58 changed files with 7305 additions and 5376 deletions
@ -1,9 +0,0 @@ |
|||||||
To make a shared library: |
|
||||||
|
|
||||||
1. Compile a static library |
|
||||||
2. Use mkexps on that to create libz.exp |
|
||||||
3. Apply the configure.diff patch to configure |
|
||||||
4. Run the new configure to make a new Makefile |
|
||||||
5. Use the new Makefile to make the shared library |
|
||||||
|
|
||||||
Courtesy of dbakker@arrayasolutions.com |
|
@ -1,57 +0,0 @@ |
|||||||
*** ../orig/zlib-1.1.4/configure Wed Jul 8 14:19:35 1998
|
|
||||||
--- configure Sun Feb 9 11:11:19 2003
|
|
||||||
***************
|
|
||||||
*** 18,23 ****
|
|
||||||
--- 18,24 ----
|
|
||||||
# If you have problems, try without defining CC and CFLAGS before reporting
|
|
||||||
# an error.
|
|
||||||
|
|
||||||
+ LDFLAGS="-L. -lz"
|
|
||||||
LIBS=libz.a
|
|
||||||
SHAREDLIB=libz.so
|
|
||||||
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
|
|
||||||
***************
|
|
||||||
*** 116,121 ****
|
|
||||||
--- 117,128 ----
|
|
||||||
SFLAGS=${CFLAGS-"-Kconform_pic -O"}
|
|
||||||
CFLAGS=${CFLAGS-"-O"}
|
|
||||||
LDSHARED=${LDSHARED-"cc -G"};;
|
|
||||||
+ AIX*)
|
|
||||||
+ SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
|
|
||||||
+ CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
|
|
||||||
+ LDTESTSHARED=${LDSHARED-"cc -G"}
|
|
||||||
+ LDSHAREDFLAGS="-L. libz.so"
|
|
||||||
+ LDSHARED=${LDSHARED-"cc -G"};;
|
|
||||||
# send working options for other systems to support@gzip.org
|
|
||||||
*) SFLAGS=${CFLAGS-"-O"}
|
|
||||||
CFLAGS=${CFLAGS-"-O"}
|
|
||||||
***************
|
|
||||||
*** 127,135 ****
|
|
||||||
echo Checking for shared library support...
|
|
||||||
# we must test in two steps (cc then ld), required at least on SunOS 4.x
|
|
||||||
if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
|
|
||||||
! test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
|
|
||||||
CFLAGS="$SFLAGS"
|
|
||||||
LIBS="$SHAREDLIB.$VER"
|
|
||||||
echo Building shared library $SHAREDLIB.$VER with $CC.
|
|
||||||
elif test -z "$old_cc" -a -z "$old_cflags"; then
|
|
||||||
echo No shared library suppport.
|
|
||||||
--- 134,143 ----
|
|
||||||
echo Checking for shared library support...
|
|
||||||
# we must test in two steps (cc then ld), required at least on SunOS 4.x
|
|
||||||
if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
|
|
||||||
! test "`($LDTESTSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
|
|
||||||
CFLAGS="$SFLAGS"
|
|
||||||
LIBS="$SHAREDLIB.$VER"
|
|
||||||
+ LDFLAGS="$LDSHAREDFLAGS"
|
|
||||||
echo Building shared library $SHAREDLIB.$VER with $CC.
|
|
||||||
elif test -z "$old_cc" -a -z "$old_cflags"; then
|
|
||||||
echo No shared library suppport.
|
|
||||||
***************
|
|
||||||
*** 209,212 ****
|
|
||||||
--- 217,221 ----
|
|
||||||
/^exec_prefix *=/s%=.*%=$exec_prefix%
|
|
||||||
/^libdir *=/s%=.*%=$libdir%
|
|
||||||
/^includedir *=/s%=.*%=$includedir%
|
|
||||||
+ /^LDFLAGS *=/s%=.*%=$LDFLAGS%
|
|
||||||
" > Makefile
|
|
@ -1,37 +0,0 @@ |
|||||||
#!/bin/ksh |
|
||||||
# |
|
||||||
# mkexps - make export list |
|
||||||
# This program creates an export list by combining all the "." and normal names |
|
||||||
# into one list. |
|
||||||
# |
|
||||||
if [[ "$#" -ne 1 ]] |
|
||||||
then |
|
||||||
print "Usage: mkexps ArchiveFile" |
|
||||||
exit -2 |
|
||||||
fi |
|
||||||
if [[ ! -f $1 ]] |
|
||||||
then |
|
||||||
print "mkexps: Cannot open file \"$1\"" |
|
||||||
exit -1 |
|
||||||
fi |
|
||||||
|
|
||||||
dump -g $1 | awk ' |
|
||||||
BEGIN { |
|
||||||
top = 1 |
|
||||||
} |
|
||||||
/^[ ]*[0-9][0-9]*/ { |
|
||||||
if ( (n = index( $2, "." )) > 0 ) { |
|
||||||
export_array[ top++ ] = substr( $2, n+1, length( $2 )) |
|
||||||
} |
|
||||||
else { |
|
||||||
export_array[ top++ ] = $2 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
END { |
|
||||||
for ( i = 1; i < top; i++ ) |
|
||||||
{ |
|
||||||
print export_array[ i ] |
|
||||||
} |
|
||||||
|
|
||||||
}' | sort | uniq |
|
@ -0,0 +1,35 @@ |
|||||||
|
These classes provide a C++ stream interface to the zlib library. It allows you |
||||||
|
to do things like: |
||||||
|
|
||||||
|
gzofstream outf("blah.gz"); |
||||||
|
outf << "These go into the gzip file " << 123 << endl; |
||||||
|
|
||||||
|
It does this by deriving a specialized stream buffer for gzipped files, which is |
||||||
|
the way Stroustrup would have done it. :-> |
||||||
|
|
||||||
|
The gzifstream and gzofstream classes were originally written by Kevin Ruland |
||||||
|
and made available in the zlib contrib/iostream directory. The older version still |
||||||
|
compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of |
||||||
|
this version. |
||||||
|
|
||||||
|
The new classes are as standard-compliant as possible, closely following the |
||||||
|
approach of the standard library's fstream classes. It compiles under gcc versions |
||||||
|
3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard |
||||||
|
library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs |
||||||
|
from the previous one in the following respects: |
||||||
|
- added showmanyc |
||||||
|
- added setbuf, with support for unbuffered output via setbuf(0,0) |
||||||
|
- a few bug fixes of stream behavior |
||||||
|
- gzipped output file opened with default compression level instead of maximum level |
||||||
|
- setcompressionlevel()/strategy() members replaced by single setcompression() |
||||||
|
|
||||||
|
The code is provided "as is", with the permission to use, copy, modify, distribute |
||||||
|
and sell it for any purpose without fee. |
||||||
|
|
||||||
|
Ludwig Schwardt |
||||||
|
<schwardt@sun.ac.za> |
||||||
|
|
||||||
|
DSP Lab |
||||||
|
Electrical & Electronic Engineering Department |
||||||
|
University of Stellenbosch |
||||||
|
South Africa |
@ -0,0 +1,17 @@ |
|||||||
|
Possible upgrades to gzfilebuf: |
||||||
|
|
||||||
|
- The ability to do putback (e.g. putbackfail) |
||||||
|
|
||||||
|
- The ability to seek (zlib supports this, but could be slow/tricky) |
||||||
|
|
||||||
|
- Simultaneous read/write access (does it make sense?) |
||||||
|
|
||||||
|
- Support for ios_base::ate open mode |
||||||
|
|
||||||
|
- Locale support? |
||||||
|
|
||||||
|
- Check public interface to see which calls give problems |
||||||
|
(due to dependence on library internals) |
||||||
|
|
||||||
|
- Override operator<<(ostream&, gzfilebuf*) to allow direct copying |
||||||
|
of stream buffer to stream ( i.e. os << is.rdbuf(); ) |
@ -0,0 +1,50 @@ |
|||||||
|
/*
|
||||||
|
* Test program for gzifstream and gzofstream |
||||||
|
*
|
||||||
|
* by Ludwig Schwardt <schwardt@sun.ac.za> |
||||||
|
* original version by Kevin Ruland <kevin@rodin.wustl.edu> |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "zfstream.h" |
||||||
|
#include <iostream> // for cout |
||||||
|
|
||||||
|
int main() { |
||||||
|
|
||||||
|
gzofstream outf; |
||||||
|
gzifstream inf; |
||||||
|
char buf[80]; |
||||||
|
|
||||||
|
outf.open("test1.txt.gz"); |
||||||
|
outf << "The quick brown fox sidestepped the lazy canine\n"
|
||||||
|
<< 1.3 << "\nPlan " << 9 << std::endl; |
||||||
|
outf.close(); |
||||||
|
std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n" |
||||||
|
<< "The quick brown fox sidestepped the lazy canine\n" |
||||||
|
<< 1.3 << "\nPlan " << 9 << std::endl; |
||||||
|
|
||||||
|
std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n"; |
||||||
|
inf.open("test1.txt.gz"); |
||||||
|
while (inf.getline(buf,80,'\n')) { |
||||||
|
std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; |
||||||
|
} |
||||||
|
inf.close(); |
||||||
|
|
||||||
|
outf.rdbuf()->pubsetbuf(0,0); |
||||||
|
outf.open("test2.txt.gz"); |
||||||
|
outf << setcompression(Z_NO_COMPRESSION) |
||||||
|
<< "The quick brown fox sidestepped the lazy canine\n" |
||||||
|
<< 1.3 << "\nPlan " << 9 << std::endl; |
||||||
|
outf.close(); |
||||||
|
std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form"; |
||||||
|
|
||||||
|
std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n"; |
||||||
|
inf.rdbuf()->pubsetbuf(0,0); |
||||||
|
inf.open("test2.txt.gz"); |
||||||
|
while (inf.getline(buf,80,'\n')) { |
||||||
|
std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; |
||||||
|
} |
||||||
|
inf.close(); |
||||||
|
|
||||||
|
return 0; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,479 @@ |
|||||||
|
/*
|
||||||
|
* A C++ I/O streams interface to the zlib gz* functions |
||||||
|
*
|
||||||
|
* by Ludwig Schwardt <schwardt@sun.ac.za> |
||||||
|
* original version by Kevin Ruland <kevin@rodin.wustl.edu> |
||||||
|
*
|
||||||
|
* This version is standard-compliant and compatible with gcc 3.x. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "zfstream.h" |
||||||
|
#include <cstring> // for strcpy, strcat, strlen (mode strings) |
||||||
|
#include <cstdio> // for BUFSIZ |
||||||
|
|
||||||
|
// Internal buffer sizes (default and "unbuffered" versions)
|
||||||
|
#define BIGBUFSIZE BUFSIZ |
||||||
|
#define SMALLBUFSIZE 1 |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
gzfilebuf::gzfilebuf()
|
||||||
|
: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
|
||||||
|
buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true) |
||||||
|
{ |
||||||
|
// No buffers to start with
|
||||||
|
this->disable_buffer(); |
||||||
|
} |
||||||
|
|
||||||
|
// Destructor
|
||||||
|
gzfilebuf::~gzfilebuf()
|
||||||
|
{ |
||||||
|
// Sync output buffer and close only if responsible for file
|
||||||
|
// (i.e. attached streams should be left open at this stage)
|
||||||
|
this->sync(); |
||||||
|
if (own_fd)
|
||||||
|
this->close(); |
||||||
|
// Make sure internal buffer is deallocated
|
||||||
|
this->disable_buffer(); |
||||||
|
} |
||||||
|
|
||||||
|
// Set compression level and strategy
|
||||||
|
int |
||||||
|
gzfilebuf::setcompression(int comp_level, |
||||||
|
int comp_strategy) |
||||||
|
{ |
||||||
|
return gzsetparams(file, comp_level, comp_strategy); |
||||||
|
} |
||||||
|
|
||||||
|
// Open gzipped file
|
||||||
|
gzfilebuf*
|
||||||
|
gzfilebuf::open(const char *name,
|
||||||
|
std::ios_base::openmode mode) |
||||||
|
{ |
||||||
|
// Fail if file already open
|
||||||
|
if (this->is_open())
|
||||||
|
return NULL; |
||||||
|
// Don't support simultaneous read/write access (yet)
|
||||||
|
if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
|
||||||
|
return NULL; |
||||||
|
|
||||||
|
// Build mode string for gzopen and check it [27.8.1.3.2]
|
||||||
|
char char_mode[6] = "\0\0\0\0\0"; |
||||||
|
if (!this->open_mode(mode, char_mode)) |
||||||
|
return NULL; |
||||||
|
|
||||||
|
// Attempt to open file
|
||||||
|
if ((file = gzopen(name, char_mode)) == NULL)
|
||||||
|
return NULL; |
||||||
|
|
||||||
|
// On success, allocate internal buffer and set flags
|
||||||
|
this->enable_buffer(); |
||||||
|
io_mode = mode; |
||||||
|
own_fd = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
// Attach to gzipped file
|
||||||
|
gzfilebuf* |
||||||
|
gzfilebuf::attach(int fd, |
||||||
|
std::ios_base::openmode mode)
|
||||||
|
{ |
||||||
|
// Fail if file already open
|
||||||
|
if (this->is_open())
|
||||||
|
return NULL; |
||||||
|
// Don't support simultaneous read/write access (yet)
|
||||||
|
if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
|
||||||
|
return NULL; |
||||||
|
|
||||||
|
// Build mode string for gzdopen and check it [27.8.1.3.2]
|
||||||
|
char char_mode[6] = "\0\0\0\0\0"; |
||||||
|
if (!this->open_mode(mode, char_mode)) |
||||||
|
return NULL; |
||||||
|
|
||||||
|
// Attempt to attach to file
|
||||||
|
if ((file = gzdopen(fd, char_mode)) == NULL) |
||||||
|
return NULL; |
||||||
|
|
||||||
|
// On success, allocate internal buffer and set flags
|
||||||
|
this->enable_buffer(); |
||||||
|
io_mode = mode; |
||||||
|
own_fd = false; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
// Close gzipped file
|
||||||
|
gzfilebuf* |
||||||
|
gzfilebuf::close()
|
||||||
|
{ |
||||||
|
// Fail immediately if no file is open
|
||||||
|
if (!this->is_open()) |
||||||
|
return NULL; |
||||||
|
// Assume success
|
||||||
|
gzfilebuf* retval = this; |
||||||
|
// Attempt to sync and close gzipped file
|
||||||
|
if (this->sync() == -1) |
||||||
|
retval = NULL; |
||||||
|
if (gzclose(file) < 0) |
||||||
|
retval = NULL; |
||||||
|
// File is now gone anyway (postcondition [27.8.1.3.8])
|
||||||
|
file = NULL; |
||||||
|
own_fd = false; |
||||||
|
// Destroy internal buffer if it exists
|
||||||
|
this->disable_buffer(); |
||||||
|
return retval; |
||||||
|
} |
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
||||||
|
|
||||||
|
// Convert int open mode to mode string
|
||||||
|
bool
|
||||||
|
gzfilebuf::open_mode(std::ios_base::openmode mode,
|
||||||
|
char* c_mode) const |
||||||
|
{ |
||||||
|
bool testb = mode & std::ios_base::binary; |
||||||
|
bool testi = mode & std::ios_base::in; |
||||||
|
bool testo = mode & std::ios_base::out; |
||||||
|
bool testt = mode & std::ios_base::trunc; |
||||||
|
bool testa = mode & std::ios_base::app; |
||||||
|
|
||||||
|
// Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
|
||||||
|
// Original zfstream hardcoded the compression level to maximum here...
|
||||||
|
// Double the time for less than 1% size improvement seems
|
||||||
|
// excessive though - keeping it at the default level
|
||||||
|
// To change back, just append "9" to the next three mode strings
|
||||||
|
if (!testi && testo && !testt && !testa) |
||||||
|
strcpy(c_mode, "w"); |
||||||
|
if (!testi && testo && !testt && testa) |
||||||
|
strcpy(c_mode, "a"); |
||||||
|
if (!testi && testo && testt && !testa) |
||||||
|
strcpy(c_mode, "w"); |
||||||
|
if (testi && !testo && !testt && !testa) |
||||||
|
strcpy(c_mode, "r"); |
||||||
|
// No read/write mode yet
|
||||||
|
// if (testi && testo && !testt && !testa)
|
||||||
|
// strcpy(c_mode, "r+");
|
||||||
|
// if (testi && testo && testt && !testa)
|
||||||
|
// strcpy(c_mode, "w+");
|
||||||
|
|
||||||
|
// Mode string should be empty for invalid combination of flags
|
||||||
|
if (strlen(c_mode) == 0) |
||||||
|
return false; |
||||||
|
if (testb) |
||||||
|
strcat(c_mode, "b"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
// Determine number of characters in internal get buffer
|
||||||
|
std::streamsize
|
||||||
|
gzfilebuf::showmanyc() |
||||||
|
{ |
||||||
|
// Calls to underflow will fail if file not opened for reading
|
||||||
|
if (!this->is_open() || !(io_mode & std::ios_base::in)) |
||||||
|
return -1; |
||||||
|
// Make sure get area is in use
|
||||||
|
if (this->gptr() && (this->gptr() < this->egptr())) |
||||||
|
return std::streamsize(this->egptr() - this->gptr()); |
||||||
|
else |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Fill get area from gzipped file
|
||||||
|
gzfilebuf::int_type |
||||||
|
gzfilebuf::underflow()
|
||||||
|
{ |
||||||
|
// If something is left in the get area by chance, return it
|
||||||
|
// (this shouldn't normally happen, as underflow is only supposed
|
||||||
|
// to be called when gptr >= egptr, but it serves as error check)
|
||||||
|
if (this->gptr() && (this->gptr() < this->egptr())) |
||||||
|
return traits_type::to_int_type(*(this->gptr())); |
||||||
|
|
||||||
|
// If the file hasn't been opened for reading, produce error
|
||||||
|
if (!this->is_open() || !(io_mode & std::ios_base::in)) |
||||||
|
return traits_type::eof(); |
||||||
|
|
||||||
|
// Attempt to fill internal buffer from gzipped file
|
||||||
|
// (buffer must be guaranteed to exist...)
|
||||||
|
int bytes_read = gzread(file, buffer, buffer_size); |
||||||
|
// Indicates error or EOF
|
||||||
|
if (bytes_read <= 0) |
||||||
|
{ |
||||||
|
// Reset get area
|
||||||
|
this->setg(buffer, buffer, buffer); |
||||||
|
return traits_type::eof(); |
||||||
|
} |
||||||
|
// Make all bytes read from file available as get area
|
||||||
|
this->setg(buffer, buffer, buffer + bytes_read); |
||||||
|
|
||||||
|
// Return next character in get area
|
||||||
|
return traits_type::to_int_type(*(this->gptr())); |
||||||
|
} |
||||||
|
|
||||||
|
// Write put area to gzipped file
|
||||||
|
gzfilebuf::int_type |
||||||
|
gzfilebuf::overflow(int_type c)
|
||||||
|
{ |
||||||
|
// Determine whether put area is in use
|
||||||
|
if (this->pbase()) |
||||||
|
{ |
||||||
|
// Double-check pointer range
|
||||||
|
if (this->pptr() > this->epptr() || this->pptr() < this->pbase()) |
||||||
|
return traits_type::eof(); |
||||||
|
// Add extra character to buffer if not EOF
|
||||||
|
if (!traits_type::eq_int_type(c, traits_type::eof())) |
||||||
|
{ |
||||||
|
*(this->pptr()) = traits_type::to_char_type(c); |
||||||
|
this->pbump(1); |
||||||
|
} |
||||||
|
// Number of characters to write to file
|
||||||
|
int bytes_to_write = this->pptr() - this->pbase(); |
||||||
|
// Overflow doesn't fail if nothing is to be written
|
||||||
|
if (bytes_to_write > 0) |
||||||
|
{ |
||||||
|
// If the file hasn't been opened for writing, produce error
|
||||||
|
if (!this->is_open() || !(io_mode & std::ios_base::out)) |
||||||
|
return traits_type::eof(); |
||||||
|
// If gzipped file won't accept all bytes written to it, fail
|
||||||
|
if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write) |
||||||
|
return traits_type::eof(); |
||||||
|
// Reset next pointer to point to pbase on success
|
||||||
|
this->pbump(-bytes_to_write); |
||||||
|
} |
||||||
|
} |
||||||
|
// Write extra character to file if not EOF
|
||||||
|
else if (!traits_type::eq_int_type(c, traits_type::eof())) |
||||||
|
{ |
||||||
|
// If the file hasn't been opened for writing, produce error
|
||||||
|
if (!this->is_open() || !(io_mode & std::ios_base::out)) |
||||||
|
return traits_type::eof(); |
||||||
|
// Impromptu char buffer (allows "unbuffered" output)
|
||||||
|
char_type last_char = traits_type::to_char_type(c); |
||||||
|
// If gzipped file won't accept this character, fail
|
||||||
|
if (gzwrite(file, &last_char, 1) != 1) |
||||||
|
return traits_type::eof();
|
||||||
|
} |
||||||
|
|
||||||
|
// If you got here, you have succeeded (even if c was EOF)
|
||||||
|
// The return value should therefore be non-EOF
|
||||||
|
if (traits_type::eq_int_type(c, traits_type::eof())) |
||||||
|
return traits_type::not_eof(c); |
||||||
|
else |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
// Assign new buffer
|
||||||
|
std::streambuf*
|
||||||
|
gzfilebuf::setbuf(char_type* p, |
||||||
|
std::streamsize n) |
||||||
|
{ |
||||||
|
// First make sure stuff is sync'ed, for safety
|
||||||
|
if (this->sync() == -1) |
||||||
|
return NULL; |
||||||
|
// If buffering is turned off on purpose via setbuf(0,0), still allocate one...
|
||||||
|
// "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
|
||||||
|
// least a buffer of size 1 (very inefficient though, therefore make it bigger?)
|
||||||
|
// This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
|
||||||
|
if (!p || !n) |
||||||
|
{ |
||||||
|
// Replace existing buffer (if any) with small internal buffer
|
||||||
|
this->disable_buffer(); |
||||||
|
buffer = NULL; |
||||||
|
buffer_size = 0; |
||||||
|
own_buffer = true; |
||||||
|
this->enable_buffer(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// Replace existing buffer (if any) with external buffer
|
||||||
|
this->disable_buffer(); |
||||||
|
buffer = p; |
||||||
|
buffer_size = n; |
||||||
|
own_buffer = false; |
||||||
|
this->enable_buffer(); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
// Write put area to gzipped file (i.e. ensures that put area is empty)
|
||||||
|
int
|
||||||
|
gzfilebuf::sync()
|
||||||
|
{ |
||||||
|
return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
||||||
|
|
||||||
|
// Allocate internal buffer
|
||||||
|
void
|
||||||
|
gzfilebuf::enable_buffer()
|
||||||
|
{ |
||||||
|
// If internal buffer required, allocate one
|
||||||
|
if (own_buffer && !buffer)
|
||||||
|
{ |
||||||
|
// Check for buffered vs. "unbuffered"
|
||||||
|
if (buffer_size > 0) |
||||||
|
{ |
||||||
|
// Allocate internal buffer
|
||||||
|
buffer = new char_type[buffer_size]; |
||||||
|
// Get area starts empty and will be expanded by underflow as need arises
|
||||||
|
this->setg(buffer, buffer, buffer); |
||||||
|
// Setup entire internal buffer as put area.
|
||||||
|
// The one-past-end pointer actually points to the last element of the buffer,
|
||||||
|
// so that overflow(c) can safely add the extra character c to the sequence.
|
||||||
|
// These pointers remain in place for the duration of the buffer
|
||||||
|
this->setp(buffer, buffer + buffer_size - 1); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// Even in "unbuffered" case, (small?) get buffer is still required
|
||||||
|
buffer_size = SMALLBUFSIZE; |
||||||
|
buffer = new char_type[buffer_size]; |
||||||
|
this->setg(buffer, buffer, buffer); |
||||||
|
// "Unbuffered" means no put buffer
|
||||||
|
this->setp(0, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// If buffer already allocated, reset buffer pointers just to make sure no
|
||||||
|
// stale chars are lying around
|
||||||
|
this->setg(buffer, buffer, buffer); |
||||||
|
this->setp(buffer, buffer + buffer_size - 1); |
||||||
|
}
|
||||||
|
} |
||||||
|
|
||||||
|
// Destroy internal buffer
|
||||||
|
void
|
||||||
|
gzfilebuf::disable_buffer()
|
||||||
|
{ |
||||||
|
// If internal buffer exists, deallocate it
|
||||||
|
if (own_buffer && buffer) |
||||||
|
{ |
||||||
|
// Preserve unbuffered status by zeroing size
|
||||||
|
if (!this->pbase()) |
||||||
|
buffer_size = 0; |
||||||
|
delete[] buffer; |
||||||
|
buffer = NULL; |
||||||
|
this->setg(0, 0, 0); |
||||||
|
this->setp(0, 0); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// Reset buffer pointers to initial state if external buffer exists
|
||||||
|
this->setg(buffer, buffer, buffer); |
||||||
|
if (buffer) |
||||||
|
this->setp(buffer, buffer + buffer_size - 1); |
||||||
|
else |
||||||
|
this->setp(0, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
// Default constructor initializes stream buffer
|
||||||
|
gzifstream::gzifstream()
|
||||||
|
: std::istream(NULL), sb() |
||||||
|
{ this->init(&sb); } |
||||||
|
|
||||||
|
// Initialize stream buffer and open file
|
||||||
|
gzifstream::gzifstream(const char* name, |
||||||
|
std::ios_base::openmode mode) |
||||||
|
: std::istream(NULL), sb() |
||||||
|
{ |
||||||
|
this->init(&sb); |
||||||
|
this->open(name, mode); |
||||||
|
} |
||||||
|
|
||||||
|
// Initialize stream buffer and attach to file
|
||||||
|
gzifstream::gzifstream(int fd, |
||||||
|
std::ios_base::openmode mode) |
||||||
|
: std::istream(NULL), sb() |
||||||
|
{ |
||||||
|
this->init(&sb); |
||||||
|
this->attach(fd, mode); |
||||||
|
} |
||||||
|
|
||||||
|
// Open file and go into fail() state if unsuccessful
|
||||||
|
void
|
||||||
|
gzifstream::open(const char* name,
|
||||||
|
std::ios_base::openmode mode) |
||||||
|
{ |
||||||
|
if (!sb.open(name, mode | std::ios_base::in)) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
else |
||||||
|
this->clear(); |
||||||
|
} |
||||||
|
|
||||||
|
// Attach to file and go into fail() state if unsuccessful
|
||||||
|
void
|
||||||
|
gzifstream::attach(int fd,
|
||||||
|
std::ios_base::openmode mode) |
||||||
|
{ |
||||||
|
if (!sb.attach(fd, mode | std::ios_base::in)) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
else |
||||||
|
this->clear(); |
||||||
|
} |
||||||
|
|
||||||
|
// Close file
|
||||||
|
void
|
||||||
|
gzifstream::close() |
||||||
|
{ |
||||||
|
if (!sb.close()) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
} |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
// Default constructor initializes stream buffer
|
||||||
|
gzofstream::gzofstream()
|
||||||
|
: std::ostream(NULL), sb() |
||||||
|
{ this->init(&sb); } |
||||||
|
|
||||||
|
// Initialize stream buffer and open file
|
||||||
|
gzofstream::gzofstream(const char* name, |
||||||
|
std::ios_base::openmode mode) |
||||||
|
: std::ostream(NULL), sb() |
||||||
|
{ |
||||||
|
this->init(&sb); |
||||||
|
this->open(name, mode); |
||||||
|
} |
||||||
|
|
||||||
|
// Initialize stream buffer and attach to file
|
||||||
|
gzofstream::gzofstream(int fd, |
||||||
|
std::ios_base::openmode mode) |
||||||
|
: std::ostream(NULL), sb() |
||||||
|
{ |
||||||
|
this->init(&sb); |
||||||
|
this->attach(fd, mode); |
||||||
|
} |
||||||
|
|
||||||
|
// Open file and go into fail() state if unsuccessful
|
||||||
|
void
|
||||||
|
gzofstream::open(const char* name,
|
||||||
|
std::ios_base::openmode mode) |
||||||
|
{ |
||||||
|
if (!sb.open(name, mode | std::ios_base::out)) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
else |
||||||
|
this->clear(); |
||||||
|
} |
||||||
|
|
||||||
|
// Attach to file and go into fail() state if unsuccessful
|
||||||
|
void
|
||||||
|
gzofstream::attach(int fd,
|
||||||
|
std::ios_base::openmode mode) |
||||||
|
{ |
||||||
|
if (!sb.attach(fd, mode | std::ios_base::out)) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
else |
||||||
|
this->clear(); |
||||||
|
} |
||||||
|
|
||||||
|
// Close file
|
||||||
|
void
|
||||||
|
gzofstream::close() |
||||||
|
{ |
||||||
|
if (!sb.close()) |
||||||
|
this->setstate(std::ios_base::failbit); |
||||||
|
} |
@ -0,0 +1,466 @@ |
|||||||
|
/*
|
||||||
|
* A C++ I/O streams interface to the zlib gz* functions |
||||||
|
*
|
||||||
|
* by Ludwig Schwardt <schwardt@sun.ac.za> |
||||||
|
* original version by Kevin Ruland <kevin@rodin.wustl.edu> |
||||||
|
*
|
||||||
|
* This version is standard-compliant and compatible with gcc 3.x. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef ZFSTREAM_H |
||||||
|
#define ZFSTREAM_H |
||||||
|
|
||||||
|
#include <istream> // not iostream, since we don't need cin/cout |
||||||
|
#include <ostream> |
||||||
|
#include "zlib.h" |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gzipped file stream buffer class. |
||||||
|
* |
||||||
|
* This class implements basic_filebuf for gzipped files. It doesn't yet support |
||||||
|
* seeking (allowed by zlib but slow/limited), putback and read/write access
|
||||||
|
* (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
|
||||||
|
* file streambuf. |
||||||
|
*/ |
||||||
|
class gzfilebuf : public std::streambuf
|
||||||
|
{ |
||||||
|
public:
|
||||||
|
// Default constructor.
|
||||||
|
gzfilebuf(); |
||||||
|
|
||||||
|
// Destructor.
|
||||||
|
virtual
|
||||||
|
~gzfilebuf(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set compression level and strategy on the fly. |
||||||
|
* @param comp_level Compression level (see zlib.h for allowed values)
|
||||||
|
* @param comp_strategy Compression strategy (see zlib.h for allowed values)
|
||||||
|
* @return Z_OK on success, Z_STREAM_ERROR otherwise. |
||||||
|
*
|
||||||
|
* Unfortunately, these parameters cannot be modified separately, as the |
||||||
|
* previous zfstream version assumed. Since the strategy is seldom changed, |
||||||
|
* it can default and setcompression(level) then becomes like the old |
||||||
|
* setcompressionlevel(level). |
||||||
|
*/ |
||||||
|
int
|
||||||
|
setcompression(int comp_level,
|
||||||
|
int comp_strategy = Z_DEFAULT_STRATEGY); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if file is open. |
||||||
|
* @return True if file is open. |
||||||
|
*/ |
||||||
|
bool
|
||||||
|
is_open() const { return (file != NULL); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open gzipped file. |
||||||
|
* @param name File name. |
||||||
|
* @param mode Open mode flags. |
||||||
|
* @return @c this on success, NULL on failure. |
||||||
|
*/ |
||||||
|
gzfilebuf*
|
||||||
|
open(const char* name,
|
||||||
|
std::ios_base::openmode mode); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attach to already open gzipped file. |
||||||
|
* @param fd File descriptor. |
||||||
|
* @param mode Open mode flags. |
||||||
|
* @return @c this on success, NULL on failure. |
||||||
|
*/ |
||||||
|
gzfilebuf*
|
||||||
|
attach(int fd,
|
||||||
|
std::ios_base::openmode mode); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close gzipped file. |
||||||
|
* @return @c this on success, NULL on failure. |
||||||
|
*/ |
||||||
|
gzfilebuf*
|
||||||
|
close(); |
||||||
|
|
||||||
|
protected: |
||||||
|
/**
|
||||||
|
* @brief Convert ios open mode int to mode string used by zlib. |
||||||
|
* @return True if valid mode flag combination. |
||||||
|
*/ |
||||||
|
bool
|
||||||
|
open_mode(std::ios_base::openmode mode,
|
||||||
|
char* c_mode) const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of characters available in stream buffer. |
||||||
|
* @return Number of characters. |
||||||
|
*
|
||||||
|
* This indicates number of characters in get area of stream buffer. |
||||||
|
* These characters can be read without accessing the gzipped file. |
||||||
|
*/ |
||||||
|
virtual std::streamsize |
||||||
|
showmanyc(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fill get area from gzipped file. |
||||||
|
* @return First character in get area on success, EOF on error. |
||||||
|
*
|
||||||
|
* This actually reads characters from gzipped file to stream |
||||||
|
* buffer. Always buffered. |
||||||
|
*/ |
||||||
|
virtual int_type |
||||||
|
underflow(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write put area to gzipped file. |
||||||
|
* @param c Extra character to add to buffer contents. |
||||||
|
* @return Non-EOF on success, EOF on error. |
||||||
|
*
|
||||||
|
* This actually writes characters in stream buffer to
|
||||||
|
* gzipped file. With unbuffered output this is done one
|
||||||
|
* character at a time. |
||||||
|
*/
|
||||||
|
virtual int_type
|
||||||
|
overflow(int_type c = traits_type::eof()); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Installs external stream buffer. |
||||||
|
* @param p Pointer to char buffer. |
||||||
|
* @param n Size of external buffer. |
||||||
|
* @return @c this on success, NULL on failure. |
||||||
|
*
|
||||||
|
* Call setbuf(0,0) to enable unbuffered output. |
||||||
|
*/ |
||||||
|
virtual std::streambuf*
|
||||||
|
setbuf(char_type* p,
|
||||||
|
std::streamsize n); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush stream buffer to file. |
||||||
|
* @return 0 on success, -1 on error. |
||||||
|
*
|
||||||
|
* This calls underflow(EOF) to do the job. |
||||||
|
*/ |
||||||
|
virtual int
|
||||||
|
sync(); |
||||||
|
|
||||||
|
//
|
||||||
|
// Some future enhancements
|
||||||
|
//
|
||||||
|
// virtual int_type uflow();
|
||||||
|
// virtual int_type pbackfail(int_type c = traits_type::eof());
|
||||||
|
// virtual pos_type
|
||||||
|
// seekoff(off_type off,
|
||||||
|
// std::ios_base::seekdir way,
|
||||||
|
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
|
||||||
|
// virtual pos_type
|
||||||
|
// seekpos(pos_type sp,
|
||||||
|
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
|
||||||
|
|
||||||
|
private: |
||||||
|
/**
|
||||||
|
* @brief Allocate internal buffer. |
||||||
|
*
|
||||||
|
* This function is safe to call multiple times. It will ensure |
||||||
|
* that a proper internal buffer exists if it is required. If the |
||||||
|
* buffer already exists or is external, the buffer pointers will be |
||||||
|
* reset to their original state. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
enable_buffer(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroy internal buffer. |
||||||
|
*
|
||||||
|
* This function is safe to call multiple times. It will ensure |
||||||
|
* that the internal buffer is deallocated if it exists. In any |
||||||
|
* case, it will also reset the buffer pointers. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
disable_buffer(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Underlying file pointer. |
||||||
|
*/ |
||||||
|
gzFile file; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode in which file was opened. |
||||||
|
*/ |
||||||
|
std::ios_base::openmode io_mode; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief True if this object owns file descriptor. |
||||||
|
* |
||||||
|
* This makes the class responsible for closing the file
|
||||||
|
* upon destruction. |
||||||
|
*/ |
||||||
|
bool own_fd; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stream buffer. |
||||||
|
*
|
||||||
|
* For simplicity this remains allocated on the free store for the
|
||||||
|
* entire life span of the gzfilebuf object, unless replaced by setbuf. |
||||||
|
*/ |
||||||
|
char_type* buffer; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stream buffer size. |
||||||
|
*
|
||||||
|
* Defaults to system default buffer size (typically 8192 bytes). |
||||||
|
* Modified by setbuf. |
||||||
|
*/ |
||||||
|
std::streamsize buffer_size; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief True if this object owns stream buffer. |
||||||
|
* |
||||||
|
* This makes the class responsible for deleting the buffer
|
||||||
|
* upon destruction. |
||||||
|
*/ |
||||||
|
bool own_buffer; |
||||||
|
}; |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gzipped file input stream class. |
||||||
|
* |
||||||
|
* This class implements ifstream for gzipped files. Seeking and putback |
||||||
|
* is not supported yet. |
||||||
|
*/ |
||||||
|
class gzifstream : public std::istream
|
||||||
|
{ |
||||||
|
public: |
||||||
|
// Default constructor
|
||||||
|
gzifstream(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct stream on gzipped file to be opened. |
||||||
|
* @param name File name. |
||||||
|
* @param mode Open mode flags (forced to contain ios::in). |
||||||
|
*/ |
||||||
|
explicit |
||||||
|
gzifstream(const char* name,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct stream on already open gzipped file. |
||||||
|
* @param fd File descriptor. |
||||||
|
* @param mode Open mode flags (forced to contain ios::in). |
||||||
|
*/ |
||||||
|
explicit
|
||||||
|
gzifstream(int fd,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain underlying stream buffer. |
||||||
|
*/
|
||||||
|
gzfilebuf*
|
||||||
|
rdbuf() const |
||||||
|
{ return const_cast<gzfilebuf*>(&sb); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if file is open. |
||||||
|
* @return True if file is open. |
||||||
|
*/ |
||||||
|
bool
|
||||||
|
is_open() { return sb.is_open(); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open gzipped file. |
||||||
|
* @param name File name. |
||||||
|
* @param mode Open mode flags (forced to contain ios::in). |
||||||
|
*
|
||||||
|
* Stream will be in state good() if file opens successfully; |
||||||
|
* otherwise in state fail(). This differs from the behavior of |
||||||
|
* ifstream, which never sets the state to good() and therefore |
||||||
|
* won't allow you to reuse the stream for a second file unless |
||||||
|
* you manually clear() the state. The choice is a matter of |
||||||
|
* convenience. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
open(const char* name,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attach to already open gzipped file. |
||||||
|
* @param fd File descriptor. |
||||||
|
* @param mode Open mode flags (forced to contain ios::in). |
||||||
|
*
|
||||||
|
* Stream will be in state good() if attach succeeded; otherwise |
||||||
|
* in state fail(). |
||||||
|
*/ |
||||||
|
void
|
||||||
|
attach(int fd,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close gzipped file. |
||||||
|
*
|
||||||
|
* Stream will be in state fail() if close failed. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
close(); |
||||||
|
|
||||||
|
private: |
||||||
|
/**
|
||||||
|
* Underlying stream buffer. |
||||||
|
*/
|
||||||
|
gzfilebuf sb; |
||||||
|
}; |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gzipped file output stream class. |
||||||
|
* |
||||||
|
* This class implements ofstream for gzipped files. Seeking and putback |
||||||
|
* is not supported yet. |
||||||
|
*/ |
||||||
|
class gzofstream : public std::ostream |
||||||
|
{ |
||||||
|
public: |
||||||
|
// Default constructor
|
||||||
|
gzofstream(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct stream on gzipped file to be opened. |
||||||
|
* @param name File name. |
||||||
|
* @param mode Open mode flags (forced to contain ios::out). |
||||||
|
*/ |
||||||
|
explicit |
||||||
|
gzofstream(const char* name,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::out); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct stream on already open gzipped file. |
||||||
|
* @param fd File descriptor. |
||||||
|
* @param mode Open mode flags (forced to contain ios::out). |
||||||
|
*/ |
||||||
|
explicit
|
||||||
|
gzofstream(int fd,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::out); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain underlying stream buffer. |
||||||
|
*/
|
||||||
|
gzfilebuf*
|
||||||
|
rdbuf() const |
||||||
|
{ return const_cast<gzfilebuf*>(&sb); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if file is open. |
||||||
|
* @return True if file is open. |
||||||
|
*/ |
||||||
|
bool
|
||||||
|
is_open() { return sb.is_open(); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open gzipped file. |
||||||
|
* @param name File name. |
||||||
|
* @param mode Open mode flags (forced to contain ios::out). |
||||||
|
*
|
||||||
|
* Stream will be in state good() if file opens successfully; |
||||||
|
* otherwise in state fail(). This differs from the behavior of |
||||||
|
* ofstream, which never sets the state to good() and therefore |
||||||
|
* won't allow you to reuse the stream for a second file unless |
||||||
|
* you manually clear() the state. The choice is a matter of |
||||||
|
* convenience. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
open(const char* name,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::out); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attach to already open gzipped file. |
||||||
|
* @param fd File descriptor. |
||||||
|
* @param mode Open mode flags (forced to contain ios::out). |
||||||
|
*
|
||||||
|
* Stream will be in state good() if attach succeeded; otherwise |
||||||
|
* in state fail(). |
||||||
|
*/ |
||||||
|
void
|
||||||
|
attach(int fd,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::out); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close gzipped file. |
||||||
|
*
|
||||||
|
* Stream will be in state fail() if close failed. |
||||||
|
*/ |
||||||
|
void
|
||||||
|
close(); |
||||||
|
|
||||||
|
private: |
||||||
|
/**
|
||||||
|
* Underlying stream buffer. |
||||||
|
*/
|
||||||
|
gzfilebuf sb; |
||||||
|
}; |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gzipped file output stream manipulator class. |
||||||
|
* |
||||||
|
* This class defines a two-argument manipulator for gzofstream. It is used |
||||||
|
* as base for the setcompression(int,int) manipulator. |
||||||
|
*/ |
||||||
|
template<typename T1, typename T2> |
||||||
|
class gzomanip2 |
||||||
|
{ |
||||||
|
public: |
||||||
|
// Allows insertor to peek at internals
|
||||||
|
template <typename Ta, typename Tb> |
||||||
|
friend gzofstream&
|
||||||
|
operator<<(gzofstream&,
|
||||||
|
const gzomanip2<Ta,Tb>&); |
||||||
|
|
||||||
|
// Constructor
|
||||||
|
gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2), |
||||||
|
T1 v1, |
||||||
|
T2 v2); |
||||||
|
private: |
||||||
|
// Underlying manipulator function
|
||||||
|
gzofstream& |
||||||
|
(*func)(gzofstream&, T1, T2); |
||||||
|
|
||||||
|
// Arguments for manipulator function
|
||||||
|
T1 val1; |
||||||
|
T2 val2; |
||||||
|
}; |
||||||
|
|
||||||
|
/*****************************************************************************/ |
||||||
|
|
||||||
|
// Manipulator function thunks through to stream buffer
|
||||||
|
inline gzofstream&
|
||||||
|
setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY) |
||||||
|
{ |
||||||
|
(gzs.rdbuf())->setcompression(l, s); |
||||||
|
return gzs; |
||||||
|
} |
||||||
|
|
||||||
|
// Manipulator constructor stores arguments
|
||||||
|
template<typename T1, typename T2> |
||||||
|
inline
|
||||||
|
gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), |
||||||
|
T1 v1, |
||||||
|
T2 v2)
|
||||||
|
: func(f), val1(v1), val2(v2) |
||||||
|
{ } |
||||||
|
|
||||||
|
// Insertor applies underlying manipulator function to stream
|
||||||
|
template<typename T1, typename T2> |
||||||
|
inline gzofstream&
|
||||||
|
operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
|
||||||
|
{ return (*m.func)(s, m.val1, m.val2); } |
||||||
|
|
||||||
|
// Insert this onto stream to simplify setting of compression level
|
||||||
|
inline gzomanip2<int,int>
|
||||||
|
setcompression(int l, int s = Z_DEFAULT_STRATEGY)
|
||||||
|
{ return gzomanip2<int,int>(&setcompression, l, s); } |
||||||
|
|
||||||
|
#endif // ZFSTREAM_H
|
@ -0,0 +1,326 @@ |
|||||||
|
/* zconf.h -- configuration of the zlib compression library
|
||||||
|
* Copyright (C) 1995-2003 Jean-loup Gailly. |
||||||
|
* For conditions of distribution and use, see copyright notice in zlib.h |
||||||
|
*/ |
||||||
|
|
||||||
|
/* @(#) $Id$ */ |
||||||
|
|
||||||
|
#ifndef _ZCONF_H |
||||||
|
#define _ZCONF_H |
||||||
|
|
||||||
|
/*
|
||||||
|
* If you *really* need a unique prefix for all types and library functions, |
||||||
|
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. |
||||||
|
*/ |
||||||
|
#ifdef Z_PREFIX |
||||||
|
# define deflateInit_ z_deflateInit_ |
||||||
|
# define deflate z_deflate |
||||||
|
# define deflateEnd z_deflateEnd |
||||||
|
# define inflateInit_ z_inflateInit_ |
||||||
|
# define inflate z_inflate |
||||||
|
# define inflateEnd z_inflateEnd |
||||||
|
# define deflateInit2_ z_deflateInit2_ |
||||||
|
# define deflateSetDictionary z_deflateSetDictionary |
||||||
|
# define deflateCopy z_deflateCopy |
||||||
|
# define deflateReset z_deflateReset |
||||||
|
# define deflateParams z_deflateParams |
||||||
|
# define deflateBound z_deflateBound |
||||||
|
# define inflateInit2_ z_inflateInit2_ |
||||||
|
# define inflateSetDictionary z_inflateSetDictionary |
||||||
|
# define inflateSync z_inflateSync |
||||||
|
# define inflateSyncPoint z_inflateSyncPoint |
||||||
|
# define inflateCopy z_inflateCopy |
||||||
|
# define inflateReset z_inflateReset |
||||||
|
# define compress z_compress |
||||||
|
# define compress2 z_compress2 |
||||||
|
# define compressBound z_compressBound |
||||||
|
# define uncompress z_uncompress |
||||||
|
# define adler32 z_adler32 |
||||||
|
# define crc32 z_crc32 |
||||||
|
# define get_crc_table z_get_crc_table |
||||||
|
|
||||||
|
# define Byte z_Byte |
||||||
|
# define uInt z_uInt |
||||||
|
# define uLong z_uLong |
||||||
|
# define Bytef z_Bytef |
||||||
|
# define charf z_charf |
||||||
|
# define intf z_intf |
||||||
|
# define uIntf z_uIntf |
||||||
|
# define uLongf z_uLongf |
||||||
|
# define voidpf z_voidpf |
||||||
|
# define voidp z_voidp |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#ifdef __STDC_VERSION__ |
||||||
|
# ifndef STDC |
||||||
|
# define STDC |
||||||
|
# endif |
||||||
|
# if __STDC_VERSION__ >= 199901L |
||||||
|
# ifndef STDC99 |
||||||
|
# define STDC99 |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) |
||||||
|
# define WIN32 |
||||||
|
#endif |
||||||
|
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) |
||||||
|
# ifndef __32BIT__ |
||||||
|
# define __32BIT__ |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
#if defined(__MSDOS__) && !defined(MSDOS) |
||||||
|
# define MSDOS |
||||||
|
#endif |
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more |
||||||
|
* than 64k bytes at a time (needed on systems with 16-bit int). |
||||||
|
*/ |
||||||
|
#if defined(MSDOS) && !defined(__32BIT__) |
||||||
|
# define MAXSEG_64K |
||||||
|
#endif |
||||||
|
#ifdef MSDOS |
||||||
|
# define UNALIGNED_OK |
||||||
|
#endif |
||||||
|
|
||||||
|
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) |
||||||
|
# define STDC |
||||||
|
#endif |
||||||
|
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) |
||||||
|
# ifndef STDC |
||||||
|
# define STDC |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined __HOS_AIX__ |
||||||
|
# ifndef STDC |
||||||
|
# define STDC |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef STDC |
||||||
|
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ |
||||||
|
# define const /* note: need a more gentle solution here */ |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Some Mac compilers merge all .h files incorrectly: */ |
||||||
|
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) |
||||||
|
# define NO_DUMMY_DECL |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Old Borland C incorrectly complains about missing returns: */ |
||||||
|
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x460) |
||||||
|
# define NEED_DUMMY_RETURN |
||||||
|
#endif |
||||||
|
#if defined(__TURBOC__) && !defined(__BORLANDC__) |
||||||
|
# define NEED_DUMMY_RETURN |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
/* Maximum value for memLevel in deflateInit2 */ |
||||||
|
#ifndef MAX_MEM_LEVEL |
||||||
|
# ifdef MAXSEG_64K |
||||||
|
# define MAX_MEM_LEVEL 8 |
||||||
|
# else |
||||||
|
# define MAX_MEM_LEVEL 9 |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||||
|
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files |
||||||
|
* created by gzip. (Files created by minigzip can still be extracted by |
||||||
|
* gzip.) |
||||||
|
*/ |
||||||
|
#ifndef MAX_WBITS |
||||||
|
# define MAX_WBITS 15 /* 32K LZ77 window */ |
||||||
|
#endif |
||||||
|
|
||||||
|
/* The memory requirements for deflate are (in bytes):
|
||||||
|
(1 << (windowBits+2)) + (1 << (memLevel+9)) |
||||||
|
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) |
||||||
|
plus a few kilobytes for small objects. For example, if you want to reduce |
||||||
|
the default memory requirements from 256K to 128K, compile with |
||||||
|
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" |
||||||
|
Of course this will generally degrade compression (there's no free lunch). |
||||||
|
|
||||||
|
The memory requirements for inflate are (in bytes) 1 << windowBits |
||||||
|
that is, 32K for windowBits=15 (default value) plus a few kilobytes |
||||||
|
for small objects. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Type declarations */ |
||||||
|
|
||||||
|
#ifndef OF /* function prototypes */ |
||||||
|
# ifdef STDC |
||||||
|
# define OF(args) args |
||||||
|
# else |
||||||
|
# define OF(args) () |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/*
|
||||||
|
* Microsoft Visual Studio define _vsnprintf but not vsnprintf |
||||||
|
*/ |
||||||
|
#if !defined(STDC99) && !(defined(__TURBOC__) && __TURBOC__ >= 0x550) && !defined(VSNPRINTF_DEFINED) |
||||||
|
# ifdef MSDOS |
||||||
|
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||||
|
but for now we just assume it doesn't. */ |
||||||
|
# define NO_vsnprintf |
||||||
|
# endif |
||||||
|
# ifdef WIN32 |
||||||
|
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ |
||||||
|
# if !defined(vsnprintf) && !defined(__TURBOC__) |
||||||
|
# define vsnprintf _vsnprintf |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
# ifdef __TURBOC__ |
||||||
|
# define NO_vsnprintf |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||||
|
* model programming (small or medium model with some far allocations). |
||||||
|
* This was tested only with MSC; for other MSDOS compilers you may have |
||||||
|
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model, |
||||||
|
* just define FAR to be empty. |
||||||
|
*/ |
||||||
|
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) |
||||||
|
/* MSC small or medium model */ |
||||||
|
# define SMALL_MEDIUM |
||||||
|
# ifdef _MSC_VER |
||||||
|
# define FAR _far |
||||||
|
# else |
||||||
|
# define FAR far |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) |
||||||
|
# ifndef __32BIT__ |
||||||
|
# define SMALL_MEDIUM |
||||||
|
# define FAR _far |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(WIN32) && (!defined(ZLIB_WIN32_NODLL)) && (!defined(ZLIB_DLL)) |
||||||
|
# define ZLIB_DLL |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Compile with -DZLIB_DLL for Windows DLL support */ |
||||||
|
#if defined(ZLIB_DLL) |
||||||
|
# if defined(_WINDOWS) || defined(WINDOWS) || defined(WIN32) |
||||||
|
# ifndef WINAPIV |
||||||
|
# ifdef FAR |
||||||
|
# undef FAR |
||||||
|
# endif |
||||||
|
# include <windows.h> |
||||||
|
# endif |
||||||
|
# ifdef WIN32 |
||||||
|
# define ZEXPORT WINAPI |
||||||
|
# define ZEXPORTVA WINAPIV |
||||||
|
# else |
||||||
|
# define ZEXPORT WINAPI _export |
||||||
|
# define ZEXPORTVA FAR _cdecl _export |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
# if defined (__BORLANDC__) |
||||||
|
# if (__BORLANDC__ >= 0x0500) && defined (WIN32) |
||||||
|
# include <windows.h> |
||||||
|
# define ZEXPORT __declspec(dllexport) WINAPI |
||||||
|
# define ZEXPORTVA __declspec(dllexport) WINAPIV |
||||||
|
# else |
||||||
|
# if defined (_Windows) && defined (__DLL__) |
||||||
|
# define ZEXPORT _export |
||||||
|
# define ZEXPORTVA _export |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined (__BEOS__) |
||||||
|
# if defined (ZLIB_DLL) |
||||||
|
# define ZEXTERN extern __declspec(dllexport) |
||||||
|
# else |
||||||
|
# define ZEXTERN extern __declspec(dllimport) |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef ZEXPORT |
||||||
|
# define ZEXPORT |
||||||
|
#endif |
||||||
|
#ifndef ZEXPORTVA |
||||||
|
# define ZEXPORTVA |
||||||
|
#endif |
||||||
|
#ifndef ZEXTERN |
||||||
|
# define ZEXTERN extern |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef FAR |
||||||
|
# define FAR |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined(__MACTYPES__) |
||||||
|
typedef unsigned char Byte; /* 8 bits */ |
||||||
|
#endif |
||||||
|
typedef unsigned int uInt; /* 16 bits or more */ |
||||||
|
typedef unsigned long uLong; /* 32 bits or more */ |
||||||
|
|
||||||
|
#ifdef SMALL_MEDIUM |
||||||
|
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ |
||||||
|
# define Bytef Byte FAR |
||||||
|
#else |
||||||
|
typedef Byte FAR Bytef; |
||||||
|
#endif |
||||||
|
typedef char FAR charf; |
||||||
|
typedef int FAR intf; |
||||||
|
typedef uInt FAR uIntf; |
||||||
|
typedef uLong FAR uLongf; |
||||||
|
|
||||||
|
#ifdef STDC |
||||||
|
typedef void const *voidpc; |
||||||
|
typedef void FAR *voidpf; |
||||||
|
typedef void *voidp; |
||||||
|
#else |
||||||
|
typedef Byte const *voidpc; |
||||||
|
typedef Byte FAR *voidpf; |
||||||
|
typedef Byte *voidp; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||||
|
# include <sys/types.h> /* for off_t */ |
||||||
|
# include <unistd.h> /* for SEEK_* and off_t */ |
||||||
|
# ifdef VMS |
||||||
|
# include <unixio.h> /* for off_t */ |
||||||
|
# endif |
||||||
|
# define z_off_t off_t |
||||||
|
#endif |
||||||
|
#ifndef SEEK_SET |
||||||
|
# define SEEK_SET 0 /* Seek from beginning of file. */ |
||||||
|
# define SEEK_CUR 1 /* Seek from current position. */ |
||||||
|
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ |
||||||
|
#endif |
||||||
|
#ifndef z_off_t |
||||||
|
# define z_off_t long |
||||||
|
#endif |
||||||
|
|
||||||
|
/* MVS linker does not support external names larger than 8 bytes */ |
||||||
|
#if defined(__MVS__) |
||||||
|
# pragma map(deflateInit_,"DEIN") |
||||||
|
# pragma map(deflateInit2_,"DEIN2") |
||||||
|
# pragma map(deflateEnd,"DEEND") |
||||||
|
# pragma map(deflateBound,"DEBND") |
||||||
|
# pragma map(inflateInit_,"ININ") |
||||||
|
# pragma map(inflateInit2_,"ININ2") |
||||||
|
# pragma map(inflateEnd,"INEND") |
||||||
|
# pragma map(inflateSync,"INSY") |
||||||
|
# pragma map(inflateSetDictionary,"INSEDI") |
||||||
|
# pragma map(compressBound,"CMBND") |
||||||
|
# pragma map(inflate_table,"INTABL") |
||||||
|
# pragma map(inflate_fast,"INFA") |
||||||
|
# pragma map(inflate_copyright,"INCOPY") |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* _ZCONF_H */ |
@ -0,0 +1,257 @@ |
|||||||
|
|
||||||
|
Frequently Asked Questions about ZLIB.DLL |
||||||
|
|
||||||
|
|
||||||
|
This FAQ is about the design, the rationale, and the use of |
||||||
|
ZLIB.DLL. If you have general questions about zlib, you should |
||||||
|
check the file "FAQ" found in the zlib distribution, or at the |
||||||
|
location http://www.gzip.org/zlib/zlib_faq.html |
||||||
|
|
||||||
|
|
||||||
|
1. Why am I having problems using ZLIB.DLL? My application works |
||||||
|
with the static build of zlib just fine, and I didn't make any |
||||||
|
modification when recompiling it for ZLIB.DLL. |
||||||
|
|
||||||
|
- Make sure you define ZLIB_DLL before including "zlib.h". |
||||||
|
Applications that link to ZLIB.DLL will work properly if |
||||||
|
the source files are compiled in this (or in a compatible) |
||||||
|
way, and the executables are linked to MSVCRT.DLL. |
||||||
|
|
||||||
|
|
||||||
|
2. Why do I have to do this? When I use other libraries, I can |
||||||
|
link my code to their static or dynamic versions, without |
||||||
|
needing any source code modification or recompilation. |
||||||
|
|
||||||
|
- In order to preserve the backwards compatibility with the |
||||||
|
older versions of ZLIB.DLL, and give the ability to use zlib |
||||||
|
to the non-C programmers at the same time, we had to do this |
||||||
|
compromise. |
||||||
|
|
||||||
|
|
||||||
|
3. What exactly is this mess about, and why is it happening? |
||||||
|
|
||||||
|
- It's about the calling convention used for the zlib functions. |
||||||
|
If linked in statically, zlib uses the C (CDECL) convention. |
||||||
|
If linked in dynamically (via ZLIB.DLL), it uses the STDCALL |
||||||
|
convention. The ZLIB_DLL macro switches on the use of STDCALL. |
||||||
|
|
||||||
|
It happens because we need to preserve compatibility with the |
||||||
|
old releases of ZLIB.DLL that use STDCALL, and, at the same |
||||||
|
time, we must provide support for programmers who use other |
||||||
|
programming languages with bindings that require CDECL. |
||||||
|
|
||||||
|
|
||||||
|
4. Why not use the STDCALL convention all the time? |
||||||
|
It's the standard convention in Win32, and I need it in my |
||||||
|
Visual Basic project! |
||||||
|
|
||||||
|
- Most of the Win32 API functions (without varargs) use indeed |
||||||
|
the STDCALL (WINAPI) convention, but the standard C functions |
||||||
|
use the default CDECL. If one calls Win32 functions such as |
||||||
|
CreateFile(), sometimes it makes sense to decorate one's own |
||||||
|
functions with STDCALL. But if one is aiming at ANSI C or |
||||||
|
POSIX portability, and calls functions such as fopen(), it is |
||||||
|
not a sound decision to include <windows.h> or to use non-ANSI |
||||||
|
constructs only to make one's functions STDCALL-able. This is |
||||||
|
not the biggest problem, however. |
||||||
|
|
||||||
|
Technically, STDCALL is not bad; it is even a little faster |
||||||
|
than CDECL. The problem of using STDCALL is actually a problem |
||||||
|
of using any explicit calling convention. FASTCALL falls into |
||||||
|
the same category. |
||||||
|
|
||||||
|
Explicit specification of calling conventions, whether it's |
||||||
|
direct or indirect via a macro, happens commonly in Windows, |
||||||
|
but it is regarded as a noisy, non-standard C quirk on other |
||||||
|
platforms. It isn't possible to write an ANSI C -conforming |
||||||
|
program, for example, if it is necessary to specify calling |
||||||
|
conventions. Libraries can hide the dirty stuff in header |
||||||
|
files, under macros, but callbacks will still remain exposed. |
||||||
|
This is why the zlib callbacks will not be decorated. |
||||||
|
(The old Windows callbacks, such as WndProc, are decorated, |
||||||
|
but the newer ones are not.) |
||||||
|
|
||||||
|
There is one more problem with explicit, non-default calling |
||||||
|
conventions: the ability to use zlib in other programming |
||||||
|
languages. Some of them, like Ada (GNAT) and Fortran (GNU G77) |
||||||
|
have C bindings implemented initially on Unix, hence relying |
||||||
|
on the C calling convention. |
||||||
|
|
||||||
|
So we are decorating the functions using STDCALL in ZLIB.DLL |
||||||
|
to maintain compatibility with the old versions, but we are |
||||||
|
using the default CDECL in the static library, to allow other |
||||||
|
programming languages to use zlib in a portable fashion, via |
||||||
|
C bindings. |
||||||
|
|
||||||
|
|
||||||
|
5. Why not use the default (CDECL) convention all the time? |
||||||
|
It's the standard convention in C, and I need it in my Ada |
||||||
|
project! |
||||||
|
|
||||||
|
- Originally, ZLIB.DLL was intended to run under Visual Basic, |
||||||
|
and VB6 and earlier need STDCALL. |
||||||
|
|
||||||
|
We admit that cluttering the main zlib sources, for the sake |
||||||
|
of interfacing with Visual Basic and at the expense of other |
||||||
|
programming languages, is not fair. It would have been better |
||||||
|
to maintain a "VB-only" project in the contrib/ directory, and |
||||||
|
to build a custom ZLIBVB.DLL, for example -- as we did with |
||||||
|
the Delphi projects. Another possible solution would have been |
||||||
|
to build STDCALL wrappers around the CDECL-exported functions. |
||||||
|
|
||||||
|
But this was the accident that we have to live with, in order |
||||||
|
to maintain binary compatibility with the older versions of |
||||||
|
ZLIB.DLL. |
||||||
|
|
||||||
|
|
||||||
|
6. If my application uses ZLIB.DLL, do I have to link it to |
||||||
|
MSVCRT.DLL? Why? |
||||||
|
|
||||||
|
- The executables (.EXE, .DLL, etc.) that are involved in the |
||||||
|
same process and are using the C run-time library (i.e. they |
||||||
|
are calling any standard C function), must link to the same |
||||||
|
library. There are several libraries in the Win32 system: |
||||||
|
CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. |
||||||
|
Since ZLIB.DLL is linked to MSVCRT.DLL, the executables that |
||||||
|
depend on it must also link to MSVCRT.DLL. |
||||||
|
|
||||||
|
|
||||||
|
7. Why are you saying that ZLIB.DLL and my application must be |
||||||
|
linked to the same C run-time library (CRT)? I linked my |
||||||
|
application and my DLLs to different C libraries (e.g. my |
||||||
|
application to a static library, and my DLLs to MSVCRT.DLL), |
||||||
|
and everything works fine. |
||||||
|
|
||||||
|
- If a library invokes only pure Win32 API (i.e. accessible |
||||||
|
via <windows.h>), its DLL build will work in any context. |
||||||
|
But if a library invokes standard C functions, things get |
||||||
|
more complicated. |
||||||
|
|
||||||
|
There is a single Win32 library in a Win32 system. Every |
||||||
|
function in this library resides in a single DLL module, that |
||||||
|
is safe to call from anywhere. On the other hand, there are |
||||||
|
multiple versions of the C library that are all at the same |
||||||
|
time in the system, and all of them have internal states, |
||||||
|
therefore it is dangerous to intermix them with each other. |
||||||
|
|
||||||
|
Intermixing multiple C libraries is possible, as long as their |
||||||
|
internal states are kept intact. The Microsoft Knowledge Base |
||||||
|
article Q140584 "HOWTO: Link with the Correct C Run-Time (CRT) |
||||||
|
Library" enumerates some of the potential problems raised by |
||||||
|
intermixing, but does not offer a complete description of how |
||||||
|
to avoid them, except by advising not to mix the C libraries. |
||||||
|
If you can send us more information about this issue, we will |
||||||
|
highly appreciate it. (But please do NOT send us source code |
||||||
|
from Microsoft, even if it comes with your legitimate copy of |
||||||
|
Visual C++!) |
||||||
|
|
||||||
|
If this kind of intermixing works for you, it's because your |
||||||
|
application and DLLs are avoiding the corruption of the CRT's |
||||||
|
internal states, due to a fortunate accident. It's not because |
||||||
|
those libraries really work together. |
||||||
|
|
||||||
|
Also note that linking ZLIB.DLL to non-Microsoft C libraries |
||||||
|
(such as Borland's) raises similar problems. |
||||||
|
|
||||||
|
|
||||||
|
8. Why are you linking ZLIB.DLL to MSVCRT.DLL? |
||||||
|
|
||||||
|
- MSVCRT.DLL exists on every Windows 95 with a new service pack |
||||||
|
installed, or with Microsoft Internet Explorer 4 or later, and |
||||||
|
on all other Windows 4.x or later (Windows 98, Windows NT 4, |
||||||
|
or later). It is freely distributable; if not present in the |
||||||
|
system, it can be downloaded from Microsoft or from other |
||||||
|
software provider for free. |
||||||
|
|
||||||
|
The fact that MSVCRT.DLL does not exist on a virgin Windows 95 |
||||||
|
is not so problematic. The number of Windows 95 installations |
||||||
|
is rapidly decreasing, Microsoft stopped supporting it a long |
||||||
|
time ago, and many recent applications from various vendors |
||||||
|
including Microsoft, do not even run on it. Even without these |
||||||
|
arguments, no serious user should run Windows 95 without a |
||||||
|
proper update installed. |
||||||
|
|
||||||
|
There is also the fact that the mainstream C compilers for |
||||||
|
Windows are Microsoft Visual C++ 6.0, and gcc/MinGW. Both |
||||||
|
are producing executables that link to MSVCRT.DLL by default, |
||||||
|
without offering other dynamic CRTs as alternatives easy to |
||||||
|
select by users. |
||||||
|
|
||||||
|
|
||||||
|
9. Why are you not linking ZLIB.DLL to |
||||||
|
<<my favorite C run-time library>> ? |
||||||
|
|
||||||
|
- We considered and abandoned the following alternatives: |
||||||
|
|
||||||
|
* Linking ZLIB.DLL to a static C library (LIBC.LIB, or |
||||||
|
LIBCMT.LIB) is not a good option. People are using ZLIB.DLL |
||||||
|
mainly to save disk space. If you are linking your program |
||||||
|
to a static C library, you may as well consider linking zlib |
||||||
|
in statically, too. |
||||||
|
|
||||||
|
* Linking ZLIB.DLL to CRTDLL.DLL looks very appealing, |
||||||
|
because CRTDLL.DLL is present on every Win32 installation. |
||||||
|
Unfortunately, it has a series of problems: it raises |
||||||
|
difficulties when linking to the Microsoft C++ libraries, |
||||||
|
it is not thread-safe, and Microsoft has discontinued its |
||||||
|
support a long time ago. |
||||||
|
|
||||||
|
* Linking ZLIB.DLL to MSVCRT70.DLL, supplied with the |
||||||
|
Microsoft .NET platform and Visual C++ 7.0, is not a good |
||||||
|
option. Although it can be downloaded and distributed |
||||||
|
freely, it is hardly present on today's Win32 installations. |
||||||
|
If it will become more popular than MSVCRT.DLL, and will be |
||||||
|
pre-installed on the future Win32 systems, we will probably |
||||||
|
think again about it. |
||||||
|
|
||||||
|
* Linking ZLIB.DLL to NTDLL.DLL is not possible. |
||||||
|
NTDLL.DLL exports only a part of the C library, and only |
||||||
|
on Windows NT systems. |
||||||
|
|
||||||
|
|
||||||
|
10. I understand your reasons. However, my project needs ZLIB.DLL |
||||||
|
linked to something different than MSVCRT.DLL. What can I do? |
||||||
|
|
||||||
|
Feel free to rebuild this DLL from the zlib sources, and link |
||||||
|
it the way you want. It is required, however, to clearly |
||||||
|
state that your build is unofficial. Another thing that is not |
||||||
|
required, but highly recommended, is to name that custom DLL |
||||||
|
differently, and/or to install it in a private directory that |
||||||
|
can be accessed by your application, but is not visible to the |
||||||
|
others (e.g. it's not the SYSTEM or the SYSTEM32 directory, |
||||||
|
and it's not in the PATH). Otherwise, your build may clash |
||||||
|
with applications that link to the official build. |
||||||
|
|
||||||
|
For example, in Cygwin, zlib is linked to their runtime |
||||||
|
CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. |
||||||
|
|
||||||
|
|
||||||
|
11. My I include additional pieces of code that I find useful, |
||||||
|
link them in ZLIB.DLL, and export them? |
||||||
|
|
||||||
|
No. A legitimate build of ZLIB.DLL must not include code that |
||||||
|
does not originate from the official zlib sources. But you can |
||||||
|
make your own private build, and give it a different name, as |
||||||
|
suggested in the previous answer. |
||||||
|
|
||||||
|
For example, in Borland Delphi and C++ Builder, zlib is part |
||||||
|
of the standard VCL library. If an application links to VCL |
||||||
|
dynamically, the name of the distributable binary (VCLxx.DLL) |
||||||
|
does not posess any danger of clashing with a legitimate but |
||||||
|
incompatible ZLIB.DLL. |
||||||
|
|
||||||
|
|
||||||
|
12. I see that I may have all kinds of problems if I use ZLIB.DLL. |
||||||
|
Do you recommend to link zlib in statically? Do I get rid of |
||||||
|
problems? |
||||||
|
|
||||||
|
- Yes, definitely. In fact, unless you are distributing a large |
||||||
|
number of executables, each of them linking to zlib, you will |
||||||
|
save space by linking zlib in statically (assuming that you |
||||||
|
would otherwise distribute ZLIB.DLL with your application). |
||||||
|
zlib is not a big library, and the space saved by ZLIB.DLL is |
||||||
|
little. Much of the actual size of the DLL is due to the 4KB |
||||||
|
alignment in the binary. |
||||||
|
|
||||||
|
But you may have reasons, other than size, to use the DLL. |
||||||
|
That is entirely up to you. |
@ -1,107 +0,0 @@ |
|||||||
.TH ZLIB 3 "11 March 2002" |
|
||||||
.SH NAME |
|
||||||
zlib \- compression/decompression library |
|
||||||
.SH SYNOPSIS |
|
||||||
[see |
|
||||||
.I zlib.h |
|
||||||
for full description] |
|
||||||
.SH DESCRIPTION |
|
||||||
The |
|
||||||
.I zlib |
|
||||||
library is a general purpose data compression library. |
|
||||||
The code is thread safe. |
|
||||||
It provides in-memory compression and decompression functions, |
|
||||||
including integrity checks of the uncompressed data. |
|
||||||
This version of the library supports only one compression method (deflation) |
|
||||||
but other algorithms will be added later and will have the same stream interface. |
|
||||||
.LP |
|
||||||
Compression can be done in a single step if the buffers are large enough |
|
||||||
(for example if an input file is mmap'ed), |
|
||||||
or can be done by repeated calls of the compression function. |
|
||||||
In the latter case, |
|
||||||
the application must provide more input and/or consume the output |
|
||||||
(providing more output space) before each call. |
|
||||||
.LP |
|
||||||
The library also supports reading and writing files in |
|
||||||
.I gzip |
|
||||||
(.gz) format |
|
||||||
with an interface similar to that of stdio. |
|
||||||
.LP |
|
||||||
The library does not install any signal handler. The decoder checks |
|
||||||
the consistency of the compressed data, so the library should never |
|
||||||
crash even in case of corrupted input. |
|
||||||
.LP |
|
||||||
All functions of the compression library are documented in the file |
|
||||||
.IR zlib.h. |
|
||||||
The distribution source includes examples of use of the library |
|
||||||
the files |
|
||||||
.I example.c |
|
||||||
and |
|
||||||
.IR minigzip.c . |
|
||||||
.LP |
|
||||||
A Java implementation of |
|
||||||
.IR zlib |
|
||||||
is available in the Java Development Kit 1.1 |
|
||||||
.IP |
|
||||||
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html |
|
||||||
.LP |
|
||||||
A Perl interface to |
|
||||||
.IR zlib , |
|
||||||
written by Paul Marquess (pmarquess@bfsec.bt.co.uk) |
|
||||||
is available at CPAN (Comprehensive Perl Archive Network) sites, |
|
||||||
such as: |
|
||||||
.IP |
|
||||||
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* |
|
||||||
.LP |
|
||||||
A Python interface to |
|
||||||
.IR zlib |
|
||||||
written by A.M. Kuchling <amk@magnet.com> |
|
||||||
is available from the Python Software Association sites, such as: |
|
||||||
.IP |
|
||||||
ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz |
|
||||||
.SH "SEE ALSO" |
|
||||||
Questions about zlib should be sent to: |
|
||||||
.IP |
|
||||||
zlib@quest.jpl.nasa.gov |
|
||||||
or, if this fails, to the author addresses given below. |
|
||||||
The zlib home page is: |
|
||||||
.IP |
|
||||||
http://www.cdrom.com/pub/infozip/zlib/ |
|
||||||
.LP |
|
||||||
The data format used by the zlib library is described by RFC |
|
||||||
(Request for Comments) 1950 to 1952 in the files: |
|
||||||
.IP |
|
||||||
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) |
|
||||||
.br |
|
||||||
rfc1951.txt (deflate format) |
|
||||||
.br |
|
||||||
rfc1952.txt (gzip format) |
|
||||||
.LP |
|
||||||
These documents are also available in other formats from: |
|
||||||
.IP |
|
||||||
ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html |
|
||||||
.SH AUTHORS |
|
||||||
Version 1.1.4 |
|
||||||
Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org) |
|
||||||
and Mark Adler (madler@alumni.caltech.edu). |
|
||||||
.LP |
|
||||||
This software is provided "as-is," |
|
||||||
without any express or implied warranty. |
|
||||||
In no event will the authors be held liable for any damages |
|
||||||
arising from the use of this software. |
|
||||||
See the distribution directory with respect to requirements |
|
||||||
governing redistribution. |
|
||||||
The deflate format used by |
|
||||||
.I zlib |
|
||||||
was defined by Phil Katz. |
|
||||||
The deflate and |
|
||||||
.I zlib |
|
||||||
specifications were written by L. Peter Deutsch. |
|
||||||
Thanks to all the people who reported problems and suggested various |
|
||||||
improvements in |
|
||||||
.IR zlib ; |
|
||||||
who are too numerous to cite here. |
|
||||||
.LP |
|
||||||
UNIX manual page by R. P. C. Rodgers, |
|
||||||
U.S. National Library of Medicine (rodgers@nlm.nih.gov). |
|
||||||
.\" end of man page |
|
@ -0,0 +1,159 @@ |
|||||||
|
.TH ZLIB 3 "12 May 2003" |
||||||
|
.SH NAME |
||||||
|
zlib \- compression/decompression library |
||||||
|
.SH SYNOPSIS |
||||||
|
[see |
||||||
|
.I zlib.h |
||||||
|
for full description] |
||||||
|
.SH DESCRIPTION |
||||||
|
The |
||||||
|
.I zlib |
||||||
|
library is a general purpose data compression library. |
||||||
|
The code is thread safe. |
||||||
|
It provides in-memory compression and decompression functions, |
||||||
|
including integrity checks of the uncompressed data. |
||||||
|
This version of the library supports only one compression method (deflation) |
||||||
|
but other algorithms will be added later |
||||||
|
and will have the same stream interface. |
||||||
|
.LP |
||||||
|
Compression can be done in a single step if the buffers are large enough |
||||||
|
(for example if an input file is mmap'ed), |
||||||
|
or can be done by repeated calls of the compression function. |
||||||
|
In the latter case, |
||||||
|
the application must provide more input and/or consume the output |
||||||
|
(providing more output space) before each call. |
||||||
|
.LP |
||||||
|
The library also supports reading and writing files in |
||||||
|
.IR gzip (1) |
||||||
|
(.gz) format |
||||||
|
with an interface similar to that of stdio. |
||||||
|
.LP |
||||||
|
The library does not install any signal handler. |
||||||
|
The decoder checks the consistency of the compressed data, |
||||||
|
so the library should never crash even in case of corrupted input. |
||||||
|
.LP |
||||||
|
All functions of the compression library are documented in the file |
||||||
|
.IR zlib.h . |
||||||
|
The distribution source includes examples of use of the library |
||||||
|
in the files |
||||||
|
.I example.c |
||||||
|
and |
||||||
|
.IR minigzip.c . |
||||||
|
.LP |
||||||
|
Changes to this version are documented in the file |
||||||
|
.I ChangeLog |
||||||
|
that accompanies the source, |
||||||
|
and are concerned primarily with bug fixes and portability enhancements. |
||||||
|
.LP |
||||||
|
A Java implementation of |
||||||
|
.I zlib |
||||||
|
is available in the Java Development Kit 1.1: |
||||||
|
.IP |
||||||
|
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html |
||||||
|
.LP |
||||||
|
A Perl interface to |
||||||
|
.IR zlib , |
||||||
|
written by Paul Marquess (pmqs@cpan.org), |
||||||
|
is available at CPAN (Comprehensive Perl Archive Network) sites, |
||||||
|
including: |
||||||
|
.IP |
||||||
|
http://www.cpan.org/modules/by-module/Compress/ |
||||||
|
.LP |
||||||
|
A Python interface to |
||||||
|
.IR zlib , |
||||||
|
written by A.M. Kuchling (amk@magnet.com), |
||||||
|
is available in Python 1.5 and later versions: |
||||||
|
.IP |
||||||
|
http://www.python.org/doc/lib/module-zlib.html |
||||||
|
.LP |
||||||
|
A |
||||||
|
.I zlib |
||||||
|
binding for |
||||||
|
.IR tcl (1), |
||||||
|
written by Andreas Kupries (a.kupries@westend.com), |
||||||
|
is availlable at: |
||||||
|
.IP |
||||||
|
http://www.westend.com/~kupries/doc/trf/man/man.html |
||||||
|
.LP |
||||||
|
An experimental package to read and write files in .zip format, |
||||||
|
written on top of |
||||||
|
.I zlib |
||||||
|
by Gilles Vollant (info@winimage.com), |
||||||
|
is available at: |
||||||
|
.IP |
||||||
|
http://www.winimage.com/zLibDll/unzip.html |
||||||
|
and also in the |
||||||
|
.I contrib/minizip |
||||||
|
directory of the main |
||||||
|
.I zlib |
||||||
|
web site. |
||||||
|
.SH "SEE ALSO" |
||||||
|
The |
||||||
|
.I zlib |
||||||
|
web site can be found at either of these locations: |
||||||
|
.IP |
||||||
|
http://www.zlib.org |
||||||
|
.br |
||||||
|
http://www.gzip.org/zlib/ |
||||||
|
.LP |
||||||
|
The data format used by the zlib library is described by RFC |
||||||
|
(Request for Comments) 1950 to 1952 in the files: |
||||||
|
.IP |
||||||
|
http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) |
||||||
|
.br |
||||||
|
http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) |
||||||
|
.br |
||||||
|
http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) |
||||||
|
.LP |
||||||
|
These documents are also available in other formats from: |
||||||
|
.IP |
||||||
|
ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html |
||||||
|
.LP |
||||||
|
Mark Nelson (markn@ieee.org) wrote an article about |
||||||
|
.I zlib |
||||||
|
for the Jan. 1997 issue of Dr. Dobb's Journal; |
||||||
|
a copy of the article is available at: |
||||||
|
.IP |
||||||
|
http://dogma.net/markn/articles/zlibtool/zlibtool.htm |
||||||
|
.SH "REPORTING PROBLEMS" |
||||||
|
Before reporting a problem, |
||||||
|
please check the |
||||||
|
.I zlib |
||||||
|
web site to verify that you have the latest version of |
||||||
|
.IR zlib ; |
||||||
|
otherwise, |
||||||
|
obtain the latest version and see if the problem still exists. |
||||||
|
Please read the |
||||||
|
.I zlib |
||||||
|
FAQ at: |
||||||
|
.IP |
||||||
|
http://www.gzip.org/zlib/zlib_faq.html |
||||||
|
.LP |
||||||
|
before asking for help. |
||||||
|
Send questions and/or comments to zlib@gzip.org, |
||||||
|
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). |
||||||
|
.SH AUTHORS |
||||||
|
Version 1.2.0.1 |
||||||
|
Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org) |
||||||
|
and Mark Adler (madler@alumni.caltech.edu). |
||||||
|
.LP |
||||||
|
This software is provided "as-is," |
||||||
|
without any express or implied warranty. |
||||||
|
In no event will the authors be held liable for any damages |
||||||
|
arising from the use of this software. |
||||||
|
See the distribution directory with respect to requirements |
||||||
|
governing redistribution. |
||||||
|
The deflate format used by |
||||||
|
.I zlib |
||||||
|
was defined by Phil Katz. |
||||||
|
The deflate and |
||||||
|
.I zlib |
||||||
|
specifications were written by L. Peter Deutsch. |
||||||
|
Thanks to all the people who reported problems and suggested various |
||||||
|
improvements in |
||||||
|
.IR zlib ; |
||||||
|
who are too numerous to cite here. |
||||||
|
.LP |
||||||
|
UNIX manual page by R. P. C. Rodgers, |
||||||
|
U.S. National Library of Medicine (rodgers@nlm.nih.gov). |
||||||
|
.\" end of man page |
Loading…
Reference in new issue