Index: src/libchcore/TOrderedBufferQueue.cpp
===================================================================
diff -u -N -r1506d51ff1c0a5d156dab398051efc0c87473e81 -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9
--- src/libchcore/TOrderedBufferQueue.cpp	(.../TOrderedBufferQueue.cpp)	(revision 1506d51ff1c0a5d156dab398051efc0c87473e81)
+++ src/libchcore/TOrderedBufferQueue.cpp	(.../TOrderedBufferQueue.cpp)	(revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9)
@@ -19,17 +19,81 @@
 #include "stdafx.h"
 #include "TOrderedBufferQueue.h"
 #include "TOverlappedDataBuffer.h"
-#include "TCoreException.h"
 
 namespace chcore
 {
-	bool CompareBufferPositions::operator()(const TOverlappedDataBuffer* pBufferA, const TOverlappedDataBuffer* pBufferB) const
+	TOrderedBufferQueue::TOrderedBufferQueue() :
+		m_eventHasBuffers(true, false)
 	{
-		if(!pBufferA)
-			throw TCoreException(eErr_InvalidArgument, L"pBufferA", LOCATION);
-		if(!pBufferB)
-			throw TCoreException(eErr_InvalidArgument, L"pBufferB", LOCATION);
+	}
 
-		return pBufferA->GetFilePosition() < pBufferB->GetFilePosition();
+	TOrderedBufferQueue::TOrderedBufferQueue(unsigned long long ullExpectedPosition) :
+		m_eventHasBuffers(true, false),
+		m_ullExpectedBufferPosition(ullExpectedPosition)
+	{
 	}
+
+	void TOrderedBufferQueue::Push(TOverlappedDataBuffer* pBuffer)
+	{
+		m_setBuffers.insert(pBuffer);
+		UpdateHasBuffers();
+	}
+
+	TOverlappedDataBuffer* TOrderedBufferQueue::Pop()
+	{
+		if(!IsBufferReady())
+			return nullptr;
+
+		TOverlappedDataBuffer* pBuffer = *m_setBuffers.begin();
+		m_setBuffers.erase(m_setBuffers.begin());
+
+		if(!pBuffer->HasError())
+			m_ullExpectedBufferPosition += pBuffer->GetRequestedDataSize();
+
+		UpdateHasBuffers();
+
+		return pBuffer;
+	}
+
+	const TOverlappedDataBuffer* const TOrderedBufferQueue::Peek() const
+	{
+		if(!m_setBuffers.empty())
+			return *m_setBuffers.begin();
+		return nullptr;
+	}
+
+	bool TOrderedBufferQueue::IsBufferReady() const
+	{
+		return (!m_setBuffers.empty() && (m_ullExpectedBufferPosition == NoPosition || (*m_setBuffers.begin())->GetFilePosition() == m_ullExpectedBufferPosition));
+	}
+
+	void TOrderedBufferQueue::Clear()
+	{
+		m_setBuffers.clear();
+		m_ullExpectedBufferPosition = NoPosition;
+		m_eventHasBuffers.ResetEvent();
+	}
+
+	size_t TOrderedBufferQueue::GetCount() const
+	{
+		return m_setBuffers.size();
+	}
+
+	bool TOrderedBufferQueue::IsEmpty() const
+	{
+		return m_setBuffers.empty();
+	}
+
+	HANDLE TOrderedBufferQueue::GetHasBuffersEvent() const
+	{
+		return m_eventHasBuffers.Handle();
+	}
+
+	void TOrderedBufferQueue::UpdateHasBuffers()
+	{
+		if(!m_setBuffers.empty() && (m_ullExpectedBufferPosition == NoPosition || Peek()->GetFilePosition() == m_ullExpectedBufferPosition))
+			m_eventHasBuffers.SetEvent();
+		else
+			m_eventHasBuffers.ResetEvent();
+	}
 }