1 /** 2 * Bzip Compressor 3 * 4 * Copyright: 5 * (C) 2001 Peter J Jones 6 * 2001-2007 Jack Lloyd 7 * (C) 2014-2015 Etienne Cimon 8 * 9 * License: 10 * Botan is released under the Simplified BSD License (see LICENSE.md) 11 */ 12 module botan.compression.bzip2; 13 14 import botan.constants; 15 static if (BOTAN_HAS_BZIP2): 16 17 import botan.utils.exceptn; 18 import botan.compression.bzip2_hd; 19 import botan.compression.compress; 20 import std.exception; 21 import botan.algo_base.transform; 22 import botan.utils.types; 23 import core.exception; 24 25 /** 26 * Bzip2 Compression 27 */ 28 class Bzip2Compression : StreamCompression, Transformation 29 { 30 public: 31 /** 32 * @param block_size in 1024 KiB increments, in range from 1 to 9. 33 * 34 * Lowering this does not noticably modify the compression or 35 * decompression speed, though less memory is required for both 36 * compression and decompression. 37 */ 38 this(size_t block_size = 9) 39 { 40 m_block_size = block_size; 41 42 } 43 44 override string name() const { return "Bzip2Compression"; } 45 46 protected: 47 override CompressionStream makeStream() const 48 { 49 return new Bzip2CompressionStream(m_block_size); 50 } 51 52 const size_t m_block_size; 53 // interface fall-through 54 override void flush(ref SecureVector!ubyte buf, size_t offset) { super.flush(buf, offset); } 55 override string provider() const { return "core"; } 56 override size_t updateGranularity() const { return 1; } 57 override size_t minimumFinalSize() const { return 0; } 58 override size_t defaultNonceLength() const { return 0; } 59 override bool validNonceLength(size_t nonce_len) const { return nonce_len == 0; } 60 override SecureVector!ubyte startRaw(const(ubyte)* data, size_t data_len) { return super.startRaw(data, data_len); } 61 override void update(ref SecureVector!ubyte buf, size_t offset) { super.update(buf, offset); } 62 override void finish(ref SecureVector!ubyte buf, size_t offset) { super.finish(buf, offset); } 63 override size_t outputLength(size_t input_length) const { return super.outputLength(input_length); } 64 override void clear() { return super.clear(); } 65 } 66 67 /** 68 * Bzip2 Deccompression 69 */ 70 class Bzip2Decompression : StreamDecompression, Transformation 71 { 72 public: 73 override string name() const { return "Bzip2Decompression"; } 74 protected: 75 override CompressionStream makeStream() const 76 { 77 return new Bzip2DecompressionStream; 78 } 79 80 // interface fall-through 81 override void flush(ref SecureVector!ubyte buf, size_t offset) { super.flush(buf, offset); } 82 override string provider() const { return "core"; } 83 override size_t updateGranularity() const { return 1; } 84 override size_t minimumFinalSize() const { return 0; } 85 override size_t defaultNonceLength() const { return 0; } 86 override bool validNonceLength(size_t nonce_len) const { return nonce_len == 0; } 87 override SecureVector!ubyte startRaw(const(ubyte)* data, size_t data_len) { return super.startRaw(data, data_len); } 88 override void update(ref SecureVector!ubyte buf, size_t offset) { super.update(buf, offset); } 89 override void finish(ref SecureVector!ubyte buf, size_t offset) { super.finish(buf, offset); } 90 override size_t outputLength(size_t input_length) const { return super.outputLength(input_length); } 91 override void clear() { return super.clear(); } 92 } 93 94 95 class Bzip2Stream : ZlibStyleStream!(bz_stream, ubyte), CompressionStream 96 { 97 public: 98 this() 99 { 100 streamp().opaque = cast(void*)alloc(); 101 streamp().bzalloc = &CompressionAllocInfo.malloc!int; 102 streamp().bzfree = &CompressionAllocInfo.free; 103 } 104 105 override uint runFlag() const { return BZ_RUN; } 106 override uint flushFlag() const { return BZ_FLUSH; } 107 override uint finishFlag() const { return BZ_FINISH; } 108 109 override bool run(uint flags) { return false; } 110 override void nextIn(ubyte* b, size_t len) { super.nextIn(b, len); } 111 override void nextOut(ubyte* b, size_t len) { super.nextOut(b, len); } 112 override size_t availIn() const { return super.availIn(); } 113 override size_t availOut() const { return super.availOut; } 114 } 115 116 class Bzip2CompressionStream : Bzip2Stream, CompressionStream 117 { 118 public: 119 this(size_t block_size) 120 { 121 int rc = BZ2_bzCompressInit(streamp(), cast(int)block_size, 0, 0); 122 123 if (rc == BZ_MEM_ERROR) 124 throw new InvalidMemoryOperationError(); 125 else if (rc != BZ_OK) 126 throw new Exception("bzip compress initialization failed"); 127 } 128 129 ~this() 130 { 131 BZ2_bzCompressEnd(streamp()); 132 } 133 134 override bool run(uint flags) 135 { 136 int rc = BZ2_bzCompress(streamp(), flags); 137 138 if (rc == BZ_MEM_ERROR) 139 throw new InvalidMemoryOperationError(); 140 else if (rc < 0) 141 throw new Exception("bzip compress error"); 142 143 return (rc == BZ_STREAM_END); 144 } 145 146 override void nextIn(ubyte* b, size_t len) { super.nextIn(b, len); } 147 override void nextOut(ubyte* b, size_t len) { super.nextOut(b, len); } 148 override size_t availIn() const { return super.availIn(); } 149 override size_t availOut() const { return super.availOut; } 150 override uint runFlag() const { return super.runFlag(); } 151 override uint flushFlag() const { return super.flushFlag(); } 152 override uint finishFlag() const { return super.finishFlag(); } 153 } 154 155 class Bzip2DecompressionStream : Bzip2Stream, CompressionStream 156 { 157 public: 158 this() 159 { 160 int rc = BZ2_bzDecompressInit(streamp(), 0, 0); 161 162 if (rc == BZ_MEM_ERROR) 163 throw new InvalidMemoryOperationError(); 164 else if (rc != BZ_OK) 165 throw new Exception("bzip decompress initialization failed"); 166 } 167 168 ~this() 169 { 170 BZ2_bzDecompressEnd(streamp()); 171 } 172 173 override bool run(uint) 174 { 175 int rc = BZ2_bzDecompress(streamp()); 176 177 if (rc == BZ_MEM_ERROR) 178 throw new InvalidMemoryOperationError(); 179 else if (rc != BZ_OK && rc != BZ_STREAM_END) 180 throw new Exception("bzip decompress error"); 181 182 return (rc == BZ_STREAM_END); 183 } 184 185 override void nextIn(ubyte* b, size_t len) { super.nextIn(b, len); } 186 override void nextOut(ubyte* b, size_t len) { super.nextOut(b, len); } 187 override size_t availIn() const { return super.availIn(); } 188 override size_t availOut() const { return super.availOut; } 189 override uint runFlag() const { return super.runFlag(); } 190 override uint flushFlag() const { return super.flushFlag(); } 191 override uint finishFlag() const { return super.finishFlag(); } 192 }