/***************************************************************************
				Fixed size Queue Class ( FixedQueue.cpp )
                -----------------------------------------
	begin      : 2013/08/09
	copyright  : (C) 2005 SolutionBox Inc.
	author     : Development 1 Team
	email      : dev1@solbox.com
	version    : 3.2

	CopyRight(C) 2005 SolutionBox Inc. All Rights reserved.
	Redistribution and use in source and binary forms, with or with out
	modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#include "FixedQueue.h"

#include <string.h>


CMutexLock::CMutexLock(pthread_mutex_t * mutex)
	: m_plock(mutex)
{
	 pthread_mutex_lock(m_plock);
}

CMutexLock::~CMutexLock()
{
	 pthread_mutex_unlock(m_plock);
}

CFixedQueue::CFixedQueue(int bufferSize, int qSzie )
	: m_bufferSize(bufferSize), m_queueSize(qSzie)
{
	pthread_mutex_init(&m_mutex, NULL);
}

CFixedQueue::~CFixedQueue()
{
	ReleaseAll();
	pthread_mutex_destroy(&m_mutex);
}

void CFixedQueue::ReleaseAll()
{
	pthread_mutex_unlock(&m_mutex);

	while (!m_queue.empty())
	{
		FixedQueueData *d = m_queue.front();
		if(d) delete (FixedQueueData*) d;
		m_queue.pop();
	}
}

int CFixedQueue::Push(char* buf, size_t buffersize)
{
	int r = 0;

	if(buf == NULL)
		return -1;

	if(buffersize > (size_t) m_bufferSize)
		return -2;

	CMutexLock lock (&m_mutex);
	do
	{
		if( m_queue.size() >= std::queue<char*>::size_type(m_queueSize) )
		{
			r = 1;
			break;
		}
		
		FixedQueueData *d = new FixedQueueData;
		d->data_size = buffersize;
		d->data = new char [buffersize];				
		memcpy(d->data, buf, buffersize);
		m_queue.push(d);
		r = 0;

	}while (false);

	return r;
}

int CFixedQueue::Pop(char* buf, size_t buffersize)
{
	int r = 0;
	if (buf == NULL)
		return -1;

	memset(buf, 0, buffersize);
	CMutexLock lock (&m_mutex);
	do 
	{
		if( m_queue.empty())
		{
			r = 1;
			break;
		}

		FixedQueueData *t = m_queue.front();		
		memcpy(buf, t->data, t->data_size);
		delete (FixedQueueData *) t;
		m_queue.pop();
		r = 0;

	} while (false);
	
	return r;
}
