⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data_lgr.cpp

📁 a program that generates a pulse-width modulated (PWM)signal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//*************************************************************************************
//  DATA_LGR.CPP
//      This file contains the implementation for the data logger class.  The logger
//      holds data in a linear, circular, or expanding buffer.
//
//  Version
//       1-21-95  JR   Original version
//       2-02-95  JR   Circular array added
//       2-12-95  JR   Bug fix (already)
//       7-18-95  JR   Uses new version of base_obj.cpp with new list objects
//*************************************************************************************

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <values.h>         //  Use maximum numbers defined here as error indicators
#include "base_obj.hpp"
#include "data_lgr.hpp"


//=====================================================================================
//  Class:  CQueueArray
//      This is an array which is of fixed size and stores data in increasing, linear
//      order as it is received.  There is a read pointer and a write pointer; the
//      read pointer follows the write pointer so that the array acts as a FIFO (First
//      In, First Out) storage element.  Because any kind of data must be able to be
//      stored in this array, access is through data pointers.
//=====================================================================================

//-------------------------------------------------------------------------------------
//  Constructor:  CQueueArray
//      This constructor calls that of CBasicArray, then starts the data pointers at 0.

CQueueArray::CQueueArray (unsigned aDataSize, unsigned aArraySize)
    : CBasicArray (aDataSize, aArraySize)
    {
    WriteIndex = 0;                 //  Set the read and write indices to 0 'cause
    ReadIndex = 0;                  //  there isn't any data yet
    PointsTaken = 0;                //  Note that we haven't taken any data yet
    }


//-------------------------------------------------------------------------------------
//  Destructor:  ~CQueueArray
//      This destructor, uh,...?

CQueueArray::~CQueueArray (void)
    {
//    for (CListNode* pCur = pFirst; pCur != NULL; pCur = pCur->pNextNode)
//        delete (pCur->pNodeData);
    }


//-------------------------------------------------------------------------------------
//  Function:  WritePointer
//      When you're going to write some data to the array, use this function to get a
//      write pointer.  It will automatically increment the index to the next item,
//      so don't use it in vain or you'll leave gaps in your data.

void* CQueueArray::WritePointer (void)
    {
    //  Check if the write index is within array bounds; if not return NULL
    if (WriteIndex >= TotalSize)
        return (NULL);

    //  If the index is within bounds, get a copy of the pointer which can be returned
    void* ThePtr = operator[] (WriteIndex);

    //  Next increment the index so it points to the next item, if there is one
    ++WriteIndex;
    ++PointsTaken;

    //  Finally return the pointer we found before incrementing
    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  ReadPointer
//      The read pointer works like the write pointer except that you can't read data
//      which hasn't been written; so the reader's not allowed to catch the writer.

void* CQueueArray::ReadPointer (void)
    {
    //  Check that the read index is less than the write index; if not, we're trying
    //  to read before writing, so return NULL
    if (ReadIndex >= WriteIndex)
        return (NULL);

    //  If the read index is OK, get a copy of the pointer and return it
    void* ThePtr = operator[] (ReadIndex);
    ++ReadIndex;
    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  Flush
//      The flushing of a queue is simple: just set the read and write indices to 0 so
//      that new data can be written and read.  The data array has been allocated
//      already, so just leave it.

void CQueueArray::Flush (void)
    {
    WriteIndex = 0;
    ReadIndex = 0;
    PointsTaken = 0;
    }


//-------------------------------------------------------------------------------------
//  Function:  Rewind
//      This function resets the read pointer to the beginning of the data, thereby
//      allowing the array to be read again from its 'full' state.

void CQueueArray::Rewind (void)
    {
    ReadIndex = 0;
    }


//=====================================================================================
//  Class:  CExpandingArray
//      This variation on the queue array "expands" - i.e. allocates some new memory
//      for more data - whenever it overflows.  Otherwise, it's used just the same as
//      the fixed-size queue.
//=====================================================================================

//-------------------------------------------------------------------------------------
//  Constructor:  CExpandingArray
//      This constructor starts up the array with one buffer allocated and the read
//      and write pointers set to the 0-th element...well actually the constructor
//      for CQueueArray does all that.

CExpandingArray::CExpandingArray (unsigned aDataSize, unsigned aArraySize)
    : CQueueArray (aDataSize, aArraySize)
    {
    }


//-------------------------------------------------------------------------------------
//  Destructor:  ~CExpandingArray
//      This thing frees up memory.

CExpandingArray::~CExpandingArray (void)
    {
    }


//-------------------------------------------------------------------------------------
//  Function:  WritePointer
//      When you're going to write some data to the array, use this function to get a
//      write pointer.  It will automatically increment the index to the next item,
//      so don't use it in vain or you'll leave gaps in your data.

void* CExpandingArray::WritePointer (void)
    {
    //  If the write index is greater than the current size of the array, we must
    //  allocate another buffer
    if (WriteIndex >= TotalSize)
        {
        if (Expand () == 0)                 //  A zero means we can't allocate more
            return (NULL);
        }

    //  If the index is within bounds, get a copy of the pointer which can be returned
    void* ThePtr = operator[] (WriteIndex);

    //  Next increment the index so it points to the next item, if there is one
    ++WriteIndex;
    ++PointsTaken;

    //  Finally return the pointer we found before incrementing
    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  ReadPointer
//      The read pointer works like the write pointer except that if there's nothing
//      to read, the array isn't expanded - the function just returns NULL.

void* CExpandingArray::ReadPointer (void)
    {
    //  Check that the read index is less than the write index; if not, we're trying
    //  to read before writing, so return NULL
    if (ReadIndex >= WriteIndex)
        return (NULL);

    //  If the read index is OK, get a copy of the pointer and return it
    void* ThePtr = operator[] (ReadIndex);
    ++ReadIndex;
    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  Flush
//      To flushing of an expanding buffer requires that we set the read and write
//      indices to 0 so that new data can be written and read and call the CBasicArray
//      Flush() method to delete the buffers full of data and allocate a new one.

void CExpandingArray::Flush (void)
    {
    WriteIndex = 0;
    ReadIndex = 0;
    PointsTaken = 0;

    CBasicArray::Flush ();
    }


//-------------------------------------------------------------------------------------
//  Function:  Rewind
//      This function resets the read pointer to the beginning of the data, thereby
//      allowing the array to be read again from its 'full' state.

void CExpandingArray::Rewind (void)
    {
    ReadIndex = 0;
    }


//=====================================================================================
//  Class:  CCircularArray
//      When you need a buffer of fixed size which will keep a record of the most
//      recent events, you need a ring buffer.  This class implements a ring buffer as
//      a descendent of the fixed-size basic array with pointers that wrap around and
//      around and write over old data, always keeping the most recent data available.
//=====================================================================================

//-------------------------------------------------------------------------------------
//  Constructor:  CCircularArray
//      This constructor starts up the array with a buffer allocated and the read
//      and write pointers set to the 0-th element...well actually the constructor
//      for CBasicArray does all that.

CCircularArray::CCircularArray (unsigned aDataSize, unsigned aArraySize)
    : CBasicArray (aDataSize, aArraySize)
    {
    WriteIndex = 0;                 //  Set the read and write indices to 0 'cause
    ReadIndex = 0;                  //  there isn't any data yet
    PointsTaken = 0;                //  Same for the points-taken counter
    MaxPointsTaken = 0;             //  Ditto again for maximum points counter
    }


//-------------------------------------------------------------------------------------
//  Destructor:  ~CCircularArray
//      This destructor, as usual, frees up the memory used by the array.

CCircularArray::~CCircularArray (void)
    {
    }


//-------------------------------------------------------------------------------------
//  Function:  WritePointer
//      Whenever there's data to be written, call this function to get a pointer to a
//      place to put it.  It will give you a pointer and increment the write index to
//      the next location, whether there's data there or not.

void* CCircularArray::WritePointer (void)
    {
    //  Get the pointer which we're going to return to the calling function
    void* ThePtr = operator[] (WriteIndex);

    //  If the buffer's full and we're writing over old data, push the read index
    //  along in front of the write index so that it still points to the oldest data
    if (PointsTaken >= TotalSize)
        {
        if (++ReadIndex >= TotalSize)
            ReadIndex = 0;
        }

    //  Now move the write index.  Note that with a full buffer which isn't being read
    //  the read and write indices end up moving together
    if (++WriteIndex >= TotalSize)
        WriteIndex = 0;

    //  If we haven't filled the array, increment the numbers of data points taken
    if (PointsTaken < TotalSize)
        PointsTaken++;
    if (MaxPointsTaken < TotalSize)
        MaxPointsTaken++;

    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  ReadPointer
//      The read pointer always "follows" the write pointer around the ring; it must
//      never overtake the write pointer or you might read unwritten data.

void* CCircularArray::ReadPointer (void)
    {
    //  Check if there's data available (that is, more data has been written than
    //  read) by looking at PointsTaken.  If there's no new data, return NULL
    if (PointsTaken == 0)
        return (NULL);

    //  If we get here, there is new data, so get a pointer to it
    void* ThePtr = operator[] (ReadIndex);

    //  Now advance the read index and decrement the points-taken counter.  Next time
    //  we want to read data, we'll check if this counter is 0 again
    if (++ReadIndex >= TotalSize)
        ReadIndex = 0;
    PointsTaken--;

    return (ThePtr);
    }


//-------------------------------------------------------------------------------------
//  Function:  Flush
//      In order to flush a circular array, just set the indices to 0 so you can over-
//      write the old data.

void CCircularArray::Flush (void)
    {
    WriteIndex = 0;
    ReadIndex = 0;
    PointsTaken = 0;
    }


//-------------------------------------------------------------------------------------
//  Function:  Rewind
//      This function resets the read pointer to the beginning of the data, thereby
//      allowing the array to be read again from its 'full' state.  For a circular
//      array, the beginning of the data is the oldest data.  If the buffer's not yet
//      full, the oldest data is at location 0; else it's pointed to by the write
//      index, because the write index points to where the next new data will go.

void CCircularArray::Rewind (void)
    {
    if (MaxPointsTaken < TotalSize)
        ReadIndex = 0;
    else
        ReadIndex = WriteIndex;

    PointsTaken = MaxPointsTaken;
    }


//=====================================================================================
//  Class:  CLogArray
//      This class implements a somewhat automatic array which stores data to be
//      logged in a file.  The log array keeps a pointer to one of the CBasicArray
//      descendents, using the one appropriate for the user's choice of array type:
//      linear, expanding, or circular.
//=====================================================================================

//-------------------------------------------------------------------------------------
//  Constructor:  CLogArray
//      This constructor sets up a logging array of the given type with a starting
//      buffer of the given size.

CLogArray::CLogArray (LogDataType aDaType, LogArrayType aArType, unsigned aBufferSize)
    {
    int DataSize;                                   //  How many bytes per data item?

    ErrorString = new CString (128);                //  String to hold error messages
    HeaderLine = new CString (64);                  //  String holds column's header
    DataType = aDaType;                             //  Save the data type information
    ArrayType = aArType;                            //  Save array type info. also

    //  Depending on the type of data the user wants to store, set the size of each
    //  data item in bytes
    switch (aDaType)
        {
        case LOG_INT:
            DataSize = sizeof (int);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -