123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #ifndef __C_DATAPUMP_H__
- #define __C_DATAPUMP_H__
- #include <stdlib.h>
- #include <memory.h>
- #include <stddef.h>
- #pragma intrinsic(memcpy,memset)
- template<class T> class C_DATAPUMP {
- private:
- protected:
- T *BufferBottom; // bottom of the physical buffer
- T *BufferTop; // top of the physical buffer
- T *BufferStart; // start of the logical buffer
- T *BufferEnd; // end of the logical buffer
- virtual void addItems(T *inputBuffer, size_t inputSize) { // inputSize = number of <T> records inputBuffer contains
- if(inputBuffer && inputSize) {
- memcpy(BufferEnd,inputBuffer,inputSize*sizeof(T)); // copy our records in
- BufferEnd += inputSize;
- if(BufferEnd >= BufferTop) BufferEnd = BufferBottom + (BufferEnd-BufferTop);
- }
- }
- virtual void delItems(int where, size_t numItems) { // where: 0 = start, 1 = end
- if(numItems > 0) {
- if(numItems > size()) { // just void everything
- BufferEnd = BufferStart;
- } else {
- if(where == 0) { // start
- BufferStart += numItems;
- if(BufferStart >= BufferTop) BufferStart = BufferBottom + (BufferTop-BufferStart);
- } else if(where == 1) { // end
- BufferEnd -= numItems;
- if(BufferEnd < BufferBottom) BufferEnd = BufferTop - (BufferBottom-BufferEnd);
- }
- }
- }
- }
- virtual void getItems(T *outputBuffer, size_t outputSize) { // outputSize = number of <T> records outputBuffer needs
- if(outputBuffer && outputSize) {
- memcpy(outputBuffer,BufferStart,outputSize*sizeof(T));
- }
- }
- public:
- C_DATAPUMP(int bufferSize) { // bufferSize = number of <T> records
- BufferBottom = NULL;
- BufferTop = NULL;
- BufferStart = NULL;
- BufferEnd = NULL;
- resizeBuffer(bufferSize);
- }
- virtual ~C_DATAPUMP() {
- if(getBufferSize() && BufferBottom) {
- free(BufferBottom);
- BufferBottom = NULL;
- }
- }
- virtual void resizeBuffer(size_t bufferSize) { // bufferSize = number of <T> records
- // this will invalidate any data in the buffer, so be careful when calling this function
- if(bufferSize) {
- if(getBufferSize() != bufferSize) {
- if(BufferBottom && BufferTop && getBufferSize()) { // buffer is valid
- if(getBufferSize() > bufferSize) { // buffer is getting smaller (will invalidate buffer)
- BufferTop -= getBufferSize()-bufferSize;
- invalidate();
- } else { // buffer is getting larger (will _NOT_ invalidate buffer... nicely moves the data over =)
- T *newBuffer = (T *)malloc(bufferSize * sizeof(T));
- // new
- BufferEnd = newBuffer + get(newBuffer,bufferSize);
- free(BufferBottom);
- BufferBottom = newBuffer;
- BufferTop = BufferBottom + bufferSize;
- BufferStart = BufferBottom;
- /* old
- T *bufptr = newBuffer;
- int top = BufferEnd >= BufferStart ? BufferEnd-BufferStart : BufferTop-BufferStart; // number of <T> records at top of physical buffer
- int bottom = BufferEnd >= BufferStart ? 0 : BufferEnd-BufferBottom; // number of <T> records at bottom of physical buffer
- if(top > 0) {
- memcpy(bufptr,BufferStart,top*sizeof(T));
- bufptr += top;
- }
- if(bottom > 0) {
- memcpy(bufptr,BufferBottom,bottom*sizeof(T));
- bufptr += bottom;
- }
- free(BufferBottom);
- BufferBottom = newBuffer;
- BufferTop = BufferBottom + bufferSize;
- BufferStart = BufferBottom;
- BufferEnd = bufptr;
- */
- }
- } else { // no buffer, create (invalidates the buffer... duh)
- BufferBottom = (T *)malloc(bufferSize * sizeof(T));
- BufferTop = BufferBottom + bufferSize;
- invalidate();
- }
- }
- }
- }
- virtual size_t size() { // will get the number of <T> records the logical buffer contains
- return BufferEnd >= BufferStart ? BufferEnd-BufferStart : (BufferTop-BufferStart)+(BufferEnd-BufferBottom);
- }
- virtual size_t put(T *inputBuffer, size_t inputSize) { // inputSize = number of <T> records inputBuffer contains
- // returns number of <T> records added to logical buffer
- size_t retval = 0;
- if(inputBuffer && inputSize) {
- size_t fitting = ((BufferTop-BufferBottom)-1) - size(); // can't go over our logical boundary.... blah
- if(fitting > inputSize) fitting = inputSize; // the entire thing can fit. yeay!
- retval = fitting;
- if(fitting > 0) {
- T *bufptr = inputBuffer;
- size_t top = BufferEnd >= BufferStart ? BufferTop-BufferEnd : 0; // number of <T> records free at top of physical buffer
- size_t bottom = BufferEnd >= BufferStart ? BufferStart-BufferBottom : (BufferStart-BufferEnd); // number of <T> records free at bottom of physical buffer
- if(top > 0) {
- if(top > fitting) top = fitting;
- addItems(bufptr,top);
- fitting -= top;
- bufptr += top;
- }
- if(bottom > 0 && fitting > 0) {
- if(bottom > fitting) bottom = fitting;
- addItems(bufptr,bottom);
- }
- }
- }
- return retval;
- }
- virtual size_t get(T *outputBuffer, size_t outputSize) { // outputSize = number of <T> records outputBuffer needs
- // returns number of <T> records pulled from the logical buffer
- size_t retval = 0;
- if(outputBuffer && outputSize) {
- size_t fitting = size();
- if(fitting > outputSize) fitting = outputSize;
- retval = fitting;
- if(fitting > 0) {
- T *bufptr = outputBuffer;
- size_t top = BufferEnd >= BufferStart ? BufferEnd-BufferStart : BufferTop-BufferStart; // number of <T> records at top of physical buffer
- size_t bottom = BufferEnd >= BufferStart ? 0 : BufferEnd-BufferBottom; // number of <T> records at bottom of physical buffer
- if(top > 0) {
- if(top > fitting) top = fitting;
- getItems(bufptr,top);
- delItems(0,top);
- fitting -= top;
- bufptr += top;
- }
- if(bottom > 0 && fitting > 0) {
- if(bottom > fitting) bottom = fitting;
- getItems(bufptr,bottom);
- delItems(0,bottom);
- }
- }
- }
- return retval;
- }
- virtual size_t getBufferSize() { // returns the size of the physical buffer in <T> items
- return BufferTop-BufferBottom;
- }
- virtual void invalidate() { // calling this will wipe all data in the buffer and reset the logical pointers
- BufferStart = BufferEnd = BufferBottom;
- }
- };
- #endif // !__C_DATAPUMP_H__
|