AuroraRuntime/Source/IO/Character/BufferedLineReader.cpp
Reece b29be7b2d5 [*] Hardened line bufferer
[+] Unstaged changes from last commit
2022-02-19 11:50:14 +00:00

117 lines
3.0 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BufferedLineReader.cpp
Date: 2022-2-8
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "BufferedLineReader.hpp"
namespace Aurora::IO::Character
{
void BufferedLineReader::Flush()
{
this->flushLine_ = true;
}
bool BufferedLineReader::ReadBytes(AuUInt32 length)
{
AU_LOCK_GUARD(this->lock_);
if (!this->buffer_.Resize(this->buffer_.GetWriteOffset() + length))
{
SysPushErrorMem();
return false;
}
AuUInt bytesRead;
if (this->inputStream_->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(this->buffer_.writePtr, this->buffer_.end()), bytesRead)) !=
EStreamError::eErrorNone)
{
SysPushErrorIO();
return false;
}
this->buffer_.writePtr += bytesRead;
return true;
}
AuList<AuString> BufferedLineReader::ReadLines()
{
AU_LOCK_GUARD(this->lock_);
AuList<AuString> ret;
bool writeAll = AuExchange(this->flushLine_, false);
if (!this->buffer_)
{
return ret;
}
while (this->buffer_.readPtr < this->buffer_.writePtr)
{
Memory::ByteBufferPushReadState _(this->buffer_, true);
if (*this->buffer_.readPtr != '\n')
{
this->buffer_.readPtr++;
continue;
}
auto end = this->buffer_.GetReadOffset();
auto next = end + 1;
if (end != 0)
{
if (this->buffer_.readPtr[-1] == '\r')
{
end--;
}
}
try
{
if (!AuTryInsert(ret, AuString(this->buffer_.base, this->buffer_.base + end)))
{
this->buffer_.flagReadError = true;
break;
}
this->buffer_.readPtr = this->buffer_.base + next;
}
catch (...)
{
this->buffer_.flagReadError = true;
SysPushErrorCatch();
break;
}
}
if (writeAll && this->buffer_.readPtr && this->buffer_.readPtr != this->buffer_.writePtr)
{
try
{
if (AuTryInsert(ret, AuString(this->buffer_.base, this->buffer_.base + this->buffer_.length)))
{
this->buffer_.readPtr = this->buffer_.base + this->buffer_.length;
}
}
catch (...)
{
SysPushErrorCatch();
}
}
return ret;
}
AUKN_SYM IBufferedLineReader *NewLineReaderNew(const AuSPtr<IStreamReader> &input)
{
return _new BufferedLineReader(input);
}
AUKN_SYM void NewLineReaderNew(IBufferedLineReader *reader)
{
AuSafeDelete<BufferedLineReader *>(reader);
}
}