/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: BufferedLineReader.cpp Date: 2022-2-8 Author: Reece ***/ #include #include "BufferedLineReader.hpp" namespace Aurora::IO::Character { BufferedLineReader::BufferedLineReader(AuSPtr reader) : pInputStream_(reader) { } 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->pInputStream_->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(this->buffer_.writePtr, this->buffer_.writePtr + this->buffer_.length), bytesRead)) != EStreamError::eErrorNone) { SysPushErrorIO(); return false; } this->buffer_.writePtr += bytesRead; return true; } AuList BufferedLineReader::ReadLines() { AU_LOCK_GUARD(this->lock_); AuList ret; bool writeAll = AuExchange(this->flushLine_, false); if (!this->buffer_) { return ret; } while (this->buffer_.readPtr < this->buffer_.writePtr) { Memory::ByteBufferPushReadState _(this->buffer_, true); auto pStartPointer = this->buffer_.readPtr; if (*this->buffer_.readPtr != '\n' && this->buffer_.readPtr < this->buffer_.base + this->buffer_.length) { this->buffer_.readPtr++; continue; } auto pEndReadPointer = this->buffer_.readPtr; auto pEndReadPointer2 = this->buffer_.readPtr; if (pEndReadPointer != this->buffer_.base) { if (pEndReadPointer[-1] == '\r') { pEndReadPointer--; } } try { AuMemoryViewRead view = this->buffer_; if (AuTryInsert(ret, AuString((char *)pStartPointer, (char *)pEndReadPointer))) { this->buffer_.flagReadError = true; break; } this->buffer_.readPtr = pEndReadPointer2; } catch (...) { this->buffer_.flagReadError = true; SysPushErrorCatch(); break; } } if (writeAll && this->buffer_.readPtr && this->buffer_.readPtr != this->buffer_.writePtr) { try { AuMemoryViewRead view = this->buffer_; if (AuTryInsert(ret, AuString(view.begin(), view.end()))) { this->buffer_.readPtr += view.length; } } catch (...) { SysPushErrorCatch(); } } if (this->buffer_.readPtr == this->buffer_.writePtr) { this->buffer_.readPtr = this->buffer_.writePtr = this->buffer_.base; } return ret; } AUKN_SYM IBufferedLineReader *NewLineReaderNew(const AuSPtr &pInputReader) { SysCheckArgNotNull(pInputReader, {}); return _new BufferedLineReader(pInputReader); } AUKN_SYM void NewLineReaderNew(IBufferedLineReader *reader) { AuSafeDelete(reader); } }