HaikuDepot: notify work status from main window
[haiku.git] / src / kits / support / CompressionAlgorithm.cpp
blobab7eb2cfffaf6efb101cf63ac93b4ebd7f89dcf6
1 /*
2 * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <CompressionAlgorithm.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include <Errors.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()
54 status_t
55 BCompressionAlgorithm::CreateCompressingInputStream(BDataIO* input,
56 const BCompressionParameters* parameters, BDataIO*& _stream)
58 return B_NOT_SUPPORTED;
62 status_t
63 BCompressionAlgorithm::CreateCompressingOutputStream(BDataIO* output,
64 const BCompressionParameters* parameters, BDataIO*& _stream)
66 return B_NOT_SUPPORTED;
70 status_t
71 BCompressionAlgorithm::CreateDecompressingInputStream(BDataIO* input,
72 const BDecompressionParameters* parameters, BDataIO*& _stream)
74 return B_NOT_SUPPORTED;
78 status_t
79 BCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO* output,
80 const BDecompressionParameters* parameters, BDataIO*& _stream)
82 return B_NOT_SUPPORTED;
86 status_t
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;
95 status_t
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()
109 BDataIO(),
110 fBuffer(NULL),
111 fBufferCapacity(0),
112 fBufferOffset(0),
113 fBufferSize(0)
118 BCompressionAlgorithm::BAbstractStream::~BAbstractStream()
120 free(fBuffer);
124 status_t
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(
138 BDataIO* input)
140 BAbstractStream(),
141 fInput(input),
142 fEndOfInput(false),
143 fNoMorePendingData(false)
148 BCompressionAlgorithm::BAbstractInputStream::~BAbstractInputStream()
153 ssize_t
154 BCompressionAlgorithm::BAbstractInputStream::Read(void* buffer, size_t size)
156 if (size == 0)
157 return 0;
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);
169 if (error != B_OK)
170 return error;
172 fBufferOffset += bytesConsumed;
173 fBufferSize -= bytesConsumed;
174 output += bytesProduced;
175 bytesRemaining -= bytesProduced;
176 continue;
179 // We couldn't process anything, because we don't have any or not enough
180 // bytes in the input buffer.
182 if (fEndOfInput)
183 break;
185 // Move any remaining data to the start of the buffer.
186 if (fBufferSize > 0) {
187 if (fBufferSize == fBufferCapacity)
188 return B_ERROR;
190 if (fBufferOffset > 0)
191 memmove(fBuffer, fBuffer + fBufferOffset, fBufferSize);
194 fBufferOffset = 0;
196 // read from the source
197 ssize_t bytesRead = fInput->Read(fBuffer + fBufferSize,
198 fBufferCapacity - fBufferSize);
199 if (bytesRead < 0)
200 return bytesRead;
201 if (bytesRead == 0) {
202 fEndOfInput = true;
203 break;
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
211 // data, now.
212 if (fEndOfInput && bytesRemaining > 0 && !fNoMorePendingData) {
213 size_t bytesProduced;
214 status_t error = FlushPendingData(output, bytesRemaining,
215 bytesProduced);
216 if (error != B_OK)
217 return error;
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(
234 BDataIO* output)
236 BAbstractStream(),
237 fOutput(output)
242 BCompressionAlgorithm::BAbstractOutputStream::~BAbstractOutputStream()
247 ssize_t
248 BCompressionAlgorithm::BAbstractOutputStream::Write(const void* buffer,
249 size_t size)
251 if (size == 0)
252 return 0;
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);
265 if (error != B_OK)
266 return error;
268 input += bytesConsumed;
269 bytesRemaining -= bytesConsumed;
270 fBufferSize += bytesProduced;
271 continue;
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)
278 return B_ERROR;
280 // write to the target
281 ssize_t bytesWritten = fOutput->Write(fBuffer, fBufferSize);
282 if (bytesWritten < 0)
283 return bytesWritten;
284 if (bytesWritten == 0)
285 break;
287 // Move any remaining data to the start of the buffer.
288 fBufferSize -= bytesWritten;
289 if (fBufferSize > 0)
290 memmove(fBuffer, fBuffer + bytesWritten, fBufferSize);
293 return size - bytesRemaining;
297 status_t
298 BCompressionAlgorithm::BAbstractOutputStream::Flush()
300 bool noMorePendingData = false;
302 for (;;) {
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);
308 if (error != B_OK)
309 return error;
311 noMorePendingData = bytesProduced < fBufferCapacity - fBufferSize;
313 fBufferSize += bytesProduced;
316 // write buffered data to output
317 if (fBufferSize == 0)
318 break;
320 status_t error = fOutput->WriteExactly(fBuffer, fBufferSize);
321 if (error != B_OK)
322 return error;
324 fBufferSize = 0;
327 return fOutput->Flush();