Files
cdev-1.7.2n/extensions/cdevGenericServer/include/fifo.h
2022-12-13 12:44:04 +01:00

316 lines
5.9 KiB
C++

/*-----------------------------------------------------------------------------
* Copyright (c) 1991,1992 Southeastern Universities Research Association,
* Continuous Electron Beam Accelerator Facility
*
* This software was developed under a United States Government license
* described in the NOTICE file included as part of this distribution.
*
*-----------------------------------------------------------------------------
*
* Description:
*
* Author: Walt Akers
*
* Revision History:
* fifo.h,v
* Revision 1.4 1997/12/22 15:15:45 akers
* Ongoing development with new cdevReactor
*
* Revision 1.3 1996/09/13 18:47:18 akers
* Installed free list for node objects
*
* Revision 1.2 1996/07/16 15:48:55 akers
* Ongoing Modifications
*
*-----------------------------------------------------------------------------
*/
#ifndef __FIFO_H_
#define __FIFO_H_ 1
#include <cdevPlatforms.h>
class GENERIC_SERVER_API QueueBase
{
public:
class node
{
friend class QueueBase;
private:
node ( void ) : binary(NULL), binaryLen(0), next(NULL) { }
~node ( void ) { }
public:
void * binary;
size_t binaryLen;
class node * next;
};
protected:
node * head;
node * tail;
private:
enum { NEWCNT = 32 };
static node * freeList_;
public:
QueueBase ( void )
: head(NULL), tail(NULL)
{
}
virtual ~QueueBase ( void )
{
}
static node * newNode ( void )
{
node * result;
if(freeList_==NULL)
{
freeList_ = new node[NEWCNT];
for(int i=0; i<NEWCNT; i++)
{
freeList_[i].binary = NULL;
freeList_[i].binaryLen = 0;
freeList_[i].next = (i<(NEWCNT-1))?&freeList_[i+1]:(node *)NULL;
}
}
result = &freeList_[0];
freeList_ = result->next;
result->binary = NULL;
result->binaryLen = 0;
result->next = NULL;
return result;
}
static void deleteNode ( node * ptr)
{
if(ptr->next!=NULL) deleteNode(ptr->next);
ptr->next = freeList_;
freeList_ = ptr;
}
};
class GENERIC_SERVER_API FifoQueue : public QueueBase
{
private:
int nodeCnt;
public:
FifoQueue ( void ) : QueueBase(), nodeCnt(0) {}
virtual ~FifoQueue ( void )
{
while(dequeue()!=NULL);
}
int empty ( void )
{
return head==NULL?1:0;
}
void enqueue ( void * ptr )
{
if(ptr != NULL)
{
if(tail==NULL) tail = newNode();
else
{
tail->next = newNode();
tail = tail->next;
}
tail->binary = ptr;
if(head==NULL) head = tail;
nodeCnt++;
}
}
void enqueue ( char * ptr, size_t len )
{
if(ptr != NULL && len > 0 )
{
if(tail==NULL) tail = newNode();
else {
tail->next = newNode();
tail = tail->next;
}
tail->binary = ptr;
tail->binaryLen = len;
if(head==NULL) head = tail;
nodeCnt++;
}
}
void * dequeue ( void )
{
void * result = NULL;
if(head!=NULL)
{
node * next = head->next;
result = head->binary;
head->next = NULL;
deleteNode(head);
head = next;
if(head==NULL) tail = NULL;
nodeCnt--;
}
return result;
}
int dequeue ( char ** ptr, size_t * len )
{
int result = -1;
*ptr = NULL;
*len = 0;
if(head!=NULL)
{
node * next = head->next;
result = 0;
*ptr = (char *)head->binary;
*len = head->binaryLen;
head->next = NULL;
deleteNode(head);
head = next;
if(head==NULL) tail = NULL;
nodeCnt--;
}
return result;
}
int peek ( char ** ptr, size_t *len )
{
int result = -1;
if(head!=NULL)
{
*ptr = (char *)head->binary;
*len = head->binaryLen;
result = 0;
}
return result;
}
void undequeue ( void * ptr )
{
if(ptr != NULL)
{
if(tail==NULL) enqueue(ptr);
else {
node * headnode = newNode();
headnode->binary = ptr;
headnode->next = head;
head = headnode;
nodeCnt++;
}
}
}
void undequeue ( char *ptr, size_t len)
{
if(ptr != NULL && len > 0)
{
if(tail==NULL) enqueue(ptr, len);
else {
node * headnode = newNode();
headnode->binary = ptr;
headnode->binaryLen = len;
headnode->next = head;
head = headnode;
nodeCnt++;
}
}
}
int getCount ( void ) { return nodeCnt; }
};
class GENERIC_SERVER_API ListQueue : public QueueBase
{
protected:
node * prev;
node * bookmark;
public:
ListQueue ( void ) : QueueBase ()
{
prev = NULL;
bookmark = NULL;
}
virtual ~ListQueue ( void )
{
while(first()==0) remove();
}
int first ( void )
{
prev = NULL;
bookmark = head;
return (bookmark==NULL?-1:0);
}
int next ( void )
{
if(bookmark!=NULL)
{
prev = bookmark;
bookmark = bookmark->next;
}
return (bookmark==NULL?-1:0);
}
void * dequeue ( void )
{
return (bookmark==NULL?NULL:bookmark->binary);
}
void enqueue ( void * ptr )
{
if(ptr != NULL)
{
prev = tail;
if(tail==NULL) tail = newNode();
else
{
tail->next = newNode();
tail = tail->next;
}
tail->binary = ptr;
bookmark = tail;
if(head==NULL) head = tail;
}
}
int remove ( void )
{
int retval = -1;
if(bookmark != NULL)
{
if(prev!=NULL) prev->next = bookmark->next;
else head = bookmark->next;
bookmark->next = NULL;
deleteNode(bookmark);
if(prev!=NULL) {
bookmark = prev->next;
}
else if(head!=NULL && head->next!=NULL) {
bookmark = head->next;
}
else bookmark = head;
for( tail=head;
tail!=NULL && tail->next!=NULL;
tail=tail->next);
retval = 0;
}
else if(head!=NULL) first();
else tail = NULL;
return retval;
}
};
#ifdef _FIFO_QUEUE_MASTER_
QueueBase::node * QueueBase::freeList_ = NULL;
#endif
#endif // __FIFO_H_