Files
pip/pibinarylog.h

176 lines
5.7 KiB
C++

/*! \file pibinarylog.h
* \brief Binary log
*/
/*
PIP - Platform Independent Primitives
Class for write binary data to logfile, and read or playback this data
Copyright (C) 2014 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIBINARYLOG_H
#define PIBINARYLOG_H
#include "pifile.h"
#define PIBINARYLOG_VERSION 0x31
#define PIBINARYLOG_SIGNATURE_SIZE 6
class PIBinaryLog: public PIIODevice
{
PIIODEVICE(PIBinaryLog)
public:
PIBinaryLog();
~PIBinaryLog() {closeDevice();}
//! \brief Play modes for \a PIBinaryLog
enum PlayMode {
PlayRealTime /*! Play in system real time */ ,
PlayVariableSpeed /*! Play in software time with speed, set by \a setSpeed. Set by default */
};
//! Current \a PlayMode
PlayMode playMode() const {return (PlayMode)(property("playMode").toInt());}
//! Current directory where billogs wiil be saved
PIString logDir() const {return property("logDir").toString();}
//! Returns current file prefix
PIString filePrefix() const {return property("filePrefix").toString();}
//! Current LogDir, returns directory where billogs wiil be saved
int defaultID() const {return property("defaultID").toInt();}
//! Returns current play speed
float playSpeed() const {return property("playSpeed").toFloat();}
//! Returns if rapid start enabled
bool rapidStart() const {return property("rapidStart").toBool();}
//! Set \a PlayMode
void setPlayMode(PlayMode mode) {setProperty("playMode", (int)mode);}
//! Set path to directory where binlogs will be saved
void setLogDir(const PIString & path) {setProperty("logDir", path);}
//! Set file prefix, used to
void setFilePrefix(const PIString & prefix) {setProperty("filePrefix", prefix);}
//! Set defaultID, used in \a write function
void setDefaultID(int id) {setProperty("defaultID", id);}
//! If enabled BinLog \a ThreadedRead starts without delay for first record, e.g. first record will be readed immediately
void setRapidStart(bool enabled) {setProperty("rapidStart", enabled);}
// /** \brief Set play speed multiplyer, used only in \a PlayMode = \a PlayRealTime default value 1x.
// * If "speedX" > 0 than it use as speed increase by X times, else as speed decrease by X times.
// * While is running this function does nothing and returns false. If "speedX" is set, returns true.*/
// bool setRealSpeedX(int speedX) {if (speedX == 0 || isRunning()) return false; real_speedX = speedX; return true;}
// //! Returns current play speed multiplyer
// float realSpeedX() const {return real_speedX;}
//! Set play speed, used only if \a playMode = \a PlayVariableSpeed, default value 1.0
void setPlaySpeed(float speed) {setProperty("playSpeed", speed);}
//! Write one record to BinLog file, with ID = id, id must be greather than 0
int writeBinLog(int id, PIByteArray data) {return writeBinLog(id, data.data(), data.size_s());}
int writeBinLog(int id, const void * data, int size);
//! Read one record from BinLog file, with ID = id, if id = 0 than any id will be readed
PIByteArray readBinLog(int id = 0);
int readBinLog(int id, void * read_to, int max_size);
//! Return true, if position at the end of BinLog file
bool isEnd() {if (!opened_) return true; return file.isEnd();}
//! Returns if BinLog file is empty
bool isEmpty() {return (file.size() <= PIBINARYLOG_SIGNATURE_SIZE + 1);}
int lastReadedID() const {return lastrecord.id;}
//! Read one message from binlog file, with ID contains in "filterID" or any ID, if "filterID" is empty
int read(void *read_to, int max_size);
//! Write one record to BinLog file, with ID = "defaultID"
int write(const void * data, int size) {return writeBinLog(defaultID(), data, size);}
//! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead
PIVector<int> filterID;
//! Go to begin of BinLog file
void restart();
PIString constructFullPath() const;
//! \handlers
//! \{
//! \fn PIString createNewFile()
//! \brief Open device
//! \}
//! \events
//! \{
//! \fn void fileEnd()
//! \brief Create new binlog file in \a logDir, if successful returns filename, else returns empty string.
//! Filename is like \a filePrefix + "yyyy_MM_dd__hh_mm_ss.binlog"
//! \fn void fileError()
//! \brief Raise on file creation error
//! \}
EVENT_HANDLER(PIString, createNewFile);
EVENT(fileEnd)
EVENT(fileError)
protected:
PIString fullPathPrefix() const {return "binlog";}
void configureFromFullPath(const PIString & full_path);
bool openDevice();
bool closeDevice();
bool threadedRead(uchar *readed, int size);
private:
struct BinLogRecord {
int id;
int size;
PISystemTime timestamp;
PIByteArray data;
};
bool writeFileHeader();
bool checkFileHeader();
BinLogRecord readRecord();
PIFile file;
BinLogRecord lastrecord;
PISystemTime startlogtime;
//BinLogRecord nextrecord;
double play_time; //milliseconds
//int real_speedX; // in X
bool is_started, is_thread_ok;
uchar binlog_sig[PIBINARYLOG_SIGNATURE_SIZE];
};
#endif // PIBINARYLOG_H