diff --git a/Include/Aurora/IO/Protocol/IProtocolPiece.hpp b/Include/Aurora/IO/Protocol/IProtocolPiece.hpp index af83283f..5e87683f 100644 --- a/Include/Aurora/IO/Protocol/IProtocolPiece.hpp +++ b/Include/Aurora/IO/Protocol/IProtocolPiece.hpp @@ -68,6 +68,8 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr GetShortPipeInterceptor() = 0; + virtual AuOptional ExchangeMaximumBufferLength(AuOptional optMax) = 0; + AURT_ADD_USR_DATA; }; } \ No newline at end of file diff --git a/Include/Aurora/IO/Protocol/IProtocolStack.hpp b/Include/Aurora/IO/Protocol/IProtocolStack.hpp index df4b5340..0abbad21 100644 --- a/Include/Aurora/IO/Protocol/IProtocolStack.hpp +++ b/Include/Aurora/IO/Protocol/IProtocolStack.hpp @@ -9,7 +9,9 @@ namespace Aurora::IO::Protocol { - struct IProtocolStack : IProtocolBaseReader, IProtocolBaseWriter + struct IProtocolStack : + IProtocolBaseReader, + IProtocolBaseWriter { /** * @brief @@ -37,6 +39,14 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr AppendInterceptorEx(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize) = 0; + /** + * @brief defer to AppendInterceptorEx + * @param pInterceptorEx + * @param uOutputBufferSize + * @return + */ + virtual AuSPtr AppendInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferDefaultSize, AuUInt uOutputBufferMaximumSize) = 0; + /** * @brief Inserts the interceptor at the bottom of the protocol stack * @param pInterceptorEx @@ -72,6 +82,15 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr PrependSingleFrameProcessor(const AuSPtr &pInterceptorEx) = 0; + /** + * @brief Defer to AppendSingleFrameProcessor + * @param pInterceptorEx + * @param uOutputBufferSize + * @param uOutputBufferSizeMax + * @return + */ + virtual AuSPtr PrependSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferDefaultSize, AuUInt uOutputBufferMaximumSize) = 0; + /** * @brief See: AppendSingleFrameProcessor * @param pInterceptorEx @@ -79,6 +98,15 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr AppendSingleFrameProcessorEx(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize) = 0; + /** + * @brief + * @param pInterceptorEx + * @param uOutputBufferSize + * @param uOutputBufferSizeMax + * @return + */ + virtual AuSPtr AppendSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferDefaultSize, AuUInt uOutputBufferMaximumSize) = 0; + /** * @brief * @param pInterceptorEx @@ -87,6 +115,14 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr PrependSingleFrameProcessorEx(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize) = 0; + /** + * @brief defer to PrependSingleFrameProcessorEx + * @param pInterceptorEx + * @param uOutputBufferSize + * @return + */ + virtual AuSPtr PrependInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferDefaultSize, AuUInt uOutputBufferMaximumSize) = 0; + /** * @brief * @param pInterceptor @@ -119,6 +155,8 @@ namespace Aurora::IO::Protocol */ virtual AuSPtr GetInterceptorAtIndex(AuUInt32 uIndex) = 0; + virtual bool IsValid() = 0; + AURT_ADD_USR_DATA; }; diff --git a/Source/IO/Protocol/AuProtocolPiece.cpp b/Source/IO/Protocol/AuProtocolPiece.cpp index a4f72845..f6509e5b 100644 --- a/Source/IO/Protocol/AuProtocolPiece.cpp +++ b/Source/IO/Protocol/AuProtocolPiece.cpp @@ -145,4 +145,19 @@ namespace Aurora::IO::Protocol { return this->pInterceptor; } + + AuOptional ProtocolPiece::ExchangeMaximumBufferLength(AuOptional optMax) + { + if (!optMax) + { + return {}; + } + + if (!this->uMax) + { + return {}; + } + + return AuExchange(this->uMax, optMax); + } } \ No newline at end of file diff --git a/Source/IO/Protocol/AuProtocolPiece.hpp b/Source/IO/Protocol/AuProtocolPiece.hpp index 7f0ea392..b1fe50de 100644 --- a/Source/IO/Protocol/AuProtocolPiece.hpp +++ b/Source/IO/Protocol/AuProtocolPiece.hpp @@ -12,7 +12,9 @@ namespace Aurora::IO::Protocol struct IProtocolNext; struct ProtocolStack; - struct ProtocolPiece : IProtocolPiece, AuEnableSharedFromThis + struct ProtocolPiece : + IProtocolPiece, + AuEnableSharedFromThis { ProtocolStack *pParent; AuSPtr pInterceptor; @@ -22,7 +24,8 @@ namespace Aurora::IO::Protocol AuByteBuffer outputBuffer; AuSPtr pOuputWriter; bool bMultipleTick {}; - + AuOptional uMax; + AuUInt64 uStartingSize {}; AuSPtr GetParent() override; AuSPtr GetNextPiece() override; @@ -33,5 +36,6 @@ namespace Aurora::IO::Protocol AuSPtr GetNextPieceBuffer() override; AuSPtr GetExtendedInterceptor() override; AuSPtr GetShortPipeInterceptor() override; + AuOptional ExchangeMaximumBufferLength(AuOptional optMax) override; }; } \ No newline at end of file diff --git a/Source/IO/Protocol/AuProtocolStack.cpp b/Source/IO/Protocol/AuProtocolStack.cpp index 0bb0d6e6..023e09b6 100644 --- a/Source/IO/Protocol/AuProtocolStack.cpp +++ b/Source/IO/Protocol/AuProtocolStack.cpp @@ -58,6 +58,26 @@ namespace Aurora::IO::Protocol return this->AddInterceptorWhereEx(true, pInterceptorEx, uOutputBufferSize, true); } + AuSPtr ProtocolStack::AppendInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) + { + return this->AddInterceptorWhereEx(false, pInterceptorEx, uOutputBufferSize, false, uOutputBufferSizeMax); + } + + AuSPtr ProtocolStack::PrependInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) + { + return this->AddInterceptorWhereEx(true, pInterceptorEx, uOutputBufferSize, false, uOutputBufferSizeMax); + } + + AuSPtr ProtocolStack::PrependSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) + { + return this->AddInterceptorWhereEx(true, pInterceptorEx, uOutputBufferSize, true, uOutputBufferSizeMax); + } + + AuSPtr ProtocolStack::AppendSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) + { + return this->AddInterceptorWhereEx(false, pInterceptorEx, uOutputBufferSize, true, uOutputBufferSizeMax); + } + AuSPtr ProtocolStack::PrependInterceptor(const AuSPtr &pInterceptor, AuUInt uOutputBufferSize) { @@ -195,7 +215,8 @@ namespace Aurora::IO::Protocol AuSPtr ProtocolStack::AddInterceptorWhereEx(bool bPrepend, const AuSPtr &pInterceptor, AuUInt uOutputBufferSize, - bool bMultipleTick) + bool bMultipleTick, + AuOptional uMax) { AU_LOCK_GUARD(this->mutex); @@ -228,6 +249,14 @@ namespace Aurora::IO::Protocol return {}; } + if (uMax) + { + pNew->uMax = uMax; + pNew->outputBuffer.flagAlwaysExpandable = pNew->outputBuffer.flagExpandable = 1; + } + + pNew->uStartingSize = uOutputBufferSize; + // Circular ref pNew->pOuputWriter = AuMakeShared(AuSPtr(pNew, &pNew->outputBuffer)); @@ -635,7 +664,10 @@ namespace Aurora::IO::Protocol } } - if (!pCurrent->pInterceptorEx->OnDataAvailable(pRead, pNextStream, pCurrent)) + bool bStatus = pCurrent->pInterceptorEx->OnDataAvailable(pRead, pNextStream, pCurrent); + + + if (!bStatus) { if (pNextStream) { @@ -644,6 +676,37 @@ namespace Aurora::IO::Protocol return bTryAgainAtleastOnce; } + else + { + if (pCurrent->uMax.has_value()) + { + auto bytesRem = pCurrent->outputBuffer.RemainingBytes(); + auto maxVal = pCurrent->uMax.value(); + if (bytesRem >= maxVal) + { + this->Terminate(); + return false; + } + + auto target = AuMin(AuPageRound(bytesRem + ((bytesRem / 4) * 3), 128), maxVal); + target = AuMax(target, pCurrent->uStartingSize); + + if (target >= pCurrent->outputBuffer.allocSize || + ((pCurrent->outputBuffer.length > target) && (bytesRem < pCurrent->uStartingSize))) + { + AuByteBuffer replacement(target, true, false); + if (!replacement.WriteFrom(pCurrent->outputBuffer)) + { + this->Terminate(); + return false; + } + + pCurrent->outputBuffer = AuMove(replacement); + pCurrent->outputBuffer.flagAlwaysExpandable = + pCurrent->outputBuffer.flagExpandable = 1; + } + } + } if (!pNextStream) { @@ -743,6 +806,11 @@ namespace Aurora::IO::Protocol return {}; } + bool ProtocolStack::IsValid() + { + return !this->bDead; + } + void ProtocolStack::DiscardAllocCaches() { AuResetMember(this->pStreamReaderCache); diff --git a/Source/IO/Protocol/AuProtocolStack.hpp b/Source/IO/Protocol/AuProtocolStack.hpp index df4c0622..8545a3af 100644 --- a/Source/IO/Protocol/AuProtocolStack.hpp +++ b/Source/IO/Protocol/AuProtocolStack.hpp @@ -39,12 +39,19 @@ namespace Aurora::IO::Protocol AuSPtr PrependSingleFrameProcessor(const AuSPtr &pInterceptorEx) override; AuSPtr PrependSingleFrameProcessorEx(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize) override; + + AuSPtr AppendInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) override; + AuSPtr PrependInterceptorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) override; + + AuSPtr PrependSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) override; + AuSPtr AppendSingleFrameProcessorDynamicBuffer(const AuSPtr &pInterceptorEx, AuUInt uOutputBufferSize, AuUInt uOutputBufferSizeMax) override; + AuSPtr AddEndInterceptor(const AuSPtr &pInterceptor) override; void Destroy() override; AuSPtr AddInterceptorWhere(bool bPrepend, const AuSPtr &pInterceptor, AuUInt uOutputBufferSize); - AuSPtr AddInterceptorWhereEx(bool bPrepend, const AuSPtr &pInterceptor, AuUInt uOutputBufferSize, bool bMultipleTick); + AuSPtr AddInterceptorWhereEx(bool bPrepend, const AuSPtr &pInterceptor, AuUInt uOutputBufferSize, bool bMultipleTick, AuOptional uMax = {}); AuSPtr AsStreamWriter() override; AuSPtr AsWritableByteBuffer() override; @@ -55,6 +62,8 @@ namespace Aurora::IO::Protocol AuList> GetArrayOfInterceptors() override; AuSPtr GetInterceptorAtIndex(AuUInt32 uIndex) override; + bool IsValid() override; + EProtocolStackCreateType eType; bool bDead {};