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