CRingBlockReader

Name

CRingBlockReader -- ABC for reading blocks of ring items from a source.

Synopsis


#include <CRingBlockReader>
            
class CRingBlockReader
{
  
  
public:
    typedef struct _DataDescriptor {
        std::uint32_t s_nBytes;
        std::uint32_t s_nItems;
        void*         s_pData;           
    } DataDescriptor, *pDataDescriptor;
public:
    CRingBlockReader();
    
    virtual DataDescriptor read(size_t nBytes);
protected:
    
    virtual ssize_t readBlock(void* pBuffer, size_t maxBytes) = 0;

};

        

DESCRIPTION

This is an abstract base class that uses a strategy pattern to read large blocks of data from some source and pass back to the user a description of the items in the block. The items are only assumed to begin with a uint32_t size in bytes.

Actual data transfer is done via the protected, pure virtual, method readBlock. The base class properly handles items which span block boundaries transparently with respect concrete derive classes.

Full customizability of the internals is also provided by making the public read method virtual as well.

METHODS

CRingBlockReader();

Constructs the object.

virtual DataDescriptor read(size_t nBytes);

Obtains at most nBytes of data from the source. The return value is a CRingBlockReader::DataDescriptor. See DataTypes.

It is important to know that the s_pData field of the returned structure points to data allocated dynamically via malloc(3). When the caller is done using it that data must be released via free(3).

It is an error if nBytes cannot accommodate at least one complete item. In that case an std::logic_error is thrown.

protected virtual =0 ssize_t readBlock(void* pBuffer, size_t maxBytes);

Concrete sub-classes must implement this method. The method must obtain at most maxBytes from the data source storing them in pBuffer. The actual number of bytes returned is the return value.

A return value of 0 represents an end to the data source. A return value less than zero indicates an error whose reason is in the errno variable. The caller will transform errors like this into throw std::system_error exceptions.

DATA TYPES

The class defines a nested struct: CRingBlockReader::DataDescriptor and an associated pointer type CRingBlockReader::pDataDescriptor which is a pointer to that struct. The struct has the following fields:

std::uint32_t s_nBytes

Number of bytes in this chunk of data. This may be less than the number of bytes requested of the read but it will never be more than that.

std::uint32_t s_nItems

The number of items in the block read. Each item is assumed to have a leading std::uint32_t that contains the size of the item in bytes. Note that this is also how NSCLDAQ ring items are formatted.

void* s_pData

Pointer to the data. The data pointed to is allocated dynamically by malloc(3) and must be deallocated by the client code when appropriate via free(3).