[+] Aurora::IO::FS::IMemoryMappedFile
[+] Aurora::IO::Adapters::NewMemoryViewWriteSeekableAdapter [*] ViewSeekableReadable -> ViewSeekableReader [+] Aurora::IO::FS::OpenMap [+] Aurora::IO::FS::OpenMapFromSharedHandle
This commit is contained in:
parent
6d4fc2c5f7
commit
38bf52e852
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Adapters
|
namespace Aurora::IO::Adapters
|
||||||
{
|
{
|
||||||
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamReader(const AuSPtr<IStreamReader> &pStreamReader, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamReader(const AuSPtr<IStreamReader> &pStreamReader, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
||||||
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamSeekingReader(const AuSPtr<ISeekingReader> &pStreamReader, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamSeekingReader(const AuSPtr<ISeekingReader> &pStreamReader, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
||||||
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamWriter(const AuSPtr<IStreamWriter> &pStreamWriter, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamWriter(const AuSPtr<IStreamWriter> &pStreamWriter, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
||||||
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamSeekingWriter(const AuSPtr<ISeekingWriter> &pStreamWriter, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
AUKN_SYM AuSPtr<IAsyncTransaction> NewAsyncTransactionFromStreamSeekingWriter(const AuSPtr<ISeekingWriter> &pStreamWriter, AuOptional<Aurora::Async::WorkerPId_t> workers);
|
||||||
}
|
}
|
@ -10,6 +10,7 @@
|
|||||||
namespace Aurora::IO::Adapters
|
namespace Aurora::IO::Adapters
|
||||||
{
|
{
|
||||||
AUKN_SYM AuSPtr<IStreamReader> NewByteBufferReadAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
AUKN_SYM AuSPtr<IStreamReader> NewByteBufferReadAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
||||||
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearReadSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
||||||
|
AUKN_SYM AuSPtr<ISeekingWriter> NewByteBufferLinearWriteSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
||||||
AUKN_SYM AuSPtr<IStreamWriter> NewByteBufferWriteAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
AUKN_SYM AuSPtr<IStreamWriter> NewByteBufferWriteAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer);
|
||||||
}
|
}
|
@ -10,6 +10,7 @@
|
|||||||
namespace Aurora::IO::Adapters
|
namespace Aurora::IO::Adapters
|
||||||
{
|
{
|
||||||
AUKN_SYM AuSPtr<IStreamReader> NewMemoryViewReadAdapter(const AuSPtr<Memory::MemoryViewRead> &pView);
|
AUKN_SYM AuSPtr<IStreamReader> NewMemoryViewReadAdapter(const AuSPtr<Memory::MemoryViewRead> &pView);
|
||||||
AUKN_SYM AuSPtr<ISeekingReader> NewMemoryViewLinearSeekableAdapter(const AuSPtr<Memory::MemoryViewRead> &pView);
|
AUKN_SYM AuSPtr<ISeekingReader> NewMemoryViewReadSeekingAdapter(const AuSPtr<Memory::MemoryViewRead> &pView);
|
||||||
AUKN_SYM AuSPtr<IStreamWriter> NewMemoryViewWriteAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView);
|
AUKN_SYM AuSPtr<IStreamWriter> NewMemoryViewWriteAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView);
|
||||||
|
AUKN_SYM AuSPtr<ISeekingWriter> NewMemoryViewWriteSeekableAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView);
|
||||||
}
|
}
|
@ -11,18 +11,16 @@ namespace Aurora::IO::Buffered
|
|||||||
{
|
{
|
||||||
struct BlobReader : IStreamReader
|
struct BlobReader : IStreamReader
|
||||||
{
|
{
|
||||||
AU_NO_COPY(BlobReader)
|
AU_COPY_MOVE(BlobReader)
|
||||||
|
|
||||||
inline BlobReader(const AuSPtr<Memory::ByteBuffer> &buffer) : buffer_(buffer) {}
|
inline BlobReader(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||||
inline BlobReader(Memory::ByteBuffer &&buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
inline BlobReader(Memory::ByteBuffer &&buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||||
inline BlobReader(const Memory::ByteBuffer &buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
inline BlobReader(const Memory::ByteBuffer &buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||||
|
inline BlobReader() : pBuffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
||||||
inline BlobReader() {}
|
|
||||||
inline ~BlobReader() {}
|
|
||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
inline virtual EStreamError IsOpen() override
|
||||||
{
|
{
|
||||||
auto pBuffer = this->buffer_;
|
auto pBuffer = this->pBuffer_;
|
||||||
if (!pBuffer)
|
if (!pBuffer)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
@ -38,7 +36,7 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError Read(const Memory::MemoryViewStreamWrite ¶meters) override
|
inline virtual EStreamError Read(const Memory::MemoryViewStreamWrite ¶meters) override
|
||||||
{
|
{
|
||||||
auto pBuffer = this->buffer_;
|
auto pBuffer = this->pBuffer_;
|
||||||
if (!pBuffer)
|
if (!pBuffer)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
@ -55,10 +53,10 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual void Close() override
|
inline virtual void Close() override
|
||||||
{
|
{
|
||||||
AuResetMember(this->buffer_);
|
AuResetMember(this->pBuffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AuSPtr<Memory::ByteBuffer> buffer_;
|
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -11,18 +11,15 @@ namespace Aurora::IO::Buffered
|
|||||||
{
|
{
|
||||||
struct BlobSeekableReader : ISeekingReader
|
struct BlobSeekableReader : ISeekingReader
|
||||||
{
|
{
|
||||||
AU_NO_COPY_NO_MOVE(BlobSeekableReader)
|
AU_COPY_MOVE_DEF(BlobSeekableReader)
|
||||||
|
|
||||||
inline BlobSeekableReader(const AuSPtr<Memory::ByteBuffer> &buffer) : buffer_(buffer) {}
|
inline BlobSeekableReader(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||||
inline BlobSeekableReader(Memory::ByteBuffer &&buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(AuMove(buffer))) {}
|
inline BlobSeekableReader(Memory::ByteBuffer &&buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(AuMove(buffer))) {}
|
||||||
inline BlobSeekableReader(const Memory::ByteBuffer &buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
inline BlobSeekableReader(const Memory::ByteBuffer &buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||||
|
|
||||||
inline BlobSeekableReader() {}
|
|
||||||
inline ~BlobSeekableReader(){}
|
|
||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
inline virtual EStreamError IsOpen() override
|
||||||
{
|
{
|
||||||
if (!this->buffer_)
|
if (!this->pBuffer_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
@ -32,27 +29,27 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError ArbitraryRead(AuUInt offset, const Memory::MemoryViewStreamWrite ¶meters) override
|
inline virtual EStreamError ArbitraryRead(AuUInt offset, const Memory::MemoryViewStreamWrite ¶meters) override
|
||||||
{
|
{
|
||||||
if (!this->buffer_)
|
if (!this->pBuffer_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->buffer_->empty())
|
if (this->pBuffer_->empty())
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorEndOfStream;
|
return EStreamError::eErrorEndOfStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->buffer_->readPtr = this->buffer_->base + offset;
|
this->pBuffer_->readPtr = this->pBuffer_->base + offset;
|
||||||
parameters.outVariable = this->buffer_->Read(parameters.ptr, parameters.length);
|
parameters.outVariable = this->pBuffer_->Read(parameters.ptr, parameters.length);
|
||||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline virtual void Close() override
|
inline virtual void Close() override
|
||||||
{
|
{
|
||||||
AuResetMember(this->buffer_);
|
AuResetMember(this->pBuffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuSPtr<Memory::ByteBuffer> buffer_;
|
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||||
};
|
};
|
||||||
}
|
}
|
59
Include/Aurora/IO/Buffered/BlobSeekableWriter.hpp
Normal file
59
Include/Aurora/IO/Buffered/BlobSeekableWriter.hpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: BlobSeekableWriter.hpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::Buffered
|
||||||
|
{
|
||||||
|
struct BlobSeekableWriter : ISeekingWriter
|
||||||
|
{
|
||||||
|
AU_COPY_MOVE_DEF(BlobSeekableWriter)
|
||||||
|
|
||||||
|
inline BlobSeekableWriter(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||||
|
inline BlobSeekableWriter(Memory::ByteBuffer &&buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(AuMove(buffer))) {}
|
||||||
|
inline BlobSeekableWriter(const Memory::ByteBuffer &buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||||
|
|
||||||
|
inline virtual EStreamError IsOpen() override
|
||||||
|
{
|
||||||
|
if (!this->pBuffer_)
|
||||||
|
{
|
||||||
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual EStreamError ArbitraryWrite(AuUInt offset, const Memory::MemoryViewStreamRead ¶meters) override
|
||||||
|
{
|
||||||
|
if (!this->pBuffer_)
|
||||||
|
{
|
||||||
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->pBuffer_->empty())
|
||||||
|
{
|
||||||
|
return EStreamError::eErrorEndOfStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pBuffer_->writePtr = this->pBuffer_->base + offset;
|
||||||
|
parameters.outVariable = this->pBuffer_->Write(parameters.ptr, parameters.length);
|
||||||
|
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void Flush() override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void Close() override
|
||||||
|
{
|
||||||
|
AuResetMember(this->pBuffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||||
|
};
|
||||||
|
}
|
@ -11,15 +11,15 @@ namespace Aurora::IO::Buffered
|
|||||||
{
|
{
|
||||||
struct BlobWriter : IStreamWriter
|
struct BlobWriter : IStreamWriter
|
||||||
{
|
{
|
||||||
AU_NO_COPY_NO_MOVE(BlobWriter)
|
AU_COPY_MOVE(BlobWriter)
|
||||||
|
|
||||||
inline BlobWriter(const AuSPtr<Memory::ByteBuffer> &buffer) : buffer_(buffer) {}
|
inline BlobWriter(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||||
inline BlobWriter() : buffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
inline BlobWriter() : pBuffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
||||||
inline ~BlobWriter() {}
|
inline ~BlobWriter() {}
|
||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
inline virtual EStreamError IsOpen() override
|
||||||
{
|
{
|
||||||
auto pBuffer = this->buffer_;
|
auto pBuffer = this->pBuffer_;
|
||||||
if (!pBuffer)
|
if (!pBuffer)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
@ -35,7 +35,7 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
||||||
{
|
{
|
||||||
auto pBuffer = this->buffer_;
|
auto pBuffer = this->pBuffer_;
|
||||||
if (!pBuffer)
|
if (!pBuffer)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
@ -56,15 +56,15 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual void Close() override
|
inline virtual void Close() override
|
||||||
{
|
{
|
||||||
AuResetMember(this->buffer_);
|
AuResetMember(this->pBuffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AuSPtr<Memory::ByteBuffer> GetBuffer()
|
inline AuSPtr<Memory::ByteBuffer> GetBuffer()
|
||||||
{
|
{
|
||||||
return this->buffer_;
|
return this->pBuffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuSPtr<Memory::ByteBuffer> buffer_;
|
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,12 +7,12 @@
|
|||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Most internal transactions will be buffered.
|
|
||||||
// For sake of being able to mix network, file, serial, and other code, its nice to use the same reader interface for buffered and streams where read/write until EOS is required
|
|
||||||
#include "BlobSeekableReader.hpp"
|
|
||||||
#include "BlobReader.hpp"
|
#include "BlobReader.hpp"
|
||||||
|
#include "BlobSeekableReader.hpp"
|
||||||
#include "BlobWriter.hpp"
|
#include "BlobWriter.hpp"
|
||||||
|
#include "BlobSeekableWriter.hpp"
|
||||||
|
|
||||||
#include "ViewReader.hpp"
|
#include "ViewReader.hpp"
|
||||||
#include "ViewSeekableReadable.hpp"
|
#include "ViewSeekableReader.hpp"
|
||||||
#include "ViewWriter.hpp"
|
#include "ViewWriter.hpp"
|
||||||
|
#include "ViewSeekableWriter.hpp"
|
||||||
|
@ -12,8 +12,12 @@ namespace Aurora::IO::Buffered
|
|||||||
struct ViewReader : IStreamReader
|
struct ViewReader : IStreamReader
|
||||||
{
|
{
|
||||||
AU_NO_COPY(ViewReader)
|
AU_NO_COPY(ViewReader)
|
||||||
|
AU_MOVE(ViewReader)
|
||||||
|
|
||||||
inline ViewReader(const AuSPtr<Memory::MemoryViewRead> &view) : pView_(view)
|
inline ViewReader(const AuSPtr<Memory::MemoryViewRead> &pView) : view_(pView ? *pView.get() : Memory::MemoryViewRead {}), pHold(pView)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ViewReader(const Memory::MemoryViewRead &view, AuSPtr<void> pBlock) : view_(view), pHold(pBlock)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline ViewReader()
|
inline ViewReader()
|
||||||
@ -24,12 +28,12 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
inline virtual EStreamError IsOpen() override
|
||||||
{
|
{
|
||||||
if (!this->pView_)
|
if (!this->view_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*this->pView_.get()))
|
if (!this->pHold)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
@ -41,27 +45,28 @@ namespace Aurora::IO::Buffered
|
|||||||
{
|
{
|
||||||
parameters.outVariable = 0;
|
parameters.outVariable = 0;
|
||||||
|
|
||||||
if (!this->pView_)
|
if (!this->view_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*this->pView_.get()))
|
if (!this->pHold)
|
||||||
{
|
{
|
||||||
this->pView_.reset();
|
this->Close();
|
||||||
return this->uOffset_ ? EStreamError::eErrorStreamNotOpen : EStreamError::eErrorNone;
|
return this->uOffset_ ? EStreamError::eErrorStreamNotOpen : EStreamError::eErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto uToRead = AuMin(this->pView_->length - this->uOffset_, parameters.length);
|
auto uToRead = AuMin(this->view_.length - this->uOffset_, parameters.length);
|
||||||
parameters.outVariable = uToRead;
|
parameters.outVariable = uToRead;
|
||||||
AuMemcpy(parameters.ptr, this->pView_->Begin<AuUInt8>() + this->uOffset_, uToRead);
|
AuMemcpy(parameters.ptr, this->view_.Begin<AuUInt8>() + this->uOffset_, uToRead);
|
||||||
this->uOffset_ += uToRead;
|
this->uOffset_ += uToRead;
|
||||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline virtual void Close() override
|
inline virtual void Close() override
|
||||||
{
|
{
|
||||||
this->pView_.reset();
|
AuResetMember(this->pHold);
|
||||||
|
AuResetMember(this->view_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AuUInt &GetOffset()
|
inline AuUInt &GetOffset()
|
||||||
@ -74,7 +79,8 @@ namespace Aurora::IO::Buffered
|
|||||||
return this->uOffset_;
|
return this->uOffset_;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
AuSPtr<Memory::MemoryViewRead> pView_;
|
Memory::MemoryViewRead view_;
|
||||||
|
AuSPtr<void> pHold;
|
||||||
AuUInt uOffset_ {};
|
AuUInt uOffset_ {};
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,71 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: ViewSeekableReadable.hpp
|
|
||||||
Date: 2022-12-11
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::IO::Buffered
|
|
||||||
{
|
|
||||||
struct ViewSeekableReadable : ISeekingReader
|
|
||||||
{
|
|
||||||
AU_NO_COPY(ViewSeekableReadable)
|
|
||||||
|
|
||||||
inline ViewSeekableReadable(const AuSPtr<Memory::MemoryViewRead> &view) : view_(view)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline ViewSeekableReadable()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline ~ViewSeekableReadable()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
|
||||||
{
|
|
||||||
if (!this->view_)
|
|
||||||
{
|
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*this->view_.get()))
|
|
||||||
{
|
|
||||||
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->view_.get()))
|
|
||||||
{
|
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<AuUInt8>() + uOffset, uToRead);
|
|
||||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline virtual void Close() override
|
|
||||||
{
|
|
||||||
this->view_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AuSPtr<Memory::MemoryViewRead> view_;
|
|
||||||
};
|
|
||||||
}
|
|
98
Include/Aurora/IO/Buffered/ViewSeekableReader.hpp
Normal file
98
Include/Aurora/IO/Buffered/ViewSeekableReader.hpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/***
|
||||||
|
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<Memory::MemoryViewRead> &pView) : view_(pView ? *pView.get() : Memory::MemoryViewRead {}), pHold(pView)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ViewSeekableReader(const Memory::MemoryViewRead &view, AuSPtr<void> 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<AuUInt8>() + 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<void> pHold;
|
||||||
|
AuInt64 iBaseOffset {};
|
||||||
|
};
|
||||||
|
}
|
102
Include/Aurora/IO/Buffered/ViewSeekableWriter.hpp
Normal file
102
Include/Aurora/IO/Buffered/ViewSeekableWriter.hpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2022-2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: ViewSeekableWriter.hpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::Buffered
|
||||||
|
{
|
||||||
|
struct ViewSeekableWriter : ISeekingWriter
|
||||||
|
{
|
||||||
|
AU_NO_COPY(ViewSeekableWriter)
|
||||||
|
AU_MOVE(ViewSeekableWriter)
|
||||||
|
|
||||||
|
inline ViewSeekableWriter(const AuSPtr<Memory::MemoryViewWrite> &pView) : view_(pView ? *pView.get() : Memory::MemoryViewWrite {}), pHold(pView)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ViewSeekableWriter(const Memory::MemoryViewWrite &view, AuSPtr<void> pBlock) : view_(view), pHold(pBlock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ViewSeekableWriter()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ~ViewSeekableWriter()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline virtual EStreamError IsOpen() override
|
||||||
|
{
|
||||||
|
if (!this->view_)
|
||||||
|
{
|
||||||
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->pHold)
|
||||||
|
{
|
||||||
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual EStreamError ArbitraryWrite(AuUInt uOffset, const Memory::MemoryViewStreamRead ¶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(this->view_.Begin<AuUInt8>() + uOffset, parameters.ptr, uToRead);
|
||||||
|
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void Close() override
|
||||||
|
{
|
||||||
|
AuResetMember(this->pHold);
|
||||||
|
AuResetMember(this->view_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline virtual void Flush() override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AuInt64 &GetBaseOffset()
|
||||||
|
{
|
||||||
|
return this->iBaseOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const AuInt64 &GetBaseOffset() const
|
||||||
|
{
|
||||||
|
return this->iBaseOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Memory::MemoryViewWrite view_;
|
||||||
|
AuSPtr<void> pHold;
|
||||||
|
AuInt64 iBaseOffset {};
|
||||||
|
};
|
||||||
|
}
|
@ -12,8 +12,12 @@ namespace Aurora::IO::Buffered
|
|||||||
struct ViewWriter : IStreamWriter
|
struct ViewWriter : IStreamWriter
|
||||||
{
|
{
|
||||||
AU_NO_COPY(ViewWriter)
|
AU_NO_COPY(ViewWriter)
|
||||||
|
AU_MOVE(ViewWriter)
|
||||||
|
|
||||||
inline ViewWriter(const AuSPtr<Memory::MemoryViewWrite> &view) : pView_(view)
|
inline ViewWriter(const AuSPtr<Memory::MemoryViewWrite> &pView) : view_(pView ? *pView.get() : Memory::MemoryViewWrite {}), pHold(pView)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ViewWriter(const Memory::MemoryViewWrite &view, AuSPtr<void> pBlock) : view_(view), pHold(pBlock)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline ViewWriter()
|
inline ViewWriter()
|
||||||
@ -24,12 +28,12 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError IsOpen() override
|
inline virtual EStreamError IsOpen() override
|
||||||
{
|
{
|
||||||
if (!this->pView_)
|
if (!this->view_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*this->pView_.get()))
|
if (!this->pHold)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
@ -39,26 +43,27 @@ namespace Aurora::IO::Buffered
|
|||||||
|
|
||||||
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
||||||
{
|
{
|
||||||
if (!this->pView_)
|
if (!this->view_)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*this->pView_.get()))
|
if (!this->pHold)
|
||||||
{
|
{
|
||||||
return EStreamError::eErrorStreamNotOpen;
|
return EStreamError::eErrorStreamNotOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto uToRead = AuMin(this->pView_->length - this->uOffset_, parameters.length);
|
auto uToRead = AuMin(this->view_.length - this->uOffset_, parameters.length);
|
||||||
parameters.outVariable = uToRead;
|
parameters.outVariable = uToRead;
|
||||||
AuMemcpy(this->pView_->Begin<AuUInt8>() + this->uOffset_, parameters.ptr, uToRead);
|
AuMemcpy(this->view_.Begin<AuUInt8>() + this->uOffset_, parameters.ptr, uToRead);
|
||||||
this->uOffset_ += uToRead;
|
this->uOffset_ += uToRead;
|
||||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline virtual void Close() override
|
inline virtual void Close() override
|
||||||
{
|
{
|
||||||
this->pView_.reset();
|
AuResetMember(this->pHold);
|
||||||
|
AuResetMember(this->view_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline virtual void Flush() override
|
inline virtual void Flush() override
|
||||||
@ -76,7 +81,8 @@ namespace Aurora::IO::Buffered
|
|||||||
return this->uOffset_;
|
return this->uOffset_;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
AuSPtr<Memory::MemoryViewWrite> pView_;
|
Memory::MemoryViewWrite view_;
|
||||||
|
AuSPtr<void> pHold;
|
||||||
AuUInt uOffset_ {};
|
AuUInt uOffset_ {};
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -314,7 +314,9 @@ namespace Aurora::IO::FS
|
|||||||
#include "Resources.hpp"
|
#include "Resources.hpp"
|
||||||
#include "Stat.hpp"
|
#include "Stat.hpp"
|
||||||
#include "IAsyncFileStream.hpp"
|
#include "IAsyncFileStream.hpp"
|
||||||
|
#include "IMemoryMappedFile.hpp"
|
||||||
#include "Async.hpp"
|
#include "Async.hpp"
|
||||||
#include "Watcher.hpp"
|
#include "Watcher.hpp"
|
||||||
#include "IReadDir.hpp"
|
#include "IReadDir.hpp"
|
||||||
#include "Overlapped.hpp"
|
#include "Overlapped.hpp"
|
||||||
|
#include "MemoryMappedFile.hpp"
|
36
Include/Aurora/IO/FS/IMemoryMappedFile.hpp
Normal file
36
Include/Aurora/IO/FS/IMemoryMappedFile.hpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IMemoryMappedFile.hpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
struct IMemoryMappedFile
|
||||||
|
{
|
||||||
|
virtual IIOHandle * ToHandle() = 0;
|
||||||
|
|
||||||
|
virtual AuUInt GetBaseAddress() = 0;
|
||||||
|
virtual AuUInt GetEndAddress() = 0;
|
||||||
|
virtual AuUInt GetLength() = 0;
|
||||||
|
|
||||||
|
virtual AuSPtr<IStreamReader> NewStreamReader() = 0;
|
||||||
|
virtual AuSPtr<IStreamWriter> NewStreamWriter() = 0;
|
||||||
|
|
||||||
|
virtual AuSPtr<IAsyncTransaction> NewAsyncReadTransaction() = 0;
|
||||||
|
virtual AuSPtr<IAsyncTransaction> NewAsyncWriteTransaction() = 0;
|
||||||
|
|
||||||
|
virtual ISeekingReader * ToStreamSeekingReader() = 0;
|
||||||
|
virtual ISeekingWriter * ToStreamSeekingWriter() = 0;
|
||||||
|
|
||||||
|
virtual void Flush(AuUInt uOffset,
|
||||||
|
AuUInt uLength) = 0;
|
||||||
|
|
||||||
|
virtual void Prefetch(AuUInt uOffset,
|
||||||
|
AuUInt uLength) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
29
Include/Aurora/IO/FS/MemoryMappedFile.hpp
Normal file
29
Include/Aurora/IO/FS/MemoryMappedFile.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: MemoryMappedFile.hpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
AUKN_SHARED_API(OpenMap, IMemoryMappedFile,
|
||||||
|
const AuString &path,
|
||||||
|
AuOptional<EFileOpenMode> opteMode = { EFileOpenMode::eRead },
|
||||||
|
AuOptional<AuUInt64> optuFileMapOffset = { 0 },
|
||||||
|
AuOptional<AuUInt64> optuFileMapLength = { 0 },
|
||||||
|
AuOptional<AuInt64> optiAdjustStreamOffset = { /* optuFileMapOffset */ }, // uFileMapOffset <= Stream transactions offset and IMemoryMappedFile::Flush(uOffset, ...) + iAdjustStreamOffset < uFileMapOffset + uFileMapLength
|
||||||
|
AuOptional<EFileAdvisoryLockLevel> opteSuccessPostAdvisoryLevel = { EFileAdvisoryLockLevel::eBlockReadWrite },
|
||||||
|
AuOptional<bool> optbLockEntireFile = { true });
|
||||||
|
|
||||||
|
|
||||||
|
AUKN_SHARED_API(OpenMapFromSharedHandle, IMemoryMappedFile,
|
||||||
|
const AuSPtr<IIOHandle> &pIOHandle,
|
||||||
|
AuOptional<AuUInt64> optuFileMapOffset = { 0 },
|
||||||
|
AuOptional<AuUInt64> optuFileMapLength = { 0 },
|
||||||
|
AuOptional<AuInt64> optiAdjustStreamOffset = { /* optuFileMapOffset */ }, // uFileMapOffset <= Stream transactions offset and IMemoryMappedFile::Flush(uOffset, ...) + iAdjustStreamOffset < uFileMapOffset + uFileMapLength
|
||||||
|
AuOptional<EFileAdvisoryLockLevel> opteSuccessPostAdvisoryLevel = { EFileAdvisoryLockLevel::eNoSafety }
|
||||||
|
);
|
||||||
|
}
|
@ -155,6 +155,8 @@ namespace Aurora::IO
|
|||||||
virtual bool SharingIsShared() = 0;
|
virtual bool SharingIsShared() = 0;
|
||||||
|
|
||||||
virtual void SharingStop() = 0;
|
virtual void SharingStop() = 0;
|
||||||
|
|
||||||
|
virtual AuUInt64 GetFileLength() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
AUKN_SHARED_SOO_CC(IOHandle, IIOHandle, 256);
|
AUKN_SHARED_SOO_CC(IOHandle, IIOHandle, 256);
|
||||||
|
@ -749,4 +749,17 @@ namespace Aurora
|
|||||||
pWakeByAddressAll((void *)pAddress);
|
pWakeByAddressAll((void *)pAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER length;
|
||||||
|
|
||||||
|
if (!::GetFileSizeEx((HANDLE)uOSHandle, &length))
|
||||||
|
{
|
||||||
|
SysPushErrorIO();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length.QuadPart;
|
||||||
|
}
|
||||||
}
|
}
|
@ -137,4 +137,9 @@ namespace Aurora
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
return PosixGetLength(uOSHandle);
|
||||||
|
}
|
||||||
}
|
}
|
@ -43,4 +43,6 @@ namespace Aurora
|
|||||||
AuUInt32 dwCount);
|
AuUInt32 dwCount);
|
||||||
|
|
||||||
void SysWakeAllOnAddress(const void *pAddress);
|
void SysWakeAllOnAddress(const void *pAddress);
|
||||||
|
|
||||||
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle);
|
||||||
}
|
}
|
@ -12,219 +12,202 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Adapters
|
namespace Aurora::IO::Adapters
|
||||||
{
|
{
|
||||||
struct AsyncReaderWriter : IAsyncTransaction,
|
void AsyncReaderWriter::DispatchFrame(ProcessInfo &info)
|
||||||
Async::APCLessWaitable,
|
|
||||||
AuAsync::IWorkItemHandler
|
|
||||||
{
|
{
|
||||||
AuSPtr<IStreamReader> pStreamReader;
|
try
|
||||||
AuSPtr<ISeekingReader> pStreamReaderEx;
|
|
||||||
AuSPtr<IStreamWriter> pStreamWriter;
|
|
||||||
AuSPtr<ISeekingWriter> pStreamWriterEx;
|
|
||||||
AuSPtr<Memory::MemoryViewRead> pReadView;
|
|
||||||
AuSPtr<Memory::MemoryViewWrite> pWriteView;
|
|
||||||
AuWorkerPId workers;
|
|
||||||
|
|
||||||
void DispatchFrame(ProcessInfo &info) override
|
|
||||||
{
|
{
|
||||||
try
|
if (this->iBaseOffset + AuInt64(this->uLastOffset) < 0)
|
||||||
{
|
{
|
||||||
if (this->pReadView)
|
this->eStreamError = EStreamError::eErrorOutOfBounds;
|
||||||
|
}
|
||||||
|
else if (this->pReadView)
|
||||||
|
{
|
||||||
|
if (this->pStreamWriter)
|
||||||
{
|
{
|
||||||
if (this->pStreamWriter)
|
this->eStreamError = this->pStreamWriter->Write(AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
||||||
{
|
|
||||||
this->eStreamError = this->pStreamWriter->Write(AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
|
||||||
}
|
|
||||||
else if (this->pStreamWriterEx)
|
|
||||||
{
|
|
||||||
this->eStreamError = this->pStreamWriterEx->ArbitraryWrite(this->uBaseOffset + this->uLastOffset, AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (this->pWriteView)
|
else if (this->pStreamWriterEx)
|
||||||
{
|
{
|
||||||
if (this->pStreamReader)
|
this->eStreamError = this->pStreamWriterEx->ArbitraryWrite(this->iBaseOffset + this->uLastOffset, AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
||||||
{
|
|
||||||
this->eStreamError = this->pStreamReader->Read(AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
|
||||||
}
|
|
||||||
else if (this->pStreamReaderEx)
|
|
||||||
{
|
|
||||||
this->eStreamError = this->pStreamReaderEx->ArbitraryRead(this->uBaseOffset + this->uLastOffset, AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
else if (this->pWriteView)
|
||||||
{
|
{
|
||||||
this->eStreamError = EStreamError::eErrorGenericFault;
|
if (this->pStreamReader)
|
||||||
|
{
|
||||||
|
this->eStreamError = this->pStreamReader->Read(AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
||||||
|
}
|
||||||
|
else if (this->pStreamReaderEx)
|
||||||
|
{
|
||||||
|
this->eStreamError = this->pStreamReaderEx->ArbitraryRead(this->iBaseOffset + this->uLastOffset, AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this->bInProgress = false;
|
catch (...)
|
||||||
this->SignalComplete();
|
{
|
||||||
|
this->eStreamError = EStreamError::eErrorGenericFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnFailure() override
|
this->bInProgress = false;
|
||||||
|
this->SignalComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncReaderWriter::OnFailure()
|
||||||
|
{
|
||||||
|
this->bInProgress = false;
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::StartRead(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewWrite> &memoryView)
|
||||||
|
{
|
||||||
|
if (!memoryView)
|
||||||
{
|
{
|
||||||
this->bInProgress = false;
|
SysPushErrorArg();
|
||||||
this->Reset();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartRead(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewWrite> &memoryView) override
|
if (this->bInProgress)
|
||||||
{
|
{
|
||||||
if (!memoryView)
|
return false;
|
||||||
{
|
|
||||||
SysPushErrorArg();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->bInProgress)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->pStreamReaderEx && !this->pStreamReader)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuResetMember(this->pReadView);
|
|
||||||
AuResetMember(this->pWriteView);
|
|
||||||
this->bInProgress = true;
|
|
||||||
this->uLastOffset = uOffset;
|
|
||||||
this->pWriteView = memoryView;
|
|
||||||
|
|
||||||
auto pThat = AuAsync::NewWorkItem(this->workers, AuStaticCast<AsyncReaderWriter>(this->SharedFromThis()));
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pThat->Dispatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartWrite(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewRead> &memoryView) override
|
if (!this->pStreamReaderEx && !this->pStreamReader)
|
||||||
{
|
{
|
||||||
if (!memoryView)
|
return false;
|
||||||
{
|
}
|
||||||
SysPushErrorArg();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->bInProgress)
|
AuResetMember(this->pReadView);
|
||||||
{
|
AuResetMember(this->pWriteView);
|
||||||
return false;
|
this->bInProgress = true;
|
||||||
}
|
this->uLastOffset = uOffset;
|
||||||
|
this->pWriteView = memoryView;
|
||||||
|
|
||||||
|
auto pThat = AuAsync::NewWorkItem(this->workers, AuStaticCast<AsyncReaderWriter>(this->SharedFromThis()));
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pThat->Dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::StartWrite(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewRead> &memoryView)
|
||||||
|
{
|
||||||
|
if (!memoryView)
|
||||||
|
{
|
||||||
|
SysPushErrorArg();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->bInProgress)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->pStreamWriterEx && !this->pStreamWriter)
|
if (!this->pStreamWriterEx && !this->pStreamWriter)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuResetMember(this->pReadView);
|
|
||||||
AuResetMember(this->pWriteView);
|
|
||||||
this->bInProgress = true;
|
|
||||||
this->uLastOffset = uOffset;
|
|
||||||
this->pReadView = memoryView;
|
|
||||||
|
|
||||||
auto pThat = AuAsync::NewWorkItem(this->workers, AuStaticCast<AsyncReaderWriter>(this->SharedFromThis()));
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pThat->Dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt32 GetLastPacketLength() override
|
|
||||||
{
|
{
|
||||||
return this->uLastLength;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnOriginThreadComplete() override
|
AuResetMember(this->pReadView);
|
||||||
|
AuResetMember(this->pWriteView);
|
||||||
|
this->bInProgress = true;
|
||||||
|
this->uLastOffset = uOffset;
|
||||||
|
this->pReadView = memoryView;
|
||||||
|
|
||||||
|
auto pThat = AuAsync::NewWorkItem(this->workers, AuStaticCast<AsyncReaderWriter>(this->SharedFromThis()));
|
||||||
|
if (!pThat)
|
||||||
{
|
{
|
||||||
if (this->pSubscriber)
|
return false;
|
||||||
{
|
|
||||||
this->pSubscriber->OnAsyncFileOpFinished(this->uBaseOffset + this->uLastOffset, this->GetLastPacketLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
AuResetMember(this->pReadView);
|
|
||||||
AuResetMember(this->pWriteView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Complete() override
|
return pThat->Dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt32 AsyncReaderWriter::GetLastPacketLength()
|
||||||
|
{
|
||||||
|
return this->uLastLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncReaderWriter::OnOriginThreadComplete()
|
||||||
|
{
|
||||||
|
if (this->pSubscriber)
|
||||||
{
|
{
|
||||||
Async::APCLessWaitable::CheckLocal();
|
this->pSubscriber->OnAsyncFileOpFinished(this->uLastOffset, this->GetLastPacketLength());
|
||||||
return Async::APCLessWaitable::HasBeenSignaled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasFailed() override
|
AuResetMember(this->pReadView);
|
||||||
|
AuResetMember(this->pWriteView);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::Complete()
|
||||||
|
{
|
||||||
|
Async::APCLessWaitable::CheckLocal();
|
||||||
|
return Async::APCLessWaitable::HasBeenSignaled();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::HasFailed()
|
||||||
|
{
|
||||||
|
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError != EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::HasCompleted()
|
||||||
|
{
|
||||||
|
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError == EStreamError::eErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt AsyncReaderWriter::GetOSErrorCode()
|
||||||
|
{
|
||||||
|
return this->HasFailed() ? AuUInt(this->eStreamError) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncReaderWriter::SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &pSubscriber)
|
||||||
|
{
|
||||||
|
this->pSubscriber = pSubscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncReaderWriter::Wait(AuUInt32 uTimeout)
|
||||||
|
{
|
||||||
|
return NewLoopSource()->WaitOn(uTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IO::Loop::ILoopSource> AsyncReaderWriter::NewLoopSource()
|
||||||
|
{
|
||||||
|
return Async::APCLessWaitable::GetLoopSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncReaderWriter::Reset()
|
||||||
|
{
|
||||||
|
if (this->bInProgress)
|
||||||
{
|
{
|
||||||
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError != EStreamError::eErrorNone;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasCompleted() override
|
AuResetMember(this->pReadView);
|
||||||
{
|
AuResetMember(this->pWriteView);
|
||||||
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError == EStreamError::eErrorNone;
|
Async::APCLessWaitable::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuUInt GetOSErrorCode() override
|
void AsyncReaderWriter::SetBaseOffset(AuUInt64 uBaseOffset)
|
||||||
{
|
{
|
||||||
return this->HasFailed() ? AuUInt(this->eStreamError) : 0;
|
this->iBaseOffset = uBaseOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &pSubscriber) override
|
bool AsyncReaderWriter::TryAttachToCompletionGroup(const AuSPtr<CompletionGroup::ICompletionGroup> &pCompletionGroup)
|
||||||
{
|
{
|
||||||
this->pSubscriber = pSubscriber;
|
return Async::APCLessWaitable::TryAttachToCompletionGroup(pCompletionGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wait(AuUInt32 uTimeout) override
|
CompletionGroup::ICompletionGroupWorkHandle *AsyncReaderWriter::ToCompletionGroupHandle()
|
||||||
{
|
{
|
||||||
return NewLoopSource()->WaitOn(uTimeout);
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<IO::Loop::ILoopSource> NewLoopSource() override
|
AuSPtr<CompletionGroup::ICompletionGroup> AsyncReaderWriter::GetCompletionGroup()
|
||||||
{
|
{
|
||||||
return Async::APCLessWaitable::GetLoopSource();
|
return Async::APCLessWaitable::GetCompletionGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
if (this->bInProgress)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuResetMember(this->pReadView);
|
|
||||||
AuResetMember(this->pWriteView);
|
|
||||||
Async::APCLessWaitable::Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetBaseOffset(AuUInt64 uBaseOffset) override
|
|
||||||
{
|
|
||||||
this->uBaseOffset = uBaseOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryAttachToCompletionGroup(const AuSPtr<CompletionGroup::ICompletionGroup> &pCompletionGroup) override
|
|
||||||
{
|
|
||||||
return Async::APCLessWaitable::TryAttachToCompletionGroup(pCompletionGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompletionGroup::ICompletionGroupWorkHandle *ToCompletionGroupHandle() override
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<CompletionGroup::ICompletionGroup> GetCompletionGroup() override
|
|
||||||
{
|
|
||||||
return Async::APCLessWaitable::GetCompletionGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AuMutex mutex;
|
|
||||||
AuSPtr<IAsyncFinishedSubscriber> pSubscriber;
|
|
||||||
AuUInt64 uBaseOffset {};
|
|
||||||
AuUInt64 uLastOffset {};
|
|
||||||
AuUInt uLastLength {};
|
|
||||||
bool bInProgress {};
|
|
||||||
EStreamError eStreamError = EStreamError::eErrorNone;
|
|
||||||
};
|
|
||||||
|
|
||||||
static AuWorkerPId GetAuxWorkerPool()
|
static AuWorkerPId GetAuxWorkerPool()
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,66 @@
|
|||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Source/IO/Async/AuIOThreadPool.hpp>
|
||||||
|
#include <Source/IO/Async/AuIOAPCLessWaitable.hpp>
|
||||||
|
|
||||||
namespace Aurora::IO::Adapters
|
namespace Aurora::IO::Adapters
|
||||||
{
|
{
|
||||||
|
struct AsyncReaderWriter : IAsyncTransaction,
|
||||||
|
Async::APCLessWaitable,
|
||||||
|
AuAsync::IWorkItemHandler
|
||||||
|
{
|
||||||
|
AuSPtr<IStreamReader> pStreamReader;
|
||||||
|
AuSPtr<ISeekingReader> pStreamReaderEx;
|
||||||
|
AuSPtr<IStreamWriter> pStreamWriter;
|
||||||
|
AuSPtr<ISeekingWriter> pStreamWriterEx;
|
||||||
|
AuSPtr<Memory::MemoryViewRead> pReadView;
|
||||||
|
AuSPtr<Memory::MemoryViewWrite> pWriteView;
|
||||||
|
AuWorkerPId workers;
|
||||||
|
|
||||||
|
void DispatchFrame(ProcessInfo &info) override;
|
||||||
|
|
||||||
|
void OnFailure() override;
|
||||||
|
|
||||||
|
bool StartRead(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewWrite> &memoryView) override;
|
||||||
|
|
||||||
|
bool StartWrite(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewRead> &memoryView) override;
|
||||||
|
|
||||||
|
AuUInt32 GetLastPacketLength() override;
|
||||||
|
|
||||||
|
void OnOriginThreadComplete() override;
|
||||||
|
|
||||||
|
bool Complete() override;
|
||||||
|
|
||||||
|
bool HasFailed() override;
|
||||||
|
|
||||||
|
bool HasCompleted() override;
|
||||||
|
|
||||||
|
AuUInt GetOSErrorCode() override;
|
||||||
|
|
||||||
|
void SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &pSubscriber) override;
|
||||||
|
|
||||||
|
bool Wait(AuUInt32 uTimeout) override;
|
||||||
|
|
||||||
|
AuSPtr<IO::Loop::ILoopSource> NewLoopSource() override;
|
||||||
|
|
||||||
|
void Reset() override;
|
||||||
|
|
||||||
|
void SetBaseOffset(AuUInt64 uBaseOffset) override;
|
||||||
|
|
||||||
|
bool TryAttachToCompletionGroup(const AuSPtr<CompletionGroup::ICompletionGroup> &pCompletionGroup) override;
|
||||||
|
|
||||||
|
CompletionGroup::ICompletionGroupWorkHandle *ToCompletionGroupHandle() override;
|
||||||
|
|
||||||
|
AuSPtr<CompletionGroup::ICompletionGroup> GetCompletionGroup() override;
|
||||||
|
|
||||||
|
AuInt64 iBaseOffset {};
|
||||||
|
private:
|
||||||
|
AuMutex mutex;
|
||||||
|
AuSPtr<IAsyncFinishedSubscriber> pSubscriber;
|
||||||
|
AuUInt64 uLastOffset {};
|
||||||
|
AuUInt uLastLength {};
|
||||||
|
bool bInProgress {};
|
||||||
|
EStreamError eStreamError = EStreamError::eErrorNone;
|
||||||
|
};
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ namespace Aurora::IO::Adapters
|
|||||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::BlobReader>(pBuffer), {});
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::BlobReader>(pBuffer), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearReadSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
||||||
{
|
{
|
||||||
SysCheckArgNotNull(pBuffer, {});
|
SysCheckArgNotNull(pBuffer, {});
|
||||||
if (pBuffer->flagCircular)
|
if (pBuffer->flagCircular)
|
||||||
@ -29,6 +29,18 @@ namespace Aurora::IO::Adapters
|
|||||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::BlobSeekableReader>(pBuffer), {});
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::BlobSeekableReader>(pBuffer), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<ISeekingWriter> NewByteBufferLinearWriteSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
||||||
|
{
|
||||||
|
SysCheckArgNotNull(pBuffer, {});
|
||||||
|
if (pBuffer->flagCircular)
|
||||||
|
{
|
||||||
|
SysPushErrorIO("Seekable buffer must not be circular");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::BlobSeekableWriter>(pBuffer), {});
|
||||||
|
}
|
||||||
|
|
||||||
AUKN_SYM AuSPtr<IStreamWriter> NewByteBufferWriteAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
AUKN_SYM AuSPtr<IStreamWriter> NewByteBufferWriteAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
||||||
{
|
{
|
||||||
SysCheckArgNotNull(pBuffer, {});
|
SysCheckArgNotNull(pBuffer, {});
|
||||||
|
@ -18,10 +18,10 @@ namespace Aurora::IO::Adapters
|
|||||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewReader>(pView), {});
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewReader>(pView), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM AuSPtr<ISeekingReader> NewMemoryViewLinearSeekableAdapter(const AuSPtr<Memory::MemoryViewRead> &pView)
|
AUKN_SYM AuSPtr<ISeekingReader> NewMemoryViewReadSeekingAdapter(const AuSPtr<Memory::MemoryViewRead> &pView)
|
||||||
{
|
{
|
||||||
SysCheckArgNotNull(pView, {});
|
SysCheckArgNotNull(pView, {});
|
||||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewSeekableReadable>(pView), {});
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewSeekableReader>(pView), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM AuSPtr<IStreamWriter> NewMemoryViewWriteAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView)
|
AUKN_SYM AuSPtr<IStreamWriter> NewMemoryViewWriteAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView)
|
||||||
@ -29,4 +29,10 @@ namespace Aurora::IO::Adapters
|
|||||||
SysCheckArgNotNull(pView, {});
|
SysCheckArgNotNull(pView, {});
|
||||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewWriter>(pView), {});
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewWriter>(pView), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<ISeekingWriter> NewMemoryViewWriteSeekableAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView)
|
||||||
|
{
|
||||||
|
SysCheckArgNotNull(pView, {});
|
||||||
|
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewSeekableWriter>(pView), {});
|
||||||
|
}
|
||||||
}
|
}
|
@ -259,7 +259,10 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
AuUInt64 AFileHandle::GetOSHandle() const
|
AuUInt64 AFileHandle::GetOSHandle() const
|
||||||
{
|
{
|
||||||
return this->uOSReadHandle.ValueOr(this->uOSWriteHandle.value());
|
return this->uOSWriteHandle.OrElse(AuMove([=]()
|
||||||
|
{
|
||||||
|
return this->uOSReadHandle;
|
||||||
|
})).Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuUInt64 AFileHandle::GetOSReadHandle() const
|
AuUInt64 AFileHandle::GetOSReadHandle() const
|
||||||
@ -397,6 +400,17 @@ namespace Aurora::IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuUInt64 AFileHandle::GetFileLength()
|
||||||
|
{
|
||||||
|
if (this->uOSReadHandle)
|
||||||
|
{
|
||||||
|
return SysGetFileLength(this->uOSReadHandle.Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
SysPushErrorResourceInvalid();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
AUKN_SYM IIOHandle *IOHandleNew()
|
AUKN_SYM IIOHandle *IOHandleNew()
|
||||||
{
|
{
|
||||||
return _new AFileHandle();
|
return _new AFileHandle();
|
||||||
|
@ -77,6 +77,8 @@ namespace Aurora::IO
|
|||||||
bool SharingIsShared() override;
|
bool SharingIsShared() override;
|
||||||
void SharingStop() override;
|
void SharingStop() override;
|
||||||
|
|
||||||
|
AuUInt64 GetFileLength() override;
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
||||||
AuOptionalEx<AuUInt64> uOSReadHandle;
|
AuOptionalEx<AuUInt64> uOSReadHandle;
|
||||||
AuSPtr<IIOHandle> pThat;
|
AuSPtr<IIOHandle> pThat;
|
||||||
|
330
Source/IO/FS/FSMemoryMappedFile.cpp
Normal file
330
Source/IO/FS/FSMemoryMappedFile.cpp
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: FSMemoryMappedFile.cpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <Source/RuntimeInternal.hpp>
|
||||||
|
#include "FSMemoryMappedFile.hpp"
|
||||||
|
#include <Source/IO/Adapters/AuIOAdapterAsyncDelegators.hpp>
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
IIOHandle * MemoryMappedFile::ToHandle()
|
||||||
|
{
|
||||||
|
return this->pHandleShared ?
|
||||||
|
this->pHandleShared.get() :
|
||||||
|
this->handle.AsPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt MemoryMappedFile::GetBaseAddress()
|
||||||
|
{
|
||||||
|
if (this->pView)
|
||||||
|
{
|
||||||
|
return (AuUInt)this->pView->GetBasePointer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt MemoryMappedFile::GetEndAddress()
|
||||||
|
{
|
||||||
|
if (this->pView)
|
||||||
|
{
|
||||||
|
return (AuUInt)this->pView->GetBasePointer() +
|
||||||
|
this->GetLength();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt MemoryMappedFile::GetLength()
|
||||||
|
{
|
||||||
|
return this->uFileMapLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IStreamReader> MemoryMappedFile::NewStreamReader()
|
||||||
|
{
|
||||||
|
return AuMakeShared<IO::Buffered::ViewReader>(this->ToReadView(), this->pView);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IStreamWriter> MemoryMappedFile::NewStreamWriter()
|
||||||
|
{
|
||||||
|
return AuMakeShared<IO::Buffered::ViewWriter>(this->ToWriteView(), this->pView);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IAsyncTransaction> MemoryMappedFile::NewAsyncReadTransaction()
|
||||||
|
{
|
||||||
|
auto pReader = AuMakeShared<IO::Buffered::ViewSeekableReader>(this->ToReadViewAlt(), this->pView);
|
||||||
|
SysCheckNotNullMemory(pReader, {});
|
||||||
|
|
||||||
|
auto iBaseOffset = 0 -
|
||||||
|
AuInt64(this->uFileMapOffset) +
|
||||||
|
this->iAdjustStreamOffset;
|
||||||
|
|
||||||
|
pReader->GetBaseOffset() = iBaseOffset;
|
||||||
|
|
||||||
|
auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingReader(pReader, {});
|
||||||
|
SysCheckNotNullMemory(pTransaction, {});
|
||||||
|
return pTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<IAsyncTransaction> MemoryMappedFile::NewAsyncWriteTransaction()
|
||||||
|
{
|
||||||
|
auto pWriter = AuMakeShared<IO::Buffered::ViewSeekableWriter>(this->ToWriteViewAlt(), this->pView);
|
||||||
|
SysCheckNotNullMemory(pWriter, {});
|
||||||
|
|
||||||
|
auto iBaseOffset = 0 -
|
||||||
|
AuInt64(this->uFileMapOffset) +
|
||||||
|
this->iAdjustStreamOffset;
|
||||||
|
|
||||||
|
pWriter->GetBaseOffset() = iBaseOffset;
|
||||||
|
|
||||||
|
auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingWriter(pWriter, {});
|
||||||
|
SysCheckNotNullMemory(pTransaction, {});
|
||||||
|
return pTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISeekingReader *MemoryMappedFile::ToStreamSeekingReader()
|
||||||
|
{
|
||||||
|
if (this->optSeekableReader)
|
||||||
|
{
|
||||||
|
return &this->optSeekableReader.Value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISeekingWriter *MemoryMappedFile::ToStreamSeekingWriter()
|
||||||
|
{
|
||||||
|
if (this->optSeekableWriter)
|
||||||
|
{
|
||||||
|
return &this->optSeekableWriter.Value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuMemoryViewRead MemoryMappedFile::ToReadView()
|
||||||
|
{
|
||||||
|
auto pBasePointer = this->pView->GetBasePointer();
|
||||||
|
|
||||||
|
auto iBaseOffset = 0 -
|
||||||
|
AuInt64(this->uFileMapOffset) +
|
||||||
|
this->iAdjustStreamOffset;
|
||||||
|
|
||||||
|
if (iBaseOffset < 0)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pHeadPointer = pBasePointer + iBaseOffset;
|
||||||
|
|
||||||
|
return { pHeadPointer, this->GetEndAddress() - AuUInt(pHeadPointer) };
|
||||||
|
}
|
||||||
|
|
||||||
|
AuMemoryViewWrite MemoryMappedFile::ToWriteView()
|
||||||
|
{
|
||||||
|
auto pBasePointer = this->pView->GetBasePointer();
|
||||||
|
|
||||||
|
auto iBaseOffset = 0 -
|
||||||
|
AuInt64(this->uFileMapOffset) +
|
||||||
|
this->iAdjustStreamOffset;
|
||||||
|
|
||||||
|
if (iBaseOffset < 0)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pHeadPointer = pBasePointer + iBaseOffset;
|
||||||
|
|
||||||
|
return { pHeadPointer, this->GetEndAddress() - AuUInt(pHeadPointer) };
|
||||||
|
}
|
||||||
|
|
||||||
|
AuMemoryViewRead MemoryMappedFile::ToReadViewAlt()
|
||||||
|
{
|
||||||
|
auto pBasePointer = this->pView->GetBasePointer();
|
||||||
|
return { pBasePointer, this->GetEndAddress() - AuUInt(pBasePointer) };
|
||||||
|
}
|
||||||
|
|
||||||
|
AuMemoryViewWrite MemoryMappedFile::ToWriteViewAlt()
|
||||||
|
{
|
||||||
|
auto pBasePointer = this->pView->GetBasePointer();
|
||||||
|
return { pBasePointer, this->GetEndAddress() - AuUInt(pBasePointer) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryMappedFile::Flush(AuUInt uOffset,
|
||||||
|
AuUInt uLength)
|
||||||
|
{
|
||||||
|
auto iOffset = 0 - AuSInt(this->uFileMapOffset) + AuSInt(iAdjustStreamOffset) + AuSInt(uOffset);
|
||||||
|
if (iOffset < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uStartAddress = iOffset;
|
||||||
|
auto uEndAddress = AuMin(this->GetLength(), uStartAddress + uLength);
|
||||||
|
auto uSecondLength = uEndAddress - uStartAddress;
|
||||||
|
this->pView->Flush(iOffset, uSecondLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryMappedFile::Prefetch(AuUInt uOffset,
|
||||||
|
AuUInt uLength)
|
||||||
|
{
|
||||||
|
AU_DEBUG_MEMCRUNCH;
|
||||||
|
|
||||||
|
auto iOffset = 0 - AuSInt(this->uFileMapOffset) + AuSInt(iAdjustStreamOffset) + AuSInt(uOffset);
|
||||||
|
if (iOffset < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uStartAddress = this->GetBaseAddress() + iOffset;
|
||||||
|
auto uEndAddress = AuMin(this->GetEndAddress(), uStartAddress + uLength);
|
||||||
|
auto uSecondLength = uEndAddress - uStartAddress;
|
||||||
|
|
||||||
|
AuMemory::Cache::OptimizeAddressRangeOnCore({
|
||||||
|
{
|
||||||
|
uStartAddress,
|
||||||
|
uSecondLength
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryMappedFile::Init(EFileOpenMode eMode,
|
||||||
|
AuUInt64 uFileMapOffset,
|
||||||
|
AuUInt64 uFileMapLength,
|
||||||
|
AuInt64 iAdjustStreamOffset,
|
||||||
|
EFileAdvisoryLockLevel eLockLevel)
|
||||||
|
{
|
||||||
|
auto pHandle = this->ToHandle();
|
||||||
|
|
||||||
|
if (!uFileMapLength)
|
||||||
|
{
|
||||||
|
uFileMapLength = pHandle->GetFileLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this->uFileMapLength = uFileMapLength;
|
||||||
|
this->uFileMapOffset = uFileMapOffset;
|
||||||
|
this->iAdjustStreamOffset = iAdjustStreamOffset;
|
||||||
|
|
||||||
|
auto pAddressSpace = AuProcess::GetGlobalProcessSpace();
|
||||||
|
|
||||||
|
this->pView = pAddressSpace->MapFileByObject(AuUnsafeRaiiToShared(this->ToHandle()),
|
||||||
|
uFileMapOffset,
|
||||||
|
uFileMapLength,
|
||||||
|
eMode,
|
||||||
|
eLockLevel);
|
||||||
|
if (!this->pView)
|
||||||
|
{
|
||||||
|
SysPushErrorNested();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto iBaseOffset = 0 -
|
||||||
|
AuInt64(this->uFileMapOffset) +
|
||||||
|
this->iAdjustStreamOffset;
|
||||||
|
|
||||||
|
IO::Buffered::ViewSeekableReader reader(this->ToReadViewAlt(), this->pView);
|
||||||
|
IO::Buffered::ViewSeekableWriter writer(this->ToWriteViewAlt(), this->pView);
|
||||||
|
|
||||||
|
writer.GetBaseOffset() = iBaseOffset;
|
||||||
|
reader.GetBaseOffset() = iBaseOffset;
|
||||||
|
|
||||||
|
this->optSeekableReader = AuMove(reader);
|
||||||
|
this->optSeekableWriter = AuMove(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMemoryMappedFile *OpenMapNew(const AuString &path,
|
||||||
|
AuOptional<EFileOpenMode> opteMode,
|
||||||
|
AuOptional<AuUInt64> optuFileMapOffset,
|
||||||
|
AuOptional<AuUInt64> optuFileMapLength,
|
||||||
|
AuOptional<AuInt64> optiAdjustStreamOffset,
|
||||||
|
AuOptional<EFileAdvisoryLockLevel> opteAdvisoryLevel,
|
||||||
|
AuOptional<bool> optbLockEntireFile)
|
||||||
|
{
|
||||||
|
auto eMode = opteMode.ValueOr(EFileOpenMode::eRead);
|
||||||
|
auto uFileMapOffset = optuFileMapOffset.ValueOr(0);
|
||||||
|
auto uFileLength = optuFileMapLength.ValueOr(0);
|
||||||
|
auto iAdjustStreamOffset = optiAdjustStreamOffset.ValueOr(uFileMapOffset);
|
||||||
|
auto bLockEntireFile = optbLockEntireFile.ValueOr(true);
|
||||||
|
auto eAdvisoryLevel = opteAdvisoryLevel.ValueOr(EFileAdvisoryLockLevel::eBlockReadWrite);
|
||||||
|
|
||||||
|
auto pReturn = _new MemoryMappedFile();
|
||||||
|
SysCheckNotNullMemory(pReturn, {});
|
||||||
|
|
||||||
|
auto createRequest = AuIO::IIOHandle::HandleCreate::Create(path);
|
||||||
|
createRequest.eMode = eMode;
|
||||||
|
createRequest.eAdvisoryLevel = bLockEntireFile ? eAdvisoryLevel : EFileAdvisoryLockLevel::eNoSafety;
|
||||||
|
createRequest.bDirectIOMode = false;
|
||||||
|
|
||||||
|
if (!pReturn->handle->InitFromPath(createRequest))
|
||||||
|
{
|
||||||
|
delete pReturn;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pReturn->Init(eMode, uFileMapOffset, uFileLength, iAdjustStreamOffset, !bLockEntireFile ? eAdvisoryLevel : EFileAdvisoryLockLevel::eNoSafety))
|
||||||
|
{
|
||||||
|
delete pReturn;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenMapRelease(IMemoryMappedFile *pReturn)
|
||||||
|
{
|
||||||
|
AuSafeDelete<MemoryMappedFile *>(pReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMemoryMappedFile *OpenMapFromSharedHandleNew(const AuSPtr<IIOHandle> &pIOHandle,
|
||||||
|
AuOptional<AuUInt64> optuFileMapOffset,
|
||||||
|
AuOptional<AuUInt64> optuFileMapLength,
|
||||||
|
AuOptional<AuInt64> optiAdjustStreamOffset,
|
||||||
|
AuOptional<EFileAdvisoryLockLevel> opteAdvisoryLevel)
|
||||||
|
{
|
||||||
|
auto uFileMapOffset = optuFileMapOffset.ValueOr(0);
|
||||||
|
auto uFileLength = optuFileMapLength.ValueOr(0);
|
||||||
|
auto iAdjustStreamOffset = optiAdjustStreamOffset.ValueOr(uFileMapOffset);
|
||||||
|
auto eAdvisoryLevel = opteAdvisoryLevel.ValueOr(EFileAdvisoryLockLevel::eNoSafety);
|
||||||
|
|
||||||
|
SysCheckArgNotNull(pIOHandle, {});
|
||||||
|
|
||||||
|
auto pReturn = _new MemoryMappedFile();
|
||||||
|
SysCheckNotNullMemory(pReturn, {});
|
||||||
|
|
||||||
|
pReturn->pHandleShared = pIOHandle;
|
||||||
|
|
||||||
|
if (!pReturn->Init(pIOHandle->GetOSWriteHandleSafe() ? EFileOpenMode::eReadWrite : EFileOpenMode::eRead,
|
||||||
|
uFileMapOffset,
|
||||||
|
uFileLength,
|
||||||
|
iAdjustStreamOffset,
|
||||||
|
eAdvisoryLevel))
|
||||||
|
{
|
||||||
|
delete pReturn;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenMapFromSharedHandleRelease(IMemoryMappedFile *pReturn)
|
||||||
|
{
|
||||||
|
AuSafeDelete<MemoryMappedFile *>(pReturn);
|
||||||
|
}
|
||||||
|
}
|
54
Source/IO/FS/FSMemoryMappedFile.hpp
Normal file
54
Source/IO/FS/FSMemoryMappedFile.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: FSMemoryMappedFile.hpp
|
||||||
|
Date: 2024-03-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
struct MemoryMappedFile : IMemoryMappedFile
|
||||||
|
{
|
||||||
|
virtual IIOHandle * ToHandle() override;
|
||||||
|
|
||||||
|
virtual AuUInt GetBaseAddress() override;
|
||||||
|
virtual AuUInt GetEndAddress() override;
|
||||||
|
virtual AuUInt GetLength() override;
|
||||||
|
|
||||||
|
virtual AuSPtr<IStreamReader> NewStreamReader() override;
|
||||||
|
virtual AuSPtr<IStreamWriter> NewStreamWriter() override;
|
||||||
|
|
||||||
|
virtual AuSPtr<IAsyncTransaction> NewAsyncReadTransaction() override;
|
||||||
|
virtual AuSPtr<IAsyncTransaction> NewAsyncWriteTransaction() override;
|
||||||
|
|
||||||
|
virtual ISeekingReader * ToStreamSeekingReader() override;
|
||||||
|
virtual ISeekingWriter * ToStreamSeekingWriter() override;
|
||||||
|
|
||||||
|
AuMemoryViewRead ToReadView();
|
||||||
|
AuMemoryViewWrite ToWriteView();
|
||||||
|
AuMemoryViewRead ToReadViewAlt();
|
||||||
|
AuMemoryViewWrite ToWriteViewAlt();
|
||||||
|
|
||||||
|
virtual void Flush(AuUInt uOffset,
|
||||||
|
AuUInt uLength) override;
|
||||||
|
|
||||||
|
virtual void Prefetch(AuUInt uOffset,
|
||||||
|
AuUInt uLength) override;
|
||||||
|
bool Init(EFileOpenMode eMode,
|
||||||
|
AuUInt64 uFileMapOffset,
|
||||||
|
AuUInt64 uFileMapLength,
|
||||||
|
AuInt64 iAdjustStreamOffset,
|
||||||
|
EFileAdvisoryLockLevel eLockLevel);
|
||||||
|
|
||||||
|
AuIOHandle handle;
|
||||||
|
AuSPtr<AuIO::IIOHandle> pHandleShared;
|
||||||
|
AuSPtr<AuProcess::IProcessSectionMapView> pView;
|
||||||
|
AuUInt64 uFileMapLength;
|
||||||
|
AuUInt64 uFileMapOffset;
|
||||||
|
AuInt64 iAdjustStreamOffset;
|
||||||
|
AuOptional<IO::Buffered::ViewSeekableWriter> optSeekableWriter;
|
||||||
|
AuOptional<IO::Buffered::ViewSeekableReader> optSeekableReader;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user