Files
pip/piiodevice.h
2013-03-18 12:07:44 +04:00

140 lines
5.5 KiB
C++

/*
PIP - Platform Independent Primitives
Abstract input/output device
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
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 PIIODEVICE_H
#define PIIODEVICE_H
#include "pitimer.h"
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
typedef bool (*ReadRetFunc)(void * , uchar * , int );
/// events:
/// void opened()
/// void closed()
///
/// handlers:
/// bool open()
/// bool open(const PIString & path)
/// bool open(const DeviceMode & type)
/// bool open(const PIString & path, const DeviceMode & type)
/// bool close()
/// bool initialize()
/// void flush()
class PIIODevice: public PIThread {
public:
PIIODevice();
enum DeviceMode {ReadOnly = 0x01, WriteOnly = 0x02, ReadWrite = 0x03};
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
virtual ~PIIODevice() {if (opened_) {closeDevice(); if (!opened_) closed();}}
DeviceMode mode() const {return mode_;}
PIString path() const {return path_;}
bool isReadable() const {return (mode_ & ReadOnly);}
bool isWriteable() const {return (mode_ & WriteOnly);}
bool isInitialized() const {return init_;}
bool isOpened() const {return opened_;}
bool isClosed() const {return !opened_;}
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
// Enable timer to periodically open device until it will be opened
void setReopenEnabled(bool yes = true) {reopen_enabled_ = yes;}
void setReopenTimeout(int msecs = 1000) {reopen_timeout_ = msecs;}
bool isReopenEnabled() const {return reopen_enabled_;}
int reopenTimeout() {return reopen_timeout_;}
// set return function executed when successful read in thread
void setThreadedReadSlot(ReadRetFunc func) {ret_func_ = func;}
void setThreadedReadData(void * d) {ret_data_ = d;}
void setThreadedReadBufferSize(int new_size) {buffer_tr.resize(new_size);}
int threadedReadBufferSize() const {return buffer_tr.size_s();}
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
void startThreadedRead() {if (!isRunning()) start();}
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER2(PIIODevice, bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER(PIIODevice, bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
EVENT_HANDLER(PIIODevice, bool, initialize) {init_ = init(); return init_;}
// Flush device
EVENT_VHANDLER(PIIODevice, void, flush) {;}
EVENT(PIIODevice, opened)
EVENT(PIIODevice, closed)
// Read from device to "read_to" maximum "max_size" bytes, return readed bytes count
virtual int read(void * read_to, int max_size) {piCout << "[PIIODevice] \"read\" not implemented!" << endl; return -2;}
// Write to device "data" maximum "max_size" bytes, return written bytes count
virtual int write(const void * data, int max_size) {piCout << "[PIIODevice] \"write\" not implemented!" << endl; return -2;}
// Read from device maximum "max_size" bytes and return them as PIByteArray
PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = read(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);}
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
protected:
// Function executed before first openDevice() or from constructor
virtual bool init() {return true;}
// Functions to open and close device, return value will set to "opened_" variable
virtual bool openDevice() = 0; // use path_, type_, opened_, init_ variables
virtual bool closeDevice() {return true;} // use path_, type_, opened_, init_ variables
// Function executed when thread read some data, default implementation execute external slot "ret_func_"
virtual bool threadedRead(uchar * readed, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, readed, size); return true;}
void terminate();
PIString path_;
DeviceMode mode_;
ReadRetFunc ret_func_;
bool init_, opened_, thread_started_, reopen_enabled_;
int reopen_timeout_;
void * ret_data_;
private:
EVENT_HANDLER2(PIIODevice, void, check_start, void * , data, int, delim);
void begin();
void run();
void end() {terminate();}
PITimer timer;
PIByteArray buffer_in, buffer_tr;
int readed_;
};
#endif // PIIODEVICE_H