diff --git a/Include/Aurora/IO/Protocol/IProtocolPiece.hpp b/Include/Aurora/IO/Protocol/IProtocolPiece.hpp index 5e87683f..46d9df0b 100644 --- a/Include/Aurora/IO/Protocol/IProtocolPiece.hpp +++ b/Include/Aurora/IO/Protocol/IProtocolPiece.hpp @@ -25,6 +25,12 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr GetNextPiece() = 0; + /** + * @brief + * @return + */ + virtual AuSPtr GetPreviousPiece() = 0; + /** * @brief * @param uOutputLength @@ -32,6 +38,13 @@ namespace Aurora::IO::Protocol */ virtual bool ReallocateDrainBuffer(AuUInt32 uOutputLength) = 0; + /** + * @brief + * @param uInputLength + * @return + */ + virtual bool ReallocateSourceBuffer(AuUInt32 uInputLength) = 0; + /** * @brief Removes this piece from the stack */ @@ -41,13 +54,19 @@ namespace Aurora::IO::Protocol * @brief * @return */ - virtual AuSPtr ToInputWriter() = 0; + virtual AuSPtr GetInputWriter() = 0; + + /** + * @brief + * @return + */ + virtual AuSPtr GetOutputReader() = 0; /** * @brief Fetches an IStreamWriter representation of the next piece in the stack * @return */ - virtual AuSPtr ToNextWriter() = 0; + virtual AuSPtr GetNextWriter() = 0; /** * @brief diff --git a/Source/IO/Protocol/AuProtocolPiece.cpp b/Source/IO/Protocol/AuProtocolPiece.cpp index c1c47778..2355999c 100644 --- a/Source/IO/Protocol/AuProtocolPiece.cpp +++ b/Source/IO/Protocol/AuProtocolPiece.cpp @@ -28,7 +28,7 @@ namespace Aurora::IO::Protocol } } - AuSPtr ProtocolPiece::ToNextWriter() + AuSPtr ProtocolPiece::GetNextWriter() { if (!this->pParent) { @@ -50,7 +50,7 @@ namespace Aurora::IO::Protocol this->pOuputWriter; } - AuSPtr ProtocolPiece::ToInputWriter() + AuSPtr ProtocolPiece::GetInputWriter() { return this->pWriteInteface ? this->pWriteInteface->GetStreamWriter() : AuSPtr {}; } @@ -60,6 +60,17 @@ namespace Aurora::IO::Protocol return this->pNext; } + AuSPtr ProtocolPiece::GetPreviousPiece() + { + return this->pBefore; + } + + AuSPtr ProtocolPiece::GetOutputReader() + { + // TODO: cache if required + return IO::Adapters::NewByteBufferReadAdapter(AuSPtr(this->SharedFromThis(), &this->outputBuffer)); + } + bool ProtocolPiece::ReallocateDrainBuffer(AuUInt32 uOutputLength) { if (!this->pParent) @@ -86,6 +97,40 @@ namespace Aurora::IO::Protocol return bRet; } + bool ProtocolPiece::ReallocateSourceBuffer(AuUInt32 uInputLength) + { + if (!this->pParent) + { + return false; + } + + AU_LOCK_GUARD(this->pParent->mutex); + + if (auto pBefore = this->pBefore) + { + if (pBefore->outputBuffer) + { + pBefore->outputBuffer.flagNoRealloc = false; + auto bRet = pBefore->outputBuffer.Resize(uInputLength); + if (!pBefore->uMax.has_value()) + { + pBefore->outputBuffer.flagNoRealloc = true; + } + return bRet; + } + } + else + { + if (this->pParent->bOwnsSource && + this->pParent->pSourceBufer) + { + return this->pParent->pSourceBufer->Resize(uInputLength); + } + } + + return false; + } + void ProtocolPiece::Remove() { this->PrivateUserDataClear(); @@ -99,7 +144,7 @@ namespace Aurora::IO::Protocol auto &pBottomPiece = this->pParent->pBottomPiece; // fix chain - AuSPtr pLast; + AuSPtr pLast; auto pCurrent = pBottomPiece; while (true) { @@ -110,7 +155,11 @@ namespace Aurora::IO::Protocol if (pCurrent.get() == this) { - AuReinterpretCast(pLast)->pNext = pCurrent->pNext; + if (auto pNext = pCurrent->pNext) + { + pNext->pBefore = pLast; + } + pLast->pNext = pCurrent->pNext; break; } diff --git a/Source/IO/Protocol/AuProtocolPiece.hpp b/Source/IO/Protocol/AuProtocolPiece.hpp index b1fe50de..2c494033 100644 --- a/Source/IO/Protocol/AuProtocolPiece.hpp +++ b/Source/IO/Protocol/AuProtocolPiece.hpp @@ -21,18 +21,23 @@ namespace Aurora::IO::Protocol AuSPtr pInterceptorEx; AuSPtr pWriteInteface; AuSPtr pNext; + AuSPtr pBefore; AuByteBuffer outputBuffer; AuSPtr pOuputWriter; bool bMultipleTick {}; AuOptional uMax; AuUInt64 uStartingSize {}; + friend struct ProtocolStack; // IProtocolPiece::PrivateUserDataClear() AuSPtr GetParent() override; AuSPtr GetNextPiece() override; + AuSPtr GetPreviousPiece() override; bool ReallocateDrainBuffer(AuUInt32 uOutputLength) override; + bool ReallocateSourceBuffer(AuUInt32 uInputLength) override; void Remove() override; - AuSPtr ToNextWriter() override; - AuSPtr ToInputWriter() override; + AuSPtr GetNextWriter() override; + AuSPtr GetInputWriter() override; + AuSPtr GetOutputReader() override; AuSPtr GetNextPieceBuffer() override; AuSPtr GetExtendedInterceptor() override; AuSPtr GetShortPipeInterceptor() override; diff --git a/Source/IO/Protocol/AuProtocolStack.cpp b/Source/IO/Protocol/AuProtocolStack.cpp index e5c1be11..06e7e898 100644 --- a/Source/IO/Protocol/AuProtocolStack.cpp +++ b/Source/IO/Protocol/AuProtocolStack.cpp @@ -203,9 +203,10 @@ namespace Aurora::IO::Protocol if (eWhere == EProtocolWhere::ePrepend) { - if (this->pBottomPiece) + if (auto pBottomPiece = this->pBottomPiece) { - pNew->pNext = this->pBottomPiece; + pBottomPiece->pBefore = pNew; + pNew->pNext = pBottomPiece; } this->pBottomPiece = pNew; @@ -214,6 +215,7 @@ namespace Aurora::IO::Protocol { if (this->pTopPiece) { + pNew->pBefore = this->pTopPiece; this->pTopPiece->pNext = pNew; } @@ -365,9 +367,10 @@ namespace Aurora::IO::Protocol if (eWhere == EProtocolWhere::ePrepend) { - if (this->pBottomPiece) + if (auto pBottomPiece = this->pBottomPiece) { - pNew->pNext = this->pBottomPiece; + pBottomPiece->pBefore = pNew; + pNew->pNext = pBottomPiece; } this->pBottomPiece = pNew; @@ -376,6 +379,7 @@ namespace Aurora::IO::Protocol { if (this->pTopPiece) { + pNew->pBefore = this->pTopPiece; this->pTopPiece->pNext = pNew; } @@ -483,6 +487,7 @@ namespace Aurora::IO::Protocol if (this->pTopPiece) { + pNew->pBefore = this->pTopPiece; this->pTopPiece->pNext = pNew; } @@ -518,10 +523,12 @@ namespace Aurora::IO::Protocol auto pCur = pItr; pItr = pCur->pNext; pCur->pNext.reset(); + pCur->pBefore.reset(); pCur->pInterceptor.reset(); pCur->pInterceptorEx.reset(); pCur->pOuputWriter.reset(); pCur->pWriteInteface.reset(); + pCur->PrivateUserDataClear(); } this->pBottomPiece.reset(); @@ -815,7 +822,7 @@ namespace Aurora::IO::Protocol pBase = pRead->readPtr; } - auto pNextStream = pCurrent->ToNextWriter(); + auto pNextStream = pCurrent->GetNextWriter(); if (!pCurrent->pInterceptor->OnDataAvailable({ pBase, uCount }, pNextStream)) { diff --git a/Source/IO/TLS/TLSContext.cpp b/Source/IO/TLS/TLSContext.cpp index 426eb4fb..5d25985e 100644 --- a/Source/IO/TLS/TLSContext.cpp +++ b/Source/IO/TLS/TLSContext.cpp @@ -97,7 +97,7 @@ namespace Aurora::IO::TLS { AuUInt count {}; if (Aurora::IO::EStreamError::eErrorNone != - pPiece->ToNextWriter()->Write(AuMemoryViewStreamRead { AuMemoryViewRead { pIn, length }, count })) + pPiece->GetNextWriter()->Write(AuMemoryViewStreamRead { AuMemoryViewRead { pIn, length }, count })) { SysPushErrorIO("TLS couldn't flush write into next protocol layer or drain"); return -1;