/*	Queue.c - Generic Queue Handling Routines
*
*******************************************************************************
* Copyright (c) 1996-97 Digi International Inc., All Rights Reserved          *
*                                                                             *
* This  software  contains  proprietary  and  confidential   information   of *
* Digi International  Inc.   By  accepting  transfer  of this copy, Recipient *
* agrees to retain this software in  confidence,  to  prevent  disclosure  to *
* others,  and  to make no  use of this software other than that for which it *
* was delivered.  This is an unpublished copyright work  Digi   International *
* Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is *
* strictly prohibited.                                                        *
*                                                                             *
* Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc. *
* Confidential  when   combined   with   the   aggregated  modules  for  this *
* product) OBJECT CODE ONLY SOURCE MATERIALS                                  *
*                                                                             *
* (C) COPYRIGHT Digi International Inc. 1996-97                               *
*                                                                             *
* All Rights Reserved                                                         *
*                                                                             *
* US   Government   Users   Restricted   Rights   -   Use,   duplication   or *
* disclosure  restricted by GSA ADP Schedule Contract with Digi International *
* Inc.                                                                        *
*                                                                             *
*******************************************************************************
*
*/

#include "DS_RAS.h"
#include "Queue.h"

#define	DataToEntry(p)	((p) == NULL ? NULL : ((ENTRY *) (((BYTE *) (p)) - sizeof (ENTRY))))
#define	EntryToData(p)	((p) == NULL ? NULL : ((void *) (((BYTE *) (p)) + sizeof (ENTRY))))

BOOL QueuePut(QUEUE * const pQueue, void const * const pvData, size_t const cbData)
{
	ENTRY * const pEntry = malloc(sizeof (ENTRY) + cbData);

	if (pEntry != NULL)
	{
		void * pData = EntryToData(pEntry);

		memcpy(pData, pvData, cbData);

		pEntry->pPrevious = NULL;
		if (pQueue->pHead == NULL)
		{
			pEntry->pNext = NULL;
			pEntry->pPrevious = NULL;

			pQueue->pHead = pEntry;
			pQueue->pTail = pEntry;
		}
		else
		{
			pEntry->pNext = pQueue->pHead;
			pEntry->pPrevious = NULL;

			pQueue->pHead = pEntry;
			pEntry->pNext->pPrevious = pEntry;
		}
	}

	return (pEntry != NULL);
}

BOOL QueuePeek(QUEUE * const pQueue, size_t * const pcbData)
{
	ENTRY * const pEntry = pQueue->pHead;

	if (pEntry != NULL)
		*pcbData = pEntry->cbData;

	return (pEntry != NULL);
}

BOOL QueueGet(QUEUE * const pQueue, void * const pvData, size_t const cbData)
{
	BOOL fSuccess = FALSE;
	ENTRY * const pEntry = pQueue->pHead;

	if (pEntry == NULL) goto Error;
	if (pEntry->cbData > cbData) goto Error;

	memcpy(pvData, EntryToData(pEntry), pEntry->cbData);

	pQueue->pTail = pEntry->pPrevious;
	if (pEntry->pPrevious != NULL)
		pEntry->pPrevious->pNext = pEntry->pNext;
		
	free(pEntry);

	fSuccess = TRUE;

Error:

	return fSuccess;
}


size_t QueueSize(QUEUE * const pQueue)
{
	size_t cEntries = 0;
	ENTRY const * pEntry = pQueue->pHead;

	if (pEntry != NULL)
	{
		cEntries++;
		while (pEntry != pQueue->pTail)
		{
			cEntries++;
			pEntry = pEntry->pNext;
		}
	}

	return cEntries;
}

