/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ViewSeekableReader.hpp Date: 2022-12-11 Author: Reece ***/ #pragma once namespace Aurora::IO::Buffered { struct ViewSeekableReader : ISeekingReader { AU_NO_COPY(ViewSeekableReader) AU_MOVE(ViewSeekableReader) inline ViewSeekableReader(const AuSPtr &pView) : view_(pView ? *pView.get() : Memory::MemoryViewRead {}), pHold(pView) { } inline ViewSeekableReader(const Memory::MemoryViewRead &view, AuSPtr pBlock) : view_(view), pHold(pBlock) { } inline ViewSeekableReader() { } inline ~ViewSeekableReader() { } inline virtual EStreamError IsOpen() override { if (!this->view_) { return EStreamError::eErrorStreamNotOpen; } if (!this->pHold) { return EStreamError::eErrorStreamNotOpen; } return EStreamError::eErrorNone; } inline virtual EStreamError ArbitraryRead(AuUInt uOffset, const Memory::MemoryViewStreamWrite ¶meters) override { if (!this->view_) { return EStreamError::eErrorStreamNotOpen; } if (!this->pHold) { return EStreamError::eErrorStreamNotOpen; } auto iOffset = this->iBaseOffset + AuInt64(uOffset); if (iOffset < 0) { return EStreamError::eErrorOutOfBounds; } else { uOffset = iOffset; } if (this->view_.length < uOffset) { return EStreamError::eErrorEndOfStream; } auto uToRead = AuMin(this->view_.length - uOffset, parameters.length); parameters.outVariable = uToRead; AuMemcpy(parameters.ptr, this->view_.Begin() + uOffset, uToRead); return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone; } inline virtual void Close() override { AuResetMember(this->pHold); AuResetMember(this->view_); } inline AuInt64 &GetBaseOffset() { return this->iBaseOffset; } inline const AuInt64 &GetBaseOffset() const { return this->iBaseOffset; } private: Memory::MemoryViewRead view_; AuSPtr pHold; AuInt64 iBaseOffset {}; }; }