class MTdeque
{
protected:
const m_iMaxSize;
deque <char> m_Queue;
CRITICAL_SECTION m_Lock;
public:
//Construction
MTdeque( int max_size ) : m_iMaxSize( max_size )
{
::InitializeCriticalSection(&m_Lock);
}
//Destruction
~MTdeque()
{
::DeleteCriticalSection(&m_Lock);
}
// Return deque's FreeSpace
int SpaceFree()
{
::EnterCriticalSection(&m_Lock);
int size = m_iMaxSize - m_Queue.size();
::LeaveCriticalSection(&m_Lock);
return (size < 0) ? 0 : size;
}
// Return deque's UsedSpace
int SpaceUsed()
{
::EnterCriticalSection(&m_Lock);
int size = m_Queue.size();
::LeaveCriticalSection(&m_Lock);
return size;
}
// Insert a char to deque
int Insert(char c)
{
int return_value = -1;
::EnterCriticalSection(&m_Lock);
if (m_Queue.size() < m_iMaxSize)
{
m_Queue.push_back(c);
return_value = c&0xff;
}
::LeaveCriticalSection(&m_Lock);
return return_value;
}
// Insert count chars to deque
int Insert(char *data, int count)
{
::EnterCriticalSection(&m_Lock);
int actual = m_iMaxSize - m_Queue.size();
if ( actual < 0 )
{
actual = 0;
}
if ( count < actual )
{
actual = count;
}
for (int i=0; i<actual; i++)
{
m_Queue.push_back( *data++ );
}
::LeaveCriticalSection(&m_Lock);
return actual;
}
// get max char and put these to *data from deque
// and clear these char
int Extract(char *data, int max)
{
int i = 0;
::EnterCriticalSection(&m_Lock);
while ( i<max && m_Queue.size() )
{
data[i++] = m_Queue.front();
m_Queue.pop_front();
}
::LeaveCriticalSection(&m_Lock);
return i;
}
// get max char and put these to *data from deque
// and do not clear these char
int Peek(char *data, int max)
{
::EnterCriticalSection(&m_Lock);
if ( max > m_Queue.size() )
{
max = m_Queue.size();
}
for (int i=0; i<max; i++)
{
data[i] = m_Queue.begin()[i];
}
::LeaveCriticalSection(&m_Lock);
return i;
}
// get a char from deque
// and clear this char
int Extract()
{
int return_value = -1;
::EnterCriticalSection(&m_Lock);
if ( m_Queue.size() )
{
return_value = m_Queue.front() & 0xff;
m_Queue.pop_front();
}
::LeaveCriticalSection(&m_Lock);
return return_value;
}
// clear all data from deque
void Clear()
{
::EnterCriticalSection(&m_Lock);
m_Queue.clear();
::LeaveCriticalSection(&m_Lock);
}
};