[+] 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
@ -10,6 +10,7 @@
|
||||
namespace Aurora::IO::Adapters
|
||||
{
|
||||
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);
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
namespace Aurora::IO::Adapters
|
||||
{
|
||||
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<ISeekingWriter> NewMemoryViewWriteSeekableAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView);
|
||||
}
|
@ -11,18 +11,16 @@ namespace Aurora::IO::Buffered
|
||||
{
|
||||
struct BlobReader : IStreamReader
|
||||
{
|
||||
AU_NO_COPY(BlobReader)
|
||||
AU_COPY_MOVE(BlobReader)
|
||||
|
||||
inline BlobReader(const AuSPtr<Memory::ByteBuffer> &buffer) : buffer_(buffer) {}
|
||||
inline BlobReader(Memory::ByteBuffer &&buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
inline BlobReader(const Memory::ByteBuffer &buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
|
||||
inline BlobReader() {}
|
||||
inline ~BlobReader() {}
|
||||
inline BlobReader(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||
inline BlobReader(Memory::ByteBuffer &&buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
inline BlobReader(const Memory::ByteBuffer &buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
inline BlobReader() : pBuffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
||||
|
||||
inline virtual EStreamError IsOpen() override
|
||||
{
|
||||
auto pBuffer = this->buffer_;
|
||||
auto pBuffer = this->pBuffer_;
|
||||
if (!pBuffer)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
@ -38,7 +36,7 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError Read(const Memory::MemoryViewStreamWrite ¶meters) override
|
||||
{
|
||||
auto pBuffer = this->buffer_;
|
||||
auto pBuffer = this->pBuffer_;
|
||||
if (!pBuffer)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
@ -55,10 +53,10 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual void Close() override
|
||||
{
|
||||
AuResetMember(this->buffer_);
|
||||
AuResetMember(this->pBuffer_);
|
||||
}
|
||||
|
||||
protected:
|
||||
AuSPtr<Memory::ByteBuffer> buffer_;
|
||||
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||
};
|
||||
}
|
@ -11,18 +11,15 @@ namespace Aurora::IO::Buffered
|
||||
{
|
||||
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(Memory::ByteBuffer &&buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(AuMove(buffer))) {}
|
||||
inline BlobSeekableReader(const Memory::ByteBuffer &buffer) : buffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
|
||||
inline BlobSeekableReader() {}
|
||||
inline ~BlobSeekableReader(){}
|
||||
inline BlobSeekableReader(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||
inline BlobSeekableReader(Memory::ByteBuffer &&buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(AuMove(buffer))) {}
|
||||
inline BlobSeekableReader(const Memory::ByteBuffer &buffer) : pBuffer_(AuMakeShared<Memory::ByteBuffer>(buffer)) {}
|
||||
|
||||
inline virtual EStreamError IsOpen() override
|
||||
{
|
||||
if (!this->buffer_)
|
||||
if (!this->pBuffer_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
@ -32,27 +29,27 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError ArbitraryRead(AuUInt offset, const Memory::MemoryViewStreamWrite ¶meters) override
|
||||
{
|
||||
if (!this->buffer_)
|
||||
if (!this->pBuffer_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
|
||||
if (this->buffer_->empty())
|
||||
if (this->pBuffer_->empty())
|
||||
{
|
||||
return EStreamError::eErrorEndOfStream;
|
||||
}
|
||||
|
||||
this->buffer_->readPtr = this->buffer_->base + offset;
|
||||
parameters.outVariable = this->buffer_->Read(parameters.ptr, parameters.length);
|
||||
this->pBuffer_->readPtr = this->pBuffer_->base + offset;
|
||||
parameters.outVariable = this->pBuffer_->Read(parameters.ptr, parameters.length);
|
||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||
}
|
||||
|
||||
inline virtual void Close() override
|
||||
{
|
||||
AuResetMember(this->buffer_);
|
||||
AuResetMember(this->pBuffer_);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
AU_NO_COPY_NO_MOVE(BlobWriter)
|
||||
AU_COPY_MOVE(BlobWriter)
|
||||
|
||||
inline BlobWriter(const AuSPtr<Memory::ByteBuffer> &buffer) : buffer_(buffer) {}
|
||||
inline BlobWriter() : buffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
||||
inline BlobWriter(const AuSPtr<Memory::ByteBuffer> &buffer) : pBuffer_(buffer) {}
|
||||
inline BlobWriter() : pBuffer_(AuMakeShared<Memory::ByteBuffer>()) {}
|
||||
inline ~BlobWriter() {}
|
||||
|
||||
inline virtual EStreamError IsOpen() override
|
||||
{
|
||||
auto pBuffer = this->buffer_;
|
||||
auto pBuffer = this->pBuffer_;
|
||||
if (!pBuffer)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
@ -35,7 +35,7 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
||||
{
|
||||
auto pBuffer = this->buffer_;
|
||||
auto pBuffer = this->pBuffer_;
|
||||
if (!pBuffer)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
@ -56,15 +56,15 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual void Close() override
|
||||
{
|
||||
AuResetMember(this->buffer_);
|
||||
AuResetMember(this->pBuffer_);
|
||||
}
|
||||
|
||||
inline AuSPtr<Memory::ByteBuffer> GetBuffer()
|
||||
{
|
||||
return this->buffer_;
|
||||
return this->pBuffer_;
|
||||
}
|
||||
|
||||
private:
|
||||
AuSPtr<Memory::ByteBuffer> buffer_;
|
||||
AuSPtr<Memory::ByteBuffer> pBuffer_;
|
||||
};
|
||||
}
|
@ -7,12 +7,12 @@
|
||||
***/
|
||||
#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 "BlobSeekableReader.hpp"
|
||||
#include "BlobWriter.hpp"
|
||||
#include "BlobSeekableWriter.hpp"
|
||||
|
||||
#include "ViewReader.hpp"
|
||||
#include "ViewSeekableReadable.hpp"
|
||||
#include "ViewSeekableReader.hpp"
|
||||
#include "ViewWriter.hpp"
|
||||
#include "ViewSeekableWriter.hpp"
|
||||
|
@ -12,8 +12,12 @@ namespace Aurora::IO::Buffered
|
||||
struct ViewReader : IStreamReader
|
||||
{
|
||||
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()
|
||||
@ -24,12 +28,12 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError IsOpen() override
|
||||
{
|
||||
if (!this->pView_)
|
||||
if (!this->view_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
|
||||
if (!(*this->pView_.get()))
|
||||
if (!this->pHold)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
@ -41,27 +45,28 @@ namespace Aurora::IO::Buffered
|
||||
{
|
||||
parameters.outVariable = 0;
|
||||
|
||||
if (!this->pView_)
|
||||
if (!this->view_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
|
||||
if (!(*this->pView_.get()))
|
||||
if (!this->pHold)
|
||||
{
|
||||
this->pView_.reset();
|
||||
this->Close();
|
||||
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;
|
||||
AuMemcpy(parameters.ptr, this->pView_->Begin<AuUInt8>() + this->uOffset_, uToRead);
|
||||
AuMemcpy(parameters.ptr, this->view_.Begin<AuUInt8>() + this->uOffset_, uToRead);
|
||||
this->uOffset_ += uToRead;
|
||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||
}
|
||||
|
||||
inline virtual void Close() override
|
||||
{
|
||||
this->pView_.reset();
|
||||
AuResetMember(this->pHold);
|
||||
AuResetMember(this->view_);
|
||||
}
|
||||
|
||||
inline AuUInt &GetOffset()
|
||||
@ -74,7 +79,8 @@ namespace Aurora::IO::Buffered
|
||||
return this->uOffset_;
|
||||
}
|
||||
private:
|
||||
AuSPtr<Memory::MemoryViewRead> pView_;
|
||||
Memory::MemoryViewRead view_;
|
||||
AuSPtr<void> pHold;
|
||||
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
|
||||
{
|
||||
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()
|
||||
@ -24,12 +28,12 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError IsOpen() override
|
||||
{
|
||||
if (!this->pView_)
|
||||
if (!this->view_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
|
||||
if (!(*this->pView_.get()))
|
||||
if (!this->pHold)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
@ -39,26 +43,27 @@ namespace Aurora::IO::Buffered
|
||||
|
||||
inline virtual EStreamError Write(const Memory::MemoryViewStreamRead ¶meters) override
|
||||
{
|
||||
if (!this->pView_)
|
||||
if (!this->view_)
|
||||
{
|
||||
return EStreamError::eErrorStreamNotOpen;
|
||||
}
|
||||
|
||||
if (!(*this->pView_.get()))
|
||||
if (!this->pHold)
|
||||
{
|
||||
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;
|
||||
AuMemcpy(this->pView_->Begin<AuUInt8>() + this->uOffset_, parameters.ptr, uToRead);
|
||||
AuMemcpy(this->view_.Begin<AuUInt8>() + this->uOffset_, parameters.ptr, uToRead);
|
||||
this->uOffset_ += uToRead;
|
||||
return parameters.outVariable == 0 ? EStreamError::eErrorEndOfStream : EStreamError::eErrorNone;
|
||||
}
|
||||
|
||||
inline virtual void Close() override
|
||||
{
|
||||
this->pView_.reset();
|
||||
AuResetMember(this->pHold);
|
||||
AuResetMember(this->view_);
|
||||
}
|
||||
|
||||
inline virtual void Flush() override
|
||||
@ -76,7 +81,8 @@ namespace Aurora::IO::Buffered
|
||||
return this->uOffset_;
|
||||
}
|
||||
private:
|
||||
AuSPtr<Memory::MemoryViewWrite> pView_;
|
||||
Memory::MemoryViewWrite view_;
|
||||
AuSPtr<void> pHold;
|
||||
AuUInt uOffset_ {};
|
||||
};
|
||||
}
|
@ -314,7 +314,9 @@ namespace Aurora::IO::FS
|
||||
#include "Resources.hpp"
|
||||
#include "Stat.hpp"
|
||||
#include "IAsyncFileStream.hpp"
|
||||
#include "IMemoryMappedFile.hpp"
|
||||
#include "Async.hpp"
|
||||
#include "Watcher.hpp"
|
||||
#include "IReadDir.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 void SharingStop() = 0;
|
||||
|
||||
virtual AuUInt64 GetFileLength() = 0;
|
||||
};
|
||||
|
||||
AUKN_SHARED_SOO_CC(IOHandle, IIOHandle, 256);
|
||||
|
@ -749,4 +749,17 @@ namespace Aurora
|
||||
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;
|
||||
}
|
||||
|
||||
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
||||
{
|
||||
return PosixGetLength(uOSHandle);
|
||||
}
|
||||
}
|
@ -43,4 +43,6 @@ namespace Aurora
|
||||
AuUInt32 dwCount);
|
||||
|
||||
void SysWakeAllOnAddress(const void *pAddress);
|
||||
|
||||
AuUInt64 SysGetFileLength(AuUInt uOSHandle);
|
||||
}
|
@ -12,23 +12,15 @@
|
||||
|
||||
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 AsyncReaderWriter::DispatchFrame(ProcessInfo &info)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this->pReadView)
|
||||
if (this->iBaseOffset + AuInt64(this->uLastOffset) < 0)
|
||||
{
|
||||
this->eStreamError = EStreamError::eErrorOutOfBounds;
|
||||
}
|
||||
else if (this->pReadView)
|
||||
{
|
||||
if (this->pStreamWriter)
|
||||
{
|
||||
@ -36,7 +28,7 @@ namespace Aurora::IO::Adapters
|
||||
}
|
||||
else if (this->pStreamWriterEx)
|
||||
{
|
||||
this->eStreamError = this->pStreamWriterEx->ArbitraryWrite(this->uBaseOffset + this->uLastOffset, AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
||||
this->eStreamError = this->pStreamWriterEx->ArbitraryWrite(this->iBaseOffset + this->uLastOffset, AuMemoryViewStreamRead(*this->pReadView, this->uLastLength));
|
||||
}
|
||||
}
|
||||
else if (this->pWriteView)
|
||||
@ -47,7 +39,7 @@ namespace Aurora::IO::Adapters
|
||||
}
|
||||
else if (this->pStreamReaderEx)
|
||||
{
|
||||
this->eStreamError = this->pStreamReaderEx->ArbitraryRead(this->uBaseOffset + this->uLastOffset, AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
||||
this->eStreamError = this->pStreamReaderEx->ArbitraryRead(this->iBaseOffset + this->uLastOffset, AuMemoryViewStreamWrite(*this->pWriteView, this->uLastLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,13 +52,13 @@ namespace Aurora::IO::Adapters
|
||||
this->SignalComplete();
|
||||
}
|
||||
|
||||
void OnFailure() override
|
||||
void AsyncReaderWriter::OnFailure()
|
||||
{
|
||||
this->bInProgress = false;
|
||||
this->Reset();
|
||||
}
|
||||
|
||||
bool StartRead(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewWrite> &memoryView) override
|
||||
bool AsyncReaderWriter::StartRead(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewWrite> &memoryView)
|
||||
{
|
||||
if (!memoryView)
|
||||
{
|
||||
@ -99,7 +91,7 @@ namespace Aurora::IO::Adapters
|
||||
return pThat->Dispatch();
|
||||
}
|
||||
|
||||
bool StartWrite(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewRead> &memoryView) override
|
||||
bool AsyncReaderWriter::StartWrite(AuUInt64 uOffset, const AuSPtr<Memory::MemoryViewRead> &memoryView)
|
||||
{
|
||||
if (!memoryView)
|
||||
{
|
||||
@ -132,59 +124,59 @@ namespace Aurora::IO::Adapters
|
||||
return pThat->Dispatch();
|
||||
}
|
||||
|
||||
AuUInt32 GetLastPacketLength() override
|
||||
AuUInt32 AsyncReaderWriter::GetLastPacketLength()
|
||||
{
|
||||
return this->uLastLength;
|
||||
}
|
||||
|
||||
void OnOriginThreadComplete() override
|
||||
void AsyncReaderWriter::OnOriginThreadComplete()
|
||||
{
|
||||
if (this->pSubscriber)
|
||||
{
|
||||
this->pSubscriber->OnAsyncFileOpFinished(this->uBaseOffset + this->uLastOffset, this->GetLastPacketLength());
|
||||
this->pSubscriber->OnAsyncFileOpFinished(this->uLastOffset, this->GetLastPacketLength());
|
||||
}
|
||||
|
||||
AuResetMember(this->pReadView);
|
||||
AuResetMember(this->pWriteView);
|
||||
}
|
||||
|
||||
bool Complete() override
|
||||
bool AsyncReaderWriter::Complete()
|
||||
{
|
||||
Async::APCLessWaitable::CheckLocal();
|
||||
return Async::APCLessWaitable::HasBeenSignaled();
|
||||
}
|
||||
|
||||
bool HasFailed() override
|
||||
bool AsyncReaderWriter::HasFailed()
|
||||
{
|
||||
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError != EStreamError::eErrorNone;
|
||||
}
|
||||
|
||||
bool HasCompleted() override
|
||||
bool AsyncReaderWriter::HasCompleted()
|
||||
{
|
||||
return Async::APCLessWaitable::HasBeenSignaled() && this->eStreamError == EStreamError::eErrorNone;
|
||||
}
|
||||
|
||||
AuUInt GetOSErrorCode() override
|
||||
AuUInt AsyncReaderWriter::GetOSErrorCode()
|
||||
{
|
||||
return this->HasFailed() ? AuUInt(this->eStreamError) : 0;
|
||||
}
|
||||
|
||||
void SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &pSubscriber) override
|
||||
void AsyncReaderWriter::SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &pSubscriber)
|
||||
{
|
||||
this->pSubscriber = pSubscriber;
|
||||
}
|
||||
|
||||
bool Wait(AuUInt32 uTimeout) override
|
||||
bool AsyncReaderWriter::Wait(AuUInt32 uTimeout)
|
||||
{
|
||||
return NewLoopSource()->WaitOn(uTimeout);
|
||||
}
|
||||
|
||||
AuSPtr<IO::Loop::ILoopSource> NewLoopSource() override
|
||||
AuSPtr<IO::Loop::ILoopSource> AsyncReaderWriter::NewLoopSource()
|
||||
{
|
||||
return Async::APCLessWaitable::GetLoopSource();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void AsyncReaderWriter::Reset()
|
||||
{
|
||||
if (this->bInProgress)
|
||||
{
|
||||
@ -196,35 +188,26 @@ namespace Aurora::IO::Adapters
|
||||
Async::APCLessWaitable::Reset();
|
||||
}
|
||||
|
||||
void SetBaseOffset(AuUInt64 uBaseOffset) override
|
||||
void AsyncReaderWriter::SetBaseOffset(AuUInt64 uBaseOffset)
|
||||
{
|
||||
this->uBaseOffset = uBaseOffset;
|
||||
this->iBaseOffset = uBaseOffset;
|
||||
}
|
||||
|
||||
bool TryAttachToCompletionGroup(const AuSPtr<CompletionGroup::ICompletionGroup> &pCompletionGroup) override
|
||||
bool AsyncReaderWriter::TryAttachToCompletionGroup(const AuSPtr<CompletionGroup::ICompletionGroup> &pCompletionGroup)
|
||||
{
|
||||
return Async::APCLessWaitable::TryAttachToCompletionGroup(pCompletionGroup);
|
||||
}
|
||||
|
||||
CompletionGroup::ICompletionGroupWorkHandle *ToCompletionGroupHandle() override
|
||||
CompletionGroup::ICompletionGroupWorkHandle *AsyncReaderWriter::ToCompletionGroupHandle()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
AuSPtr<CompletionGroup::ICompletionGroup> GetCompletionGroup() override
|
||||
AuSPtr<CompletionGroup::ICompletionGroup> AsyncReaderWriter::GetCompletionGroup()
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -7,6 +7,66 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include <Source/IO/Async/AuIOThreadPool.hpp>
|
||||
#include <Source/IO/Async/AuIOAPCLessWaitable.hpp>
|
||||
|
||||
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), {});
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
||||
AUKN_SYM AuSPtr<ISeekingReader> NewByteBufferLinearReadSeekableAdapter(const AuSPtr<Memory::ByteBuffer> &pBuffer)
|
||||
{
|
||||
SysCheckArgNotNull(pBuffer, {});
|
||||
if (pBuffer->flagCircular)
|
||||
@ -29,6 +29,18 @@ namespace Aurora::IO::Adapters
|
||||
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)
|
||||
{
|
||||
SysCheckArgNotNull(pBuffer, {});
|
||||
|
@ -18,10 +18,10 @@ namespace Aurora::IO::Adapters
|
||||
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, {});
|
||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewSeekableReadable>(pView), {});
|
||||
SysCheckRetExpNotNullMemory(AuMakeShared<Buffered::ViewSeekableReader>(pView), {});
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<IStreamWriter> NewMemoryViewWriteAdapter(const AuSPtr<Memory::MemoryViewWrite> &pView)
|
||||
@ -29,4 +29,10 @@ namespace Aurora::IO::Adapters
|
||||
SysCheckArgNotNull(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
|
||||
{
|
||||
return this->uOSReadHandle.ValueOr(this->uOSWriteHandle.value());
|
||||
return this->uOSWriteHandle.OrElse(AuMove([=]()
|
||||
{
|
||||
return this->uOSReadHandle;
|
||||
})).Value();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return _new AFileHandle();
|
||||
|
@ -77,6 +77,8 @@ namespace Aurora::IO
|
||||
bool SharingIsShared() override;
|
||||
void SharingStop() override;
|
||||
|
||||
AuUInt64 GetFileLength() override;
|
||||
|
||||
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
||||
AuOptionalEx<AuUInt64> uOSReadHandle;
|
||||
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