/*** 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 { 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_.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); 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 &input) { return _new BufferedLineReader(input); } AUKN_SYM void NewLineReaderNew(IBufferedLineReader *reader) { AuSafeDelete(reader); } }