DecoderBuffer: use class DynamicFifoBuffer
This commit is contained in:
parent
ea37b89753
commit
a68e52c2e3
@ -21,33 +21,19 @@
|
|||||||
#include "DecoderBuffer.hxx"
|
#include "DecoderBuffer.hxx"
|
||||||
#include "DecoderAPI.hxx"
|
#include "DecoderAPI.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "util/VarSize.hxx"
|
#include "util/DynamicFifoBuffer.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
struct DecoderBuffer {
|
struct DecoderBuffer {
|
||||||
Decoder *decoder;
|
Decoder *decoder;
|
||||||
InputStream *is;
|
InputStream *is;
|
||||||
|
|
||||||
/** the allocated size of the buffer */
|
DynamicFifoBuffer<uint8_t> buffer;
|
||||||
size_t size;
|
|
||||||
|
|
||||||
/** the current length of the buffer */
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
/** number of bytes already consumed at the beginning of the
|
|
||||||
buffer */
|
|
||||||
size_t consumed;
|
|
||||||
|
|
||||||
/** the actual buffer (dynamic size) */
|
|
||||||
unsigned char data[sizeof(size_t)];
|
|
||||||
|
|
||||||
DecoderBuffer(Decoder *_decoder, InputStream &_is,
|
DecoderBuffer(Decoder *_decoder, InputStream &_is,
|
||||||
size_t _size)
|
size_t _size)
|
||||||
:decoder(_decoder), is(&_is),
|
:decoder(_decoder), is(&_is), buffer(_size) {}
|
||||||
size(_size), length(0), consumed(0) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DecoderBuffer *
|
DecoderBuffer *
|
||||||
@ -56,9 +42,7 @@ decoder_buffer_new(Decoder *decoder, InputStream &is,
|
|||||||
{
|
{
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
return NewVarSize<DecoderBuffer>(sizeof(DecoderBuffer::data),
|
return new DecoderBuffer(decoder, is, size);
|
||||||
size,
|
|
||||||
decoder, is, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -66,7 +50,7 @@ decoder_buffer_free(DecoderBuffer *buffer)
|
|||||||
{
|
{
|
||||||
assert(buffer != nullptr);
|
assert(buffer != nullptr);
|
||||||
|
|
||||||
DeleteVarSize(buffer);
|
delete buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputStream &
|
const InputStream &
|
||||||
@ -78,73 +62,48 @@ decoder_buffer_get_stream(const DecoderBuffer *buffer)
|
|||||||
void
|
void
|
||||||
decoder_buffer_clear(DecoderBuffer *buffer)
|
decoder_buffer_clear(DecoderBuffer *buffer)
|
||||||
{
|
{
|
||||||
buffer->length = buffer->consumed = 0;
|
buffer->buffer.Clear();
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
decoder_buffer_shift(DecoderBuffer *buffer)
|
|
||||||
{
|
|
||||||
assert(buffer->consumed > 0);
|
|
||||||
|
|
||||||
buffer->length -= buffer->consumed;
|
|
||||||
memmove(buffer->data, buffer->data + buffer->consumed, buffer->length);
|
|
||||||
buffer->consumed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
decoder_buffer_fill(DecoderBuffer *buffer)
|
decoder_buffer_fill(DecoderBuffer *buffer)
|
||||||
{
|
{
|
||||||
size_t nbytes;
|
auto w = buffer->buffer.Write();
|
||||||
|
if (w.IsEmpty())
|
||||||
if (buffer->consumed > 0)
|
|
||||||
decoder_buffer_shift(buffer);
|
|
||||||
|
|
||||||
if (buffer->length >= buffer->size)
|
|
||||||
/* buffer is full */
|
/* buffer is full */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nbytes = decoder_read(buffer->decoder, *buffer->is,
|
size_t nbytes = decoder_read(buffer->decoder, *buffer->is,
|
||||||
buffer->data + buffer->length,
|
w.data, w.size);
|
||||||
buffer->size - buffer->length);
|
|
||||||
if (nbytes == 0)
|
if (nbytes == 0)
|
||||||
/* end of file, I/O error or decoder command
|
/* end of file, I/O error or decoder command
|
||||||
received */
|
received */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
buffer->length += nbytes;
|
buffer->buffer.Append(nbytes);
|
||||||
assert(buffer->length <= buffer->size);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void *
|
|
||||||
decoder_buffer_head(const DecoderBuffer *buffer)
|
|
||||||
{
|
|
||||||
return buffer->data + buffer->consumed;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
decoder_buffer_available(const DecoderBuffer *buffer)
|
decoder_buffer_available(const DecoderBuffer *buffer)
|
||||||
{
|
{
|
||||||
return buffer->length - buffer->consumed;
|
return buffer->buffer.GetAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
ConstBuffer<void>
|
||||||
decoder_buffer_read(const DecoderBuffer *buffer)
|
decoder_buffer_read(const DecoderBuffer *buffer)
|
||||||
{
|
{
|
||||||
return {
|
auto r = buffer->buffer.Read();
|
||||||
decoder_buffer_head(buffer),
|
return { r.data, r.size };
|
||||||
decoder_buffer_available(buffer),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
ConstBuffer<void>
|
||||||
decoder_buffer_need(DecoderBuffer *buffer, size_t min_size)
|
decoder_buffer_need(DecoderBuffer *buffer, size_t min_size)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
const auto available = decoder_buffer_available(buffer);
|
const auto r = decoder_buffer_read(buffer);
|
||||||
if (available >= min_size)
|
if (r.size >= min_size)
|
||||||
return { decoder_buffer_head(buffer), available };
|
return r;
|
||||||
|
|
||||||
if (!decoder_buffer_fill(buffer))
|
if (!decoder_buffer_fill(buffer))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -154,25 +113,20 @@ decoder_buffer_need(DecoderBuffer *buffer, size_t min_size)
|
|||||||
void
|
void
|
||||||
decoder_buffer_consume(DecoderBuffer *buffer, size_t nbytes)
|
decoder_buffer_consume(DecoderBuffer *buffer, size_t nbytes)
|
||||||
{
|
{
|
||||||
/* just move the "consumed" pointer - decoder_buffer_shift()
|
buffer->buffer.Consume(nbytes);
|
||||||
will do the real work later (called by
|
|
||||||
decoder_buffer_fill()) */
|
|
||||||
buffer->consumed += nbytes;
|
|
||||||
|
|
||||||
assert(buffer->consumed <= buffer->length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
decoder_buffer_skip(DecoderBuffer *buffer, size_t nbytes)
|
decoder_buffer_skip(DecoderBuffer *buffer, size_t nbytes)
|
||||||
{
|
{
|
||||||
const size_t available = decoder_buffer_available(buffer);
|
const auto r = buffer->buffer.Read();
|
||||||
if (available >= nbytes) {
|
if (r.size >= nbytes) {
|
||||||
decoder_buffer_consume(buffer, nbytes);
|
buffer->buffer.Consume(nbytes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder_buffer_clear(buffer);
|
buffer->buffer.Clear();
|
||||||
nbytes -= available;
|
nbytes -= r.size;
|
||||||
|
|
||||||
return decoder_skip(buffer->decoder, *buffer->is, nbytes);
|
return decoder_skip(buffer->decoder, *buffer->is, nbytes);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user