FileReaderCDF.hh 5.5 KB
/*
 * FileReaderCDF.hh
 *
 *  Created on: Nov 24, 2014
 *  Author: AKKA
 */

#ifndef FILEREADERCDF_HH_
#define FILEREADERCDF_HH_

#include "FileReaderAbstract.hh"

#include "cdf.h"

namespace AMDA {
namespace LocalFileInterface {

/*
 * @brief Implementation of the class FileReaderAbstract to load a CDF file format
 */
class FileReaderCDF : public FileReaderAbstract
{
public:
	/*
	 * @brief Constructor
	 */
	FileReaderCDF();

	/*
	 * @brief Destructor
	 */
	virtual ~FileReaderCDF();

	/*
	 * @brief Open a CDF file
	 */
	virtual bool open(std::string filePath);

	/*
	 * @brief Close the CDF file
	 */
	virtual bool close(void);

	/*
	 * @brief Test if a CDF file is currently opened
	 */
	virtual bool isOpened(void);

	/*
	 * @brief Get the id of the time param to use. For the CDF format, it's the first CDF_EPOCH var
	 */
	virtual std::string getTimeParamId(void);

	/*
	 * @brief Get a param type and a param size in the CDF file
	 */
	virtual bool getParamInfo(std::string& paramId, LocalParamType& paramType, int& dim1Size, int& dim2Size);

	/*
	 * @brief Get the index of the nearest record of time (the higher one) in the CDF file
	 */
	virtual int getRecordIndex(std::string& timeId, double time);

	/*
	 * @brief Get a param packet from the CDF file
	 */
	virtual FileReaderStatus getParamPacketData(std::string& timeId, std::string& paramId,
			int recordIndex, double stopTime, LocalParamDataPacket *packet);

protected:
	/*
	 * @brief TimeStamp (Unix time) to EPOCH time conversion
	 */
	double timeStampToEPOCHTime(double timeStamp);

	/*
	 * @brief EPOCH time to TimeStamp conversion
	 */
	double epochTimeToTimeStamp(double epochTime);

private:

	/*
	 * @brief CDF var type : rVariable or zVariable
	 */
	typedef enum {CDFVT_R,CDFVT_Z} CDFVarType;

	/*
	 * @brief Working structure to contain CDF variable info
	 */
	typedef struct
	{
		//variable name
		char       _name[CDF_VAR_NAME_LEN256+1];
		//rVariable or zVariable
		CDFVarType _type;
		//variable number
		long	   _num;
		//data type
		long       _dataType;
		//number of bytes for the data type
		long       _numBytes;
		//number of elements (of the data type)
		long       _numElts;
		//number of dimensions
		long       _numDims;
		//dimension sizes
		long       _dimSizes[CDF_MAX_DIMS];
		//record variance
		long       _recVary;
		//dimension variances
		long       _dimVarys[CDF_MAX_DIMS];
		//maximum record number
		long       _maxRecNum;
	} CDFVarInfo;

	/*
	 * @brief Working buffers container
	 */
	class CDFWorkingBuffers
	{
	public:
		/*
		 * @brief Buffer type:
		 */
		typedef enum {
			//buffer used to store time data
			BUFFER_TIME,
			//buffer used to store param data
			BUFFER_DATA,
			//buffer used to store packet data for one record
			BUFFER_PACKETREC
		} BufferType;

		/*
		 * @brief Constructor
		 */
		CDFWorkingBuffers() : _timeBuffer(NULL), _dataBuffer(NULL), _packetRecBuffer(NULL)
		{
		}

		/*
		 * @brief Destructor
		 */
		~CDFWorkingBuffers()
		{
			//free all buffers
			if (_timeBuffer != NULL)
				free(_timeBuffer);
			if (_dataBuffer != NULL)
				free(_dataBuffer);
			if (_packetRecBuffer != NULL)
				free(_packetRecBuffer);
		}

		/*
		 * @brief Get buffer pointer from a buffer type
		 */
		void* getBuffer(BufferType type)
		{
			switch (type)
			{
			case BUFFER_TIME:
				return _timeBuffer;
			case BUFFER_DATA:
				return _dataBuffer;
			case BUFFER_PACKETREC:
				return _packetRecBuffer;
			}
			return NULL;
		}

		/*
		 * @brief Reallocate a buffer from a buffer type
		 */
		void reallocBuffer(BufferType type, long size)
		{
			switch (type)
			{
			case BUFFER_TIME:
				if (_timeBuffer != NULL)
					free(_timeBuffer);
				_timeBuffer = malloc(size);
				break;
			case BUFFER_DATA:
				if (_dataBuffer != NULL)
					free(_dataBuffer);
				_dataBuffer = malloc(size);
				break;
			case BUFFER_PACKETREC:
				if (_packetRecBuffer != NULL)
					free(_packetRecBuffer);
				_packetRecBuffer = malloc(size);
				break;
			}
		}

	private:
		/*
		 * @brief Buffer for time data
		 */
		void* _timeBuffer;

		/*
		 * @brief Buffer for param data
		 */
		void* _dataBuffer;

		/*
		 * @brief Buffer for one record packet data
		 */
		void* _packetRecBuffer;
	};

	/*
	 * @brief CDF identifier
	 */
	CDFid _cdfid;

	/*
	 * @brief Working buffers container
	 */
	boost::shared_ptr<CDFWorkingBuffers> _workingBuffers;

	/*
	 * @brief Get CDF variable Info from param name
	 */
	bool getCDFVarInfo(std::string paramName, CDFVarInfo& varInfo);

	/*
	 * @brief Get CDF data for paramId from startRec to the end of the file
	 */
	bool getCDFData(std::string& varId, long startRec, CDFWorkingBuffers::BufferType bufferType,
			long& dataType, long& numBytes, long& nbRec, long& dimSize);

	/*
	 * @brief Extract a short to a CDF data buffer
	 */
	bool extractShort(CDFWorkingBuffers::BufferType bufferType, long recIndex, long dimIndex, long dimSize,
			long dataType, long numBytes, short& value);

	/*
	 * @brief Extract a int to a CDF data buffer
	 */
	bool extractInt(CDFWorkingBuffers::BufferType bufferType, long recIndex, long dimIndex, long dimSize,
			long dataType, long numBytes, int& value);

	/*
	 * @brief Extract a float to a CDF data buffer
	 */
	bool extractFloat(CDFWorkingBuffers::BufferType bufferType, long recIndex, long dimIndex, long dimSize,
			long dataType, long numBytes, float& value);

	/*
	 * @brief Extract a int to a CDF data buffer
	 */
	bool extractDouble(CDFWorkingBuffers::BufferType bufferType, long recIndex, long dimIndex, long dimSize,
			long dataType, long numBytes, double& value);

};

} /* LocalFileInterface */
} /* AMDA */

#endif /* FILEREADERCDF_HH_ */