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 }