Skip to content
Snippets Groups Projects
Commit 1fb8bc46 authored by Vojtěch Moravec's avatar Vojtěch Moravec
Browse files

Fixed assertion bug.

parent 2b60dd77
No related branches found
No related tags found
No related merge requests found
#include "buffered_binary_stream.h"
BufferedBinaryStream::BufferedBinaryStream()
{
this->isOpen = false;
this->underlayingSourceType = BufferSourceType_NoSource;
}
BufferedBinaryStream::BufferedBinaryStream(ByteArray *bytes)
{
this->isOpen = true;
this->underlayingSourceType = BufferSourceType_Memory;
this->memoryBuffer = bytes;
this->currentBufferPosition = 0;
}
BufferedBinaryStream::BufferedBinaryStream(BinaryStreamBase *stream, const long streamBufferSize)
{
this->isOpen = stream->is_open();
this->underlayingSourceType = BufferSourceType_Stream;
this->streamBufferSize = streamBufferSize;
this->underlayingStream = stream;
this->currentBufferPosition = 0;
}
BufferedBinaryStream::~BufferedBinaryStream()
{
// Do we want to close stream / clear buffer?
// Probably not, because someone may want to use them later.
/*
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->buffer.clear();
}
break;
case BufferSourceType_Stream:
{
this->underlayingStream->close_stream();
}
break;
}
*/
}
long BufferedBinaryStream::get_size() const
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
return this->memoryBuffer->size();
}
break;
case BufferSourceType_Stream:
{
return this->underlayingStream->get_size();
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
long BufferedBinaryStream::get_position()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
return this->currentBufferPosition;
}
break;
case BufferSourceType_Stream:
{
always_assert(this->currentBufferPosition <= this->streamBufferSize);
long pos = (this->readedFromSource > 0) ? this->readedFromSource - (this->streamBufferSize - this->currentBufferPosition) : 0;
return pos;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
ulong BufferedBinaryStream::get_consume_size()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
always_assert(false && "This shouldn't be called ever.");
return 0;
}
break;
case BufferSourceType_Stream:
{
long totalSize = get_size();
ulong currPos = this->underlayingStream->get_position();
ulong avaible = totalSize - currPos;
ulong toConsume = (avaible > this->streamBufferSize) ? this->streamBufferSize : avaible;
return toConsume;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
void BufferedBinaryStream::move_to(const long position)
{
always_assert(position < get_size());
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->currentBufferPosition = position;
}
break;
case BufferSourceType_Stream:
{
// move_to will always reload the buffer.
this->underlayingStream->move_to(position);
ulong toConsume = get_consume_size();
this->streamBuffer = this->underlayingStream->consume_bytes(toConsume);
this->readedFromSource = this->underlayingStream->get_position();
// Just for sure.
//always_assert(this->readedFromSource == position + this->streamBufferSize);
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_to_beginning()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->currentBufferPosition = 0;
}
break;
case BufferSourceType_Stream:
{
// move_to_beginning will always reload the buffer.
this->underlayingStream->move_to_beginning();
this->streamBuffer = this->underlayingStream->consume_bytes(get_consume_size());
this->readedFromSource = this->streamBufferSize;
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_to_end()
{
this->currentBufferPosition = get_size();
switch (this->underlayingSourceType)
{
case BufferSourceType_Stream:
{
// move_to_beginning will always clear the buffer.
this->streamBuffer.clear();
this->readedFromSource = this->currentBufferPosition;
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_by(const long distance)
{
always_assert((get_position() + distance) < get_size());
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
always_assert((this->currentBufferPosition + distance) < this->memoryBuffer->size());
this->currentBufferPosition += distance;
}
break;
case BufferSourceType_Stream:
{
// If atleast one byte can be read, just advance the buffer position.
if ((this->currentBufferPosition + distance + 1) < this->streamBufferSize)
{
this->currentBufferPosition += distance;
}
else
{
// If we are moving outside buffer, reload the buffer from desired location.
long currentPosInStreamRelativeToBufferPos = get_position();
always_assert((currentPosInStreamRelativeToBufferPos + distance) < this->underlayingStream->get_size());
this->underlayingStream->move_to((currentPosInStreamRelativeToBufferPos + distance));
ulong toConsume = get_consume_size();
this->streamBuffer = this->underlayingStream->consume_bytes(toConsume);
this->readedFromSource = this->underlayingStream->get_position();
this->currentBufferPosition = 0;
}
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
ByteArray BufferedBinaryStream::consume_bytes(const ulong byteCount)
{
if (this->streamBufferSize < byteCount)
{
printf(RED "To parse this file, you need buffer of size atleast: %lu\n" RESET, byteCount);
}
// We won't allow consuming more bytes than is buffer size.
always_assert(byteCount <= this->streamBufferSize && "Buffer is too small.");
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
// Check how many bytes are avaible in memory buffer.
ulong bytesAvaible = this->memoryBuffer->size() - this->currentBufferPosition;
always_assert(bytesAvaible <= byteCount);
auto fromIt = this->memoryBuffer->begin() + this->currentBufferPosition;
auto toIt = fromIt + byteCount;
this->currentBufferPosition += byteCount;
ByteArray result(fromIt, toIt);
return result;
}
break;
case BufferSourceType_Stream:
{
ulong bytesAvaible = this->streamBuffer.size() - this->currentBufferPosition;
if ((bytesAvaible == 0) || (byteCount > bytesAvaible))
{
long currentPos = get_position();
// Moving to current position will ensure, that streamBufferSize of data will be read into buffer.
move_to(currentPos);
}
auto fromIt = this->streamBuffer.begin() + this->currentBufferPosition;
auto toIt = fromIt + byteCount;
this->currentBufferPosition += byteCount;
ByteArray result(fromIt, toIt);
return result;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return ByteArray();
#include "buffered_binary_stream.h"
BufferedBinaryStream::BufferedBinaryStream()
{
this->isOpen = false;
this->underlayingSourceType = BufferSourceType_NoSource;
}
BufferedBinaryStream::BufferedBinaryStream(ByteArray *bytes)
{
this->isOpen = true;
this->underlayingSourceType = BufferSourceType_Memory;
this->memoryBuffer = bytes;
this->currentBufferPosition = 0;
}
BufferedBinaryStream::BufferedBinaryStream(BinaryStreamBase *stream, const long streamBufferSize)
{
this->isOpen = stream->is_open();
this->underlayingSourceType = BufferSourceType_Stream;
this->streamBufferSize = streamBufferSize;
this->underlayingStream = stream;
this->currentBufferPosition = 0;
}
BufferedBinaryStream::~BufferedBinaryStream()
{
// Do we want to close stream / clear buffer?
// Probably not, because someone may want to use them later.
/*
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->buffer.clear();
}
break;
case BufferSourceType_Stream:
{
this->underlayingStream->close_stream();
}
break;
}
*/
}
long BufferedBinaryStream::get_size() const
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
return this->memoryBuffer->size();
}
break;
case BufferSourceType_Stream:
{
return this->underlayingStream->get_size();
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
long BufferedBinaryStream::get_position()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
return this->currentBufferPosition;
}
break;
case BufferSourceType_Stream:
{
always_assert(this->currentBufferPosition <= this->streamBufferSize);
long pos = (this->readedFromSource > 0) ? this->readedFromSource - (this->streamBufferSize - this->currentBufferPosition) : 0;
return pos;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
ulong BufferedBinaryStream::get_consume_size()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
always_assert(false && "This shouldn't be called ever.");
return 0;
}
break;
case BufferSourceType_Stream:
{
long totalSize = get_size();
ulong currPos = this->underlayingStream->get_position();
ulong avaible = totalSize - currPos;
ulong toConsume = (avaible > this->streamBufferSize) ? this->streamBufferSize : avaible;
return toConsume;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return 0;
}
void BufferedBinaryStream::move_to(const long position)
{
always_assert(position < get_size());
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->currentBufferPosition = position;
}
break;
case BufferSourceType_Stream:
{
// move_to will always reload the buffer.
this->underlayingStream->move_to(position);
ulong toConsume = get_consume_size();
this->streamBuffer = this->underlayingStream->consume_bytes(toConsume);
this->readedFromSource = this->underlayingStream->get_position();
// Just for sure.
//always_assert(this->readedFromSource == position + this->streamBufferSize);
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_to_beginning()
{
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
this->currentBufferPosition = 0;
}
break;
case BufferSourceType_Stream:
{
// move_to_beginning will always reload the buffer.
this->underlayingStream->move_to_beginning();
this->streamBuffer = this->underlayingStream->consume_bytes(get_consume_size());
this->readedFromSource = this->streamBufferSize;
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_to_end()
{
this->currentBufferPosition = get_size();
switch (this->underlayingSourceType)
{
case BufferSourceType_Stream:
{
// move_to_beginning will always clear the buffer.
this->streamBuffer.clear();
this->readedFromSource = this->currentBufferPosition;
this->currentBufferPosition = 0;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
void BufferedBinaryStream::move_by(const long distance)
{
always_assert((get_position() + distance) < get_size());
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
always_assert((this->currentBufferPosition + distance) < this->memoryBuffer->size());
this->currentBufferPosition += distance;
}
break;
case BufferSourceType_Stream:
{
// If atleast one byte can be read, just advance the buffer position.
if ((this->currentBufferPosition + distance + 1) < this->streamBufferSize)
{
this->currentBufferPosition += distance;
}
else
{
// If we are moving outside buffer, reload the buffer from desired location.
long currentPosInStreamRelativeToBufferPos = get_position();
always_assert((currentPosInStreamRelativeToBufferPos + distance) < this->underlayingStream->get_size());
this->underlayingStream->move_to((currentPosInStreamRelativeToBufferPos + distance));
ulong toConsume = get_consume_size();
this->streamBuffer = this->underlayingStream->consume_bytes(toConsume);
this->readedFromSource = this->underlayingStream->get_position();
this->currentBufferPosition = 0;
}
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
}
ByteArray BufferedBinaryStream::consume_bytes(const ulong byteCount)
{
if (this->streamBufferSize < byteCount)
{
printf(RED "To parse this file, you need buffer of size atleast: %lu\n" RESET, byteCount);
}
// We won't allow consuming more bytes than is buffer size.
always_assert(byteCount <= this->streamBufferSize && "Buffer is too small.");
switch (this->underlayingSourceType)
{
case BufferSourceType_Memory:
{
// Check how many bytes are avaible in memory buffer.
ulong bytesAvaible = this->memoryBuffer->size() - this->currentBufferPosition;
printf("BA: %lu\n", bytesAvaible);
always_assert(bytesAvaible >= byteCount);
auto fromIt = this->memoryBuffer->begin() + this->currentBufferPosition;
auto toIt = fromIt + byteCount;
this->currentBufferPosition += byteCount;
ByteArray result(fromIt, toIt);
return result;
}
break;
case BufferSourceType_Stream:
{
ulong bytesAvaible = this->streamBuffer.size() - this->currentBufferPosition;
if ((bytesAvaible == 0) || (byteCount > bytesAvaible))
{
long currentPos = get_position();
// Moving to current position will ensure, that streamBufferSize of data will be read into buffer.
move_to(currentPos);
}
auto fromIt = this->streamBuffer.begin() + this->currentBufferPosition;
auto toIt = fromIt + byteCount;
this->currentBufferPosition += byteCount;
ByteArray result(fromIt, toIt);
return result;
}
break;
default:
always_assert(false && "Invalid BufferSourceType.");
break;
}
return ByteArray();
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment