//------------------------------------------------------------------------------ // 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: rsvcDataEntry.h // This file defines the classes necessary for storage of an individual // tagged data item within a rsvcData class object. // // Author: Walt Akers & Jie Chen // // // //------------------------------------------------------------------------------ #ifndef _RSVC_DATA_ENTRY_H_ #define _RSVC_DATA_ENTRY_H_ #include #include // ############################################################################# // # rsvcDataEntryStorage: // # This class contains the data elements and methods necessary to store data // # associated with one tagged data item. // # // # Note: Because the rsvcData object must actively manipulate the data in // # this structure - it has been made public to increase access speed // # and to allow the subclassing of the rsvcData object. // ############################################################################# class rsvcDataEntryStorage { public: // ************************************************************* // * tag_: // * This is char string value that is used to uniquely identify // * a data element within a rsvcData object. // ************************************************************* char tag_[RSVC_TAG_MAX_LEN]; // ************************************************************* // * dataType_: // * This is the data type of the tagged data item that is to be // * stored in this rsvcDataEntryStorage object. // ************************************************************* rsvcDataTypes dataType_; // ************************************************************* // * size_: // * This variable is the allocated size of the buffer_ which is // * used to store both the array data and its associated bounds // * information. // ************************************************************* size_t size_; // ************************************************************* // * dim_: // * This variable indicates the user specified number of // * dimensions that the array represents. // * either 0 or 1 // ************************************************************* size_t dim_; // ************************************************************* // * elems_: // * This variable contains the maximum number of elements that // * the array may contain. // ************************************************************* size_t elems_; // ************************************************************* // * bytes_: // * This variable contains the number of bytes per element. // ************************************************************* size_t bytes_; // ************************************************************* // * buffer_: // * This is the buffer that is allocated to store data and // * bounds information. // ************************************************************* unsigned char * buffer_; // ************************************************************* // * data_: // * This is a union that is used to store scalar data and a // * pointer to the array data this is stored within this object // ************************************************************* union dataUnion { BYTE cval; short sval; unsigned short usval; long lval; unsigned long ulval; float fval; double dval; void * vptr; BYTE * cptr; short * sptr; unsigned short * usptr; long * lptr; unsigned long * ulptr; float * fptr; double * dptr; char * str; char ** strarr; rsvc_TS_STAMP ts; rsvc_TS_STAMP * tsptr; } data_; // ************************************************************* // * rsvcDataEntryStorage: // * Default constructor for the rsvcDataEntryStorage class. It sets // * the buffer_ pointer to NULL to prevent deletion of non- // * allocated memory, and then calls the clear method to // * initialize all data variables. // ************************************************************* rsvcDataEntryStorage ( void ) : buffer_(0) { clear(); } // ************************************************************* // * ~rsvcDataEntryStorage: // * Default destructor for the rsvcDaaEntry class. It calls // * the clear method to release and reinitialize all data // * elements. // ************************************************************* ~rsvcDataEntryStorage ( void ) { clear(); } // ************************************************************* // * clear: // * Releases and reinitializes all data variables. // ************************************************************* void clear ( void ) { deallocate(); tag_[0] = 0; dataType_ = RSVC_INVALID; } // ************************************************************* // * allocate: // * Allocates a block of memory sufficient to store a caller // * specified number of bytes. If sufficient space has already // * been allocated, then it will be used, otherwise, a new // * block will be created to service the request. // ************************************************************* void allocate ( size_t dimensions, size_t elems, size_t bytesPerElem ) { size_t newBlockSize = (elems * bytesPerElem); if(buffer_==NULL || newBlockSize>size_) { deallocate(); buffer_ = ::new unsigned char[newBlockSize]; size_ = newBlockSize; } dim_ = dimensions; elems_ = elems; bytes_ = bytesPerElem; data_.vptr = &buffer_[0]; memset (buffer_, 0, newBlockSize); } // ************************************************************* // * deallocate: // * Deallocates any memory previously allocated to the buffer // * and reinitializes the size_, dim_, bytes_ and buffer_ // * variables. Any references to the previously allocated // * block is cleared. // ************************************************************* void deallocate ( void ) { if(buffer_ != 0) { delete []buffer_; buffer_ = 0; } size_ = 0; dim_ = 0; elems_ = 0; bytes_ = 0; data_.dval = 0.00; } // ************************************************************* // * operator ==: // * This operator allows you to directly and rapidly // * compare two rsvcDataEntryStorage objects... // ************************************************************* int operator == (rsvcDataEntryStorage & entry); // ************************************************************* // * operator !=: // * This operator allows the caller to directly and rapidly // * comapre two rsvcDataEntryStorage objects. // ************************************************************* int operator != (rsvcDataEntryStorage & entry) { return !(operator == (entry)); } }; // ############################################################################# // # rsvcDataEntry: // # This class is used to define the node attributes necessary to support // # linked lists of rsvcDataEntryStorage objects. It also provides an internal // # freelist of rsvcDataEntry objects. // # // # Note: Because the rsvcData object must actively manipulate the data in // # this structure - it has been made public to increase access speed // # and to allow the subclassing of the rsvcData object. // ############################################################################# class rsvcDataEntry : public rsvcDataEntryStorage { public: // ************************************************************* // * freeList_: // * This is a pointer to a list of currently allocated // * rsvcDataEntrys that will be provided to the user // * upon request. This technique should reduce the number of // * mallocs called to allocated rsvcDataEntrys. // ************************************************************* static rsvcDataEntry * freeList_; // ************************************************************* // * ALLOCATION_COUNT: // * This is the minimum number of rsvcDataEntrys that will // * be allocated when the freeList_ becomes empty. // ************************************************************* enum { ALLOCATION_COUNT = 16 }; // ************************************************************* // * next_ : // * This is the pointer to the next element in the list of // * rsvcDataEntry objects. // ************************************************************* rsvcDataEntry * next_; // ************************************************************* // * rsvcDataEntry: // * Constructor for the class. It serves only to set the next_ // * pointer to NULL. // ************************************************************* rsvcDataEntry ( void ) : next_(NULL), rsvcDataEntryStorage() { } // ************************************************************* // * ~rsvcDataEntry: // * Destructor for the class. It is a placeholder that // * does nothing when called. // ************************************************************* ~rsvcDataEntry ( void ) { } // ************************************************************* // * next: // * Retrieves a pointer to the next_ rsvcDataEntry object. // * Incorporation of this function into a list object is the // * responsibility of the caller. // ************************************************************* rsvcDataEntry * &next ( void ) { return next_; } // ************************************************************* // * new: // * Allocation function for the object. It will get the next // * preallocated rsvcDataEntry object from the freeList_, // * or, if none are available, refill the freeList_ and then // * return a new rsvcDataEntry object. // ************************************************************* void * operator new ( size_t size ); // ************************************************************* // * delete: // * Rather than deallocating the rsvcDataEntry object, this // * function returns it to the freeList_ where it may be // * retrieved by a later call of new. // ************************************************************* void operator delete ( void * ptr ) { rsvcDataEntry * node = (rsvcDataEntry *)ptr; if(node != NULL) { node->next_ = freeList_; freeList_ = node; } } // ************************************************************* // * Copy operation // * Copy an existing data entry to a new data entry // * this may allow new data entry to be inserted into data object // * quickly // ************************************************************* rsvcDataEntry (const rsvcDataEntry& entry); // ************************************************************* // * Assignment operation // * Copy an existing data entry to a data entry // ************************************************************* rsvcDataEntry& operator = (const rsvcDataEntry& entry); // ************************************************************* // * operator ==: // * This operator allows you to directly and rapidly // * compare two rsvcDataEntry objects... // ************************************************************* int operator == (rsvcDataEntry & entry) { rsvcDataEntryStorage *storage = &entry; return rsvcDataEntryStorage::operator == (*storage); } // ************************************************************* // * operator !=: // * This operator allows the caller to directly and rapidly // * comapre two rsvcDataEntry objects. // ************************************************************* int operator != (rsvcDataEntry & entry) { rsvcDataEntryStorage *storage = &entry; return !(rsvcDataEntryStorage::operator == (*storage)); } }; #endif /* __RSVC_DATA_ENTRY_H_ */