Botan  1.11.15
src/lib/compression/bzip2/bzip2.cpp
Go to the documentation of this file.
00001 /*
00002 * Bzip2 Compressor
00003 * (C) 2001 Peter J Jones
00004 *     2001-2007,2014 Jack Lloyd
00005 *     2006 Matt Johnston
00006 *
00007 * Botan is released under the Simplified BSD License (see license.txt)
00008 */
00009 
00010 #include <botan/bzip2.h>
00011 #include <botan/internal/compress_utils.h>
00012 
00013 #define BZ_NO_STDIO
00014 #include <bzlib.h>
00015 
00016 namespace Botan {
00017 
00018 BOTAN_REGISTER_COMPRESSION(Bzip2_Compression, Bzip2_Decompression);
00019 
00020 namespace {
00021 
00022 class Bzip2_Stream : public Zlib_Style_Stream<bz_stream, char>
00023    {
00024    public:
00025       Bzip2_Stream()
00026          {
00027          streamp()->opaque = alloc();
00028          streamp()->bzalloc = Compression_Alloc_Info::malloc<int>;
00029          streamp()->bzfree = Compression_Alloc_Info::free;
00030          }
00031 
00032       u32bit run_flag() const override { return BZ_RUN; }
00033       u32bit flush_flag() const override { return BZ_FLUSH; }
00034       u32bit finish_flag() const override { return BZ_FINISH; }
00035    };
00036 
00037 class Bzip2_Compression_Stream : public Bzip2_Stream
00038    {
00039    public:
00040       Bzip2_Compression_Stream(size_t block_size)
00041          {
00042          int rc = BZ2_bzCompressInit(streamp(), block_size, 0, 0);
00043 
00044          if(rc == BZ_MEM_ERROR)
00045             throw std::bad_alloc();
00046          else if(rc != BZ_OK)
00047             throw std::runtime_error("bzip compress initialization failed");
00048          }
00049 
00050       ~Bzip2_Compression_Stream()
00051          {
00052          BZ2_bzCompressEnd(streamp());
00053          }
00054 
00055       bool run(u32bit flags) override
00056          {
00057          int rc = BZ2_bzCompress(streamp(), flags);
00058 
00059          if(rc == BZ_MEM_ERROR)
00060             throw std::bad_alloc();
00061          else if(rc < 0)
00062             throw std::runtime_error("bzip compress error");
00063 
00064          return (rc == BZ_STREAM_END);
00065          }
00066    };
00067 
00068 class Bzip2_Decompression_Stream : public Bzip2_Stream
00069    {
00070    public:
00071       Bzip2_Decompression_Stream()
00072          {
00073          int rc = BZ2_bzDecompressInit(streamp(), 0, 0);
00074 
00075          if(rc == BZ_MEM_ERROR)
00076             throw std::bad_alloc();
00077          else if(rc != BZ_OK)
00078             throw std::runtime_error("bzip decompress initialization failed");
00079          }
00080 
00081       ~Bzip2_Decompression_Stream()
00082          {
00083          BZ2_bzDecompressEnd(streamp());
00084          }
00085 
00086       bool run(u32bit) override
00087          {
00088          int rc = BZ2_bzDecompress(streamp());
00089 
00090          if(rc == BZ_MEM_ERROR)
00091             throw std::bad_alloc();
00092          else if(rc != BZ_OK && rc != BZ_STREAM_END)
00093             throw std::runtime_error("bzip decompress error");
00094 
00095          return (rc == BZ_STREAM_END);
00096          }
00097    };
00098 
00099 }
00100 
00101 Compression_Stream* Bzip2_Compression::make_stream() const
00102    {
00103    return new Bzip2_Compression_Stream(m_block_size);
00104    }
00105 
00106 Compression_Stream* Bzip2_Decompression::make_stream() const
00107    {
00108    return new Bzip2_Decompression_Stream;
00109    }
00110 
00111 }