2 * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include <CompressionAlgorithm.h>
15 // #pragma mark - BCompressionParameters
18 BCompressionParameters::BCompressionParameters()
23 BCompressionParameters::~BCompressionParameters()
28 // #pragma mark - BDecompressionParameters
31 BDecompressionParameters::BDecompressionParameters()
36 BDecompressionParameters::~BDecompressionParameters()
41 // #pragma mark - BCompressionAlgorithm
44 BCompressionAlgorithm::BCompressionAlgorithm()
49 BCompressionAlgorithm::~BCompressionAlgorithm()
55 BCompressionAlgorithm::CreateCompressingInputStream(BDataIO
* input
,
56 const BCompressionParameters
* parameters
, BDataIO
*& _stream
)
58 return B_NOT_SUPPORTED
;
63 BCompressionAlgorithm::CreateCompressingOutputStream(BDataIO
* output
,
64 const BCompressionParameters
* parameters
, BDataIO
*& _stream
)
66 return B_NOT_SUPPORTED
;
71 BCompressionAlgorithm::CreateDecompressingInputStream(BDataIO
* input
,
72 const BDecompressionParameters
* parameters
, BDataIO
*& _stream
)
74 return B_NOT_SUPPORTED
;
79 BCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO
* output
,
80 const BDecompressionParameters
* parameters
, BDataIO
*& _stream
)
82 return B_NOT_SUPPORTED
;
87 BCompressionAlgorithm::CompressBuffer(const void* input
, size_t inputSize
,
88 void* output
, size_t outputSize
, size_t& _compressedSize
,
89 const BCompressionParameters
* parameters
)
91 return B_NOT_SUPPORTED
;
96 BCompressionAlgorithm::DecompressBuffer(const void* input
,
97 size_t inputSize
, void* output
, size_t outputSize
,
98 size_t& _uncompressedSize
, const BDecompressionParameters
* parameters
)
100 return B_NOT_SUPPORTED
;
104 // #pragma mark - BAbstractStream
107 BCompressionAlgorithm::BAbstractStream::BAbstractStream()
118 BCompressionAlgorithm::BAbstractStream::~BAbstractStream()
125 BCompressionAlgorithm::BAbstractStream::Init(size_t bufferSize
)
127 fBuffer
= (uint8
*)malloc(bufferSize
);
128 fBufferCapacity
= bufferSize
;
130 return fBuffer
!= NULL
? B_OK
: B_NO_MEMORY
;
134 // #pragma mark - BAbstractInputStream
137 BCompressionAlgorithm::BAbstractInputStream::BAbstractInputStream(
143 fNoMorePendingData(false)
148 BCompressionAlgorithm::BAbstractInputStream::~BAbstractInputStream()
154 BCompressionAlgorithm::BAbstractInputStream::Read(void* buffer
, size_t size
)
159 size_t bytesRemaining
= size
;
160 uint8
* output
= (uint8
*)buffer
;
162 while (bytesRemaining
> 0) {
163 // process the data still in the input buffer
164 if (fBufferSize
> 0) {
165 size_t bytesConsumed
;
166 size_t bytesProduced
;
167 status_t error
= ProcessData(fBuffer
+ fBufferOffset
, fBufferSize
,
168 output
, bytesRemaining
, bytesConsumed
, bytesProduced
);
172 fBufferOffset
+= bytesConsumed
;
173 fBufferSize
-= bytesConsumed
;
174 output
+= bytesProduced
;
175 bytesRemaining
-= bytesProduced
;
179 // We couldn't process anything, because we don't have any or not enough
180 // bytes in the input buffer.
185 // Move any remaining data to the start of the buffer.
186 if (fBufferSize
> 0) {
187 if (fBufferSize
== fBufferCapacity
)
190 if (fBufferOffset
> 0)
191 memmove(fBuffer
, fBuffer
+ fBufferOffset
, fBufferSize
);
196 // read from the source
197 ssize_t bytesRead
= fInput
->Read(fBuffer
+ fBufferSize
,
198 fBufferCapacity
- fBufferSize
);
201 if (bytesRead
== 0) {
206 fBufferSize
+= bytesRead
;
209 // If we've reached the end of the input and still have room in the output
210 // buffer, we have consumed all input data and want to flush all pending
212 if (fEndOfInput
&& bytesRemaining
> 0 && !fNoMorePendingData
) {
213 size_t bytesProduced
;
214 status_t error
= FlushPendingData(output
, bytesRemaining
,
219 if (bytesProduced
< bytesRemaining
)
220 fNoMorePendingData
= true;
222 output
+= bytesProduced
;
223 bytesRemaining
-= bytesProduced
;
226 return size
- bytesRemaining
;
230 // #pragma mark - BAbstractOutputStream
233 BCompressionAlgorithm::BAbstractOutputStream::BAbstractOutputStream(
242 BCompressionAlgorithm::BAbstractOutputStream::~BAbstractOutputStream()
248 BCompressionAlgorithm::BAbstractOutputStream::Write(const void* buffer
,
254 size_t bytesRemaining
= size
;
255 uint8
* input
= (uint8
*)buffer
;
257 while (bytesRemaining
> 0) {
258 // try to process more data
259 if (fBufferSize
< fBufferCapacity
) {
260 size_t bytesConsumed
;
261 size_t bytesProduced
;
262 status_t error
= ProcessData(input
, bytesRemaining
,
263 fBuffer
+ fBufferSize
, fBufferCapacity
- fBufferSize
,
264 bytesConsumed
, bytesProduced
);
268 input
+= bytesConsumed
;
269 bytesRemaining
-= bytesConsumed
;
270 fBufferSize
+= bytesProduced
;
274 // We couldn't process anything, because we don't have any or not enough
275 // room in the output buffer.
277 if (fBufferSize
== 0)
280 // write to the target
281 ssize_t bytesWritten
= fOutput
->Write(fBuffer
, fBufferSize
);
282 if (bytesWritten
< 0)
284 if (bytesWritten
== 0)
287 // Move any remaining data to the start of the buffer.
288 fBufferSize
-= bytesWritten
;
290 memmove(fBuffer
, fBuffer
+ bytesWritten
, fBufferSize
);
293 return size
- bytesRemaining
;
298 BCompressionAlgorithm::BAbstractOutputStream::Flush()
300 bool noMorePendingData
= false;
303 // let the derived class flush all pending data
304 if (fBufferSize
< fBufferCapacity
&& !noMorePendingData
) {
305 size_t bytesProduced
;
306 status_t error
= FlushPendingData(fBuffer
+ fBufferSize
,
307 fBufferCapacity
- fBufferSize
, bytesProduced
);
311 noMorePendingData
= bytesProduced
< fBufferCapacity
- fBufferSize
;
313 fBufferSize
+= bytesProduced
;
316 // write buffered data to output
317 if (fBufferSize
== 0)
320 status_t error
= fOutput
->WriteExactly(fBuffer
, fBufferSize
);
327 return fOutput
->Flush();