/*----------------------------------------------------------------------------- * 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 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; inext; 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_