2010-02-08 17:23:39 +01:00
|
|
|
/* Copyright (c) 2010 Wildfire Games
|
2009-04-18 19:00:33 +02:00
|
|
|
*
|
2010-02-08 17:23:39 +01:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2009-04-18 19:00:33 +02:00
|
|
|
*/
|
|
|
|
|
2009-04-18 19:51:05 +02:00
|
|
|
/*
|
2009-05-03 13:47:38 +02:00
|
|
|
* output buffer and 'stream' layered on top of a compression codec
|
2009-04-18 18:14:48 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef INCLUDED_STREAM
|
|
|
|
#define INCLUDED_STREAM
|
|
|
|
|
2010-03-01 15:52:58 +01:00
|
|
|
#include "lib/file/archive/codec.h"
|
2009-04-18 18:14:48 +02:00
|
|
|
|
|
|
|
// note: this is similar in function to std::vector, but we don't need
|
|
|
|
// iterators etc. and would prefer to avoid initializing each byte.
|
|
|
|
class OutputBufferManager
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OutputBufferManager();
|
|
|
|
|
|
|
|
void Reset();
|
|
|
|
void SetBuffer(u8* buffer, size_t size);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* allocate a new output buffer.
|
|
|
|
*
|
|
|
|
* @param size [bytes] to allocate.
|
|
|
|
*
|
|
|
|
* notes:
|
|
|
|
* - if a buffer had previously been allocated and is large enough,
|
|
|
|
* it is reused (this reduces the number of allocations).
|
|
|
|
* - this class manages the lifetime of the buffer.
|
|
|
|
**/
|
|
|
|
void AllocateBuffer(size_t size);
|
|
|
|
|
|
|
|
u8* Buffer() const
|
|
|
|
{
|
|
|
|
return m_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Size() const
|
|
|
|
{
|
|
|
|
return m_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool IsAllowableBuffer(u8* buffer, size_t size);
|
|
|
|
|
|
|
|
u8* m_buffer;
|
|
|
|
size_t m_size;
|
|
|
|
|
|
|
|
shared_ptr<u8> m_mem;
|
|
|
|
// size of m_mem. allows reusing previously allocated buffers
|
|
|
|
// (user-specified buffers can't be reused because we have no control
|
|
|
|
// over their lifetime)
|
|
|
|
size_t m_capacity;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Stream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Stream(const PICodec& codec);
|
|
|
|
|
|
|
|
void SetOutputBuffer(u8* out, size_t outSize);
|
|
|
|
|
|
|
|
void AllocateOutputBuffer(size_t outSizeMax);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 'feed' the codec with a data block.
|
|
|
|
**/
|
2011-05-03 14:38:42 +02:00
|
|
|
Status Feed(const u8* in, size_t inSize);
|
2009-04-18 18:14:48 +02:00
|
|
|
|
2011-05-03 14:38:42 +02:00
|
|
|
Status Finish();
|
2009-04-18 18:14:48 +02:00
|
|
|
|
|
|
|
size_t OutSize() const
|
|
|
|
{
|
|
|
|
return m_outProduced;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 Checksum() const
|
|
|
|
{
|
|
|
|
return m_checksum;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PICodec m_codec;
|
|
|
|
OutputBufferManager m_outputBufferManager;
|
|
|
|
|
|
|
|
size_t m_inConsumed;
|
|
|
|
size_t m_outProduced;
|
|
|
|
u32 m_checksum;
|
|
|
|
};
|
|
|
|
|
2011-04-30 00:55:35 +02:00
|
|
|
// avoids the need for std::bind (not supported on all compilers) and boost::bind (can't be
|
|
|
|
// used at work)
|
|
|
|
struct StreamFeeder
|
|
|
|
{
|
|
|
|
NONCOPYABLE(StreamFeeder);
|
|
|
|
public:
|
|
|
|
StreamFeeder(Stream& stream)
|
|
|
|
: stream(stream)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-05-03 14:38:42 +02:00
|
|
|
Status operator()(const u8* data, size_t size) const
|
2011-04-30 00:55:35 +02:00
|
|
|
{
|
|
|
|
return stream.Feed(data, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Stream& stream;
|
|
|
|
};
|
|
|
|
|
2009-04-18 18:14:48 +02:00
|
|
|
#endif // #ifndef INCLUDED_STREAM
|