/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuProtocolPiece.cpp Date: 2022-8-24 Author: Reece ***/ #include "Protocol.hpp" #include "AuProtocolPiece.hpp" #include "AuProtocolStack.hpp" #include "IProtocolNext.hpp" // TODO: check correct thread or throw api // restrict this to one thread namespace Aurora::IO::Protocol { AuSPtr ProtocolPiece::GetParent() { if (this->pParent) { return this->pParent->SharedFromThis(); } else { return {}; } } AuSPtr ProtocolPiece::ToNextWriter() { if (!this->pParent) { return {}; } AU_LOCK_GUARD(this->pParent->mutex); if (this->pParent->pTopPiece.get() == this) { if (this->pParent->pDrainBuffer) { return AuMakeShared(this->pParent->pDrainBuffer); } } return this->pNext ? this->pNext->pWriteInteface->GetStreamWriter() : this->pOuputWriter; } AuSPtr ProtocolPiece::ToInputWriter() { return this->pWriteInteface ? this->pWriteInteface->GetStreamWriter() : AuSPtr {}; } AuSPtr ProtocolPiece::GetNextPiece() { return this->pNext; } bool ProtocolPiece::ReallocateDrainBuffer(AuUInt32 uOutputLength) { if (!this->pParent) { return false; } AU_LOCK_GUARD(this->pParent->mutex); if (!this->pNext) { if (this->pParent->pDrainBuffer) { return false; } } this->outputBuffer.flagNoFree = false; auto bRet = this->outputBuffer.Resize(uOutputLength); if (!this->uMax.has_value()) { this->outputBuffer.flagNoFree = true; } return bRet; } void ProtocolPiece::Remove() { this->PrivateUserDataClear(); if (!this->pParent) { return; } AU_LOCK_GUARD(this->pParent->mutex); auto &pBottomPiece = this->pParent->pBottomPiece; // fix chain AuSPtr pLast; auto pCurrent = pBottomPiece; while (true) { if (!pCurrent) { break; } if (pCurrent.get() == this) { AuReinterpretCast(pLast)->pNext = pCurrent->pNext; break; } pLast = pCurrent; pCurrent = pCurrent->pNext; } // fix head pointers if (this->pParent->pTopPiece.get() == this) { this->pParent->pTopPiece = AuReinterpretCast(pLast); this->pParent->bWrittenEnd = false; } if (this->pParent->pBottomPiece.get() == this) { this->pParent->pBottomPiece = this->pNext; } this->PrivateUserDataClear(); this->pParent->DiscardAllocCaches(); this->pParent = nullptr; } AuSPtr ProtocolPiece::GetNextPieceBuffer() { return AuSPtr(AuSharedFromThis(), &this->outputBuffer); } AuSPtr ProtocolPiece::GetExtendedInterceptor() { return this->pInterceptorEx; } AuSPtr ProtocolPiece::GetShortPipeInterceptor() { return this->pInterceptor; } AuOptional ProtocolPiece::ExchangeMaximumBufferLength(AuOptional optMax) { if (!optMax) { return {}; } if (!this->uMax) { return {}; } return AuExchange(this->uMax, optMax); } }