📄 manual_3.html
字号:
</P><P>If <CODE>nbytes_in</CODE> is non-null, <CODE>*nbytes_in</CODE> will be set to be thetotal volume of uncompressed data handled. Similarly, <CODE>nbytes_out</CODE>will be set to the total volume of compressed data written.</P><P>Possible assignments to <CODE>bzerror</CODE>:<PRE> <CODE>BZ_SEQUENCE_ERROR</CODE> if <CODE>b</CODE> was opened with <CODE>bzReadOpen</CODE> <CODE>BZ_IO_ERROR</CODE> if there is an error writing the compressed file <CODE>BZ_OK</CODE> otherwise</PRE><H3><A NAME="SEC24" HREF="manual_toc.html#TOC24">Handling embedded compressed data streams</A></H3><P>The high-level library facilitates use of<CODE>bzip2</CODE> data streams which form some part of a surrounding, largerdata stream.<UL><LI>For writing, the library takes an open file handle, writescompressed data to it, <CODE>fflush</CODE>es it but does not <CODE>fclose</CODE> it.The calling application can write its own data before and after thecompressed data stream, using that same file handle.<LI>Reading is more complex, and the facilities are not as generalas they could be since generality is hard to reconcile with efficiency.<CODE>bzRead</CODE> reads from the compressed file in blocks of size<CODE>BZ_MAX_UNUSED</CODE> bytes, and in doing so probably will overshootthe logical end of compressed stream.To recover this data once decompression hasended, call <CODE>bzReadGetUnused</CODE> after the last call of <CODE>bzRead</CODE>(the one returning <CODE>BZ_STREAM_END</CODE>) but before calling<CODE>bzReadClose</CODE>.</UL><P>This mechanism makes it easy to decompress multiple <CODE>bzip2</CODE>streams placed end-to-end. As the end of one stream, when <CODE>bzRead</CODE>returns <CODE>BZ_STREAM_END</CODE>, call <CODE>bzReadGetUnused</CODE> to collect theunused data (copy it into your own buffer somewhere). That data forms the start of the next compressed stream.To start uncompressing that next stream, call <CODE>bzReadOpen</CODE> again,feeding in the unused data via the <CODE>unused</CODE>/<CODE>nUnused</CODE>parameters.Keep doing this until <CODE>BZ_STREAM_END</CODE> return coincides with thephysical end of file (<CODE>feof(f)</CODE>). In this situation<CODE>bzReadGetUnused</CODE>will of course return no data.</P><P>This should give some feel for how the high-level interface can be used.If you require extra flexibility, you'll have to bite the bullet and getto grips with the low-level interface.</P><H3><A NAME="SEC25" HREF="manual_toc.html#TOC25">Standard file-reading/writing code</A></H3><P>Here's how you'd write data to a compressed file:<PRE>FILE* f;BZFILE* b;int nBuf;char buf[ /* whatever size you like */ ];int bzerror;int nWritten;f = fopen ( "myfile.bz2", "w" );if (!f) { /* handle error */}b = bzWriteOpen ( &bzerror, f, 9 );if (bzerror != BZ_OK) { bzWriteClose ( b ); /* handle error */}while ( /* condition */ ) { /* get data to write into buf, and set nBuf appropriately */ nWritten = bzWrite ( &bzerror, b, buf, nBuf ); if (bzerror == BZ_IO_ERROR) { bzWriteClose ( &bzerror, b ); /* handle error */ }}bzWriteClose ( &bzerror, b );if (bzerror == BZ_IO_ERROR) { /* handle error */}</PRE><P>And to read from a compressed file:<PRE>FILE* f;BZFILE* b;int nBuf;char buf[ /* whatever size you like */ ];int bzerror;int nWritten;f = fopen ( "myfile.bz2", "r" );if (!f) { /* handle error */}b = bzReadOpen ( &bzerror, f, 0, NULL, 0 );if (bzerror != BZ_OK) { bzReadClose ( &bzerror, b ); /* handle error */}bzerror = BZ_OK;while (bzerror == BZ_OK && /* arbitrary other conditions */) { nBuf = bzRead ( &bzerror, b, buf, /* size of buf */ ); if (bzerror == BZ_OK) { /* do something with buf[0 .. nBuf-1] */ }}if (bzerror != BZ_STREAM_END) { bzReadClose ( &bzerror, b ); /* handle error */} else { bzReadClose ( &bzerror );}</PRE><H2><A NAME="SEC26" HREF="manual_toc.html#TOC26">Utility functions</A></H2><H3><A NAME="SEC27" HREF="manual_toc.html#TOC27"><CODE>bzBuffToBuffCompress</CODE></A></H3><PRE> int bzBuffToBuffCompress( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int blockSize100k, int verbosity, int workFactor );</PRE><P>Attempts to compress the data in <CODE>source[0 .. sourceLen-1]</CODE>into the destination buffer, <CODE>dest[0 .. *destLen-1]</CODE>.If the destination buffer is big enough, <CODE>*destLen</CODE> isset to the size of the compressed data, and <CODE>BZ_OK</CODE> isreturned. If the compressed data won't fit, <CODE>*destLen</CODE>is unchanged, and <CODE>BZ_OUTBUFF_FULL</CODE> is returned.</P><P>Compression in this manner is a one-shot event, done with a single callto this function. The resulting compressed data is a complete<CODE>bzip2</CODE> format data stream. There is no mechanism for makingadditional calls to provide extra input data. If you want that kind ofmechanism, use the low-level interface.</P><P>For the meaning of parameters <CODE>blockSize100k</CODE>, <CODE>verbosity</CODE>and <CODE>workFactor</CODE>, <BR> see <CODE>bzCompressInit</CODE>.</P><P>To guarantee that the compressed data will fit in its buffer, allocatean output buffer of size 1% larger than the uncompressed data, plussix hundred extra bytes.</P><P><CODE>bzBuffToBuffDecompress</CODE> will not write data at orbeyond <CODE>dest[*destLen]</CODE>, even in case of buffer overflow.</P><P>Possible return values:<PRE> <CODE>BZ_PARAM_ERROR</CODE> if <CODE>dest</CODE> is <CODE>NULL</CODE> or <CODE>destLen</CODE> is <CODE>NULL</CODE> or <CODE>blockSize100k < 1</CODE> or <CODE>blockSize100k > 9</CODE> or <CODE>verbosity < 0</CODE> or <CODE>verbosity > 4</CODE> or <CODE>workFactor < 0</CODE> or <CODE>workFactor > 250</CODE> <CODE>BZ_MEM_ERROR</CODE> if insufficient memory is available <CODE>BZ_OUTBUFF_FULL</CODE> if the size of the compressed data exceeds <CODE>*destLen</CODE> <CODE>BZ_OK</CODE> otherwise</PRE><H3><A NAME="SEC28" HREF="manual_toc.html#TOC28"><CODE>bzBuffToBuffDecompress</CODE></A></H3><PRE> int bzBuffToBuffDecompress ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int small, int verbosity );</PRE><P>Attempts to decompress the data in <CODE>source[0 .. sourceLen-1]</CODE>into the destination buffer, <CODE>dest[0 .. *destLen-1]</CODE>.If the destination buffer is big enough, <CODE>*destLen</CODE> isset to the size of the uncompressed data, and <CODE>BZ_OK</CODE> isreturned. If the compressed data won't fit, <CODE>*destLen</CODE>is unchanged, and <CODE>BZ_OUTBUFF_FULL</CODE> is returned.</P><P><CODE>source</CODE> is assumed to hold a complete <CODE>bzip2</CODE> formatdata stream. <CODE>bzBuffToBuffDecompress</CODE> tries to decompressthe entirety of the stream into the output buffer.</P><P>For the meaning of parameters <CODE>small</CODE> and <CODE>verbosity</CODE>,see <CODE>bzDecompressInit</CODE>.</P><P>Because the compression ratio of the compressed data cannot be known inadvance, there is no easy way to guarantee that the output buffer willbe big enough. You may of course make arrangements in your code torecord the size of the uncompressed data, but such a mechanism is beyondthe scope of this library.</P><P><CODE>bzBuffToBuffDecompress</CODE> will not write data at orbeyond <CODE>dest[*destLen]</CODE>, even in case of buffer overflow.</P><P>Possible return values:<PRE> <CODE>BZ_PARAM_ERROR</CODE> if <CODE>dest</CODE> is <CODE>NULL</CODE> or <CODE>destLen</CODE> is <CODE>NULL</CODE> or <CODE>small != 0 && small != 1</CODE> or <CODE>verbosity < 0</CODE> or <CODE>verbosity > 4</CODE> <CODE>BZ_MEM_ERROR</CODE> if insufficient memory is available <CODE>BZ_OUTBUFF_FULL</CODE> if the size of the compressed data exceeds <CODE>*destLen</CODE> <CODE>BZ_DATA_ERROR</CODE> if a data integrity error was detected in the compressed data <CODE>BZ_DATA_ERROR_MAGIC</CODE> if the compressed data doesn't begin with the right magic bytes <CODE>BZ_UNEXPECTED_EOF</CODE> if the compressed data ends unexpectedly <CODE>BZ_OK</CODE> otherwise</PRE><H2><A NAME="SEC29" HREF="manual_toc.html#TOC29">Using the library in a <CODE>stdio</CODE>-free environment</A></H2><H3><A NAME="SEC30" HREF="manual_toc.html#TOC30">Getting rid of <CODE>stdio</CODE></A></H3><P>In a deeply embedded application, you might want to use justthe memory-to-memory functions. You can do this convenientlyby compiling the library with preprocessor symbol <CODE>BZ_NO_STDIO</CODE>defined. Doing this gives you a library containing only the followingeight functions:</P><P><CODE>bzCompressInit</CODE>, <CODE>bzCompress</CODE>, <CODE>bzCompressEnd</CODE> <BR><CODE>bzDecompressInit</CODE>, <CODE>bzDecompress</CODE>, <CODE>bzDecompressEnd</CODE> <BR><CODE>bzBuffToBuffCompress</CODE>, <CODE>bzBuffToBuffDecompress</CODE></P><P>When compiled like this, all functions will ignore <CODE>verbosity</CODE>settings.</P><H3><A NAME="SEC31" HREF="manual_toc.html#TOC31">Critical error handling</A></H3><P><CODE>libbzip2</CODE> contains a number of internal assertion checks whichshould, needless to say, never be activated. Nevertheless, if anassertion should fail, behaviour depends on whether or not the librarywas compiled with <CODE>BZ_NO_STDIO</CODE> set.</P><P>For a normal compile, an assertion failure yields the message<PRE> bzip2/libbzip2, v0.9.0: internal error number N. This is a bug in bzip2/libbzip2, v0.9.0. Please report it to me at: jseward@acm.org. If this happened when you were using some program which uses libbzip2 as a component, you should also report this bug to the author(s) of that program. Please make an effort to report this bug; timely and accurate bug reports eventually lead to higher quality software. Thx. Julian Seward, 27 June 1998.</PRE><P>where <CODE>N</CODE> is some error code number. <CODE>exit(3)</CODE>is then called.</P><P>For a <CODE>stdio</CODE>-free library, assertion failures resultin a call to a function declared as:<PRE> extern void bz_internal_error ( int errcode );</PRE><P>The relevant code is passed as a parameter. You should supplysuch a function.</P><P>In either case, once an assertion failure has occurred, any <CODE>bz_stream</CODE> records involved can be regarded as invalid.You should not attempt to resume normal operation with them.</P><P>You may, of course, change critical error handling to suityour needs. As I said above, critical errors indicate bugsin the library and should not occur. All "normal" errorsituations are indicated via error return codes from functions,and can be recovered from.</P><H2><A NAME="SEC32" HREF="manual_toc.html#TOC32">Making a Windows DLL</A></H2><P>Everything related to Windows has been contributed by Yoshioka Tsuneo<BR> (<CODE>QWF00133@niftyserve.or.jp</CODE> /<CODE>tsuneo-y@is.aist-nara.ac.jp</CODE>), so you should send your queries tohim (but perhaps Cc: me, <CODE>jseward@acm.org</CODE>).</P><P>My vague understanding of what to do is: using Visual C++ 5.0,open the project file <CODE>libbz2.dsp</CODE>, and build. That's all.</P><P>If you can'topen the project file for some reason, make a new one, naming these files:<CODE>blocksort.c</CODE>, <CODE>bzlib.c</CODE>, <CODE>compress.c</CODE>, <CODE>crctable.c</CODE>, <CODE>decompress.c</CODE>, <CODE>huffman.c</CODE>, <BR><CODE>randtable.c</CODE> and <CODE>libbz2.def</CODE>. You might also needto name the header files <CODE>bzlib.h</CODE> and <CODE>bzlib_private.h</CODE>.</P><P>If you don't use VC++, you may need to define the proprocessor symbol<CODE>_WIN32</CODE>. </P><P>Finally, <CODE>dlltest.c</CODE> is a sample program using the DLL. It has aproject file, <CODE>dlltest.dsp</CODE>.</P><P>I haven't tried any of this stuff myself, but it all looks plausible.</P><P><HR><P>Go to the <A HREF="manual_1.html">first</A>, <A HREF="manual_2.html">previous</A>, <A HREF="manual_4.html">next</A>, <A HREF="manual_4.html">last</A> section, <A HREF="manual_toc.html">table of contents</A>.</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -