219 lines
7.5 KiB
C++
219 lines
7.5 KiB
C++
/*! \file piiodevice.h
|
|
* \brief Abstract input/output device
|
|
*/
|
|
/*
|
|
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 PIP_EXPORT PIIODevice: public PIThread
|
|
{
|
|
PIOBJECT(PIIODevice)
|
|
public:
|
|
PIIODevice();
|
|
|
|
//! \brief Open modes for PIIODevice
|
|
enum DeviceMode {
|
|
ReadOnly /*! Device can only read */ = 0x01,
|
|
WriteOnly /*! Device can only write */ = 0x02,
|
|
ReadWrite /*! Device can both read and write */ = 0x03
|
|
};
|
|
|
|
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
|
virtual ~PIIODevice() {stop(); write_thread.stop(); if (opened_) {closeDevice(); if (!opened_) closed();}}
|
|
|
|
//! Current open mode of device
|
|
DeviceMode mode() const {return mode_;}
|
|
|
|
//! Current path of device
|
|
PIString path() const {return path_;}
|
|
|
|
//! return \b true if mode is ReadOnly or ReadWrite
|
|
bool isReadable() const {return (mode_ & ReadOnly);}
|
|
|
|
//! return \b true if mode is WriteOnly or ReadWrite
|
|
bool isWriteable() const {return (mode_ & WriteOnly);}
|
|
|
|
bool isInitialized() const {return init_;}
|
|
|
|
//! return \b true if device is successfully opened
|
|
bool isOpened() const {return opened_;}
|
|
|
|
//! return \b true if device is closed
|
|
bool isClosed() const {return !opened_;}
|
|
|
|
//! return \b true if device can read \b now
|
|
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
|
|
|
|
//! return \b true if device can write \b now
|
|
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();}
|
|
|
|
bool isThreadedRead() const {return isRunning();}
|
|
void startThreadedRead() {if (!isRunning()) start();}
|
|
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
|
|
|
|
|
bool isThreadedWrite() const {return write_thread.isRunning();}
|
|
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();}
|
|
void stopThreadedWrite() {write_thread.stop();}
|
|
void clearThreadedWriteQueue() {write_thread.lock(); write_queue.clear(); write_thread.unlock();}
|
|
|
|
|
|
// 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!"; 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!"; 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());}
|
|
|
|
ullong writeThreaded(const void * data, int max_size) {return writeThreaded(PIByteArray(data, uint(max_size)));}
|
|
ullong writeThreaded(const PIByteArray & data);
|
|
|
|
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
|
EVENT_HANDLER1(bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
|
EVENT_HANDLER1(bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
|
EVENT_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
|
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
|
|
EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;}
|
|
|
|
EVENT_VHANDLER(void, flush) {;}
|
|
|
|
EVENT(opened)
|
|
EVENT(closed)
|
|
EVENT2(threadedReadEvent, uchar * , readed, int, size)
|
|
EVENT2(threadedWriteEvent, ullong, id, int, written_size)
|
|
|
|
//! \handlers
|
|
//! \{
|
|
|
|
//! \fn bool open()
|
|
//! \brief Open device
|
|
|
|
//! \fn bool open(const PIString & path)
|
|
//! \brief Open device with path "path"
|
|
|
|
//! \fn bool open(const DeviceMode & mode)
|
|
//! \brief Open device with mode "mode"
|
|
|
|
//! \fn bool open(const PIString & path, const DeviceMode & mode)
|
|
//! \brief Open device with path "path" and mode "mode"
|
|
|
|
//! \}
|
|
//! \vhandlers
|
|
//! \{
|
|
|
|
//! \fn void flush()
|
|
//! \brief Immediate write all buffers
|
|
|
|
//! \}
|
|
//! \events
|
|
//! \{
|
|
|
|
//! \fn void opened()
|
|
//! \brief Raise if succesfull open
|
|
|
|
//! \fn void closed()
|
|
//! \brief Raise if succesfull close
|
|
|
|
//! \fn void threadedReadEvent(uchar * readed, int size)
|
|
//! \brief Raise if read thread succesfull read some data
|
|
|
|
//! \fn void threadedWriteEvent(ullong id, int written_size)
|
|
//! \brief Raise if write thread succesfull write some data of queue item with id "id"
|
|
|
|
//! \}
|
|
|
|
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(void, check_start, void * , data, int, delim);
|
|
EVENT_HANDLER(void, write_func);
|
|
|
|
void begin();
|
|
void run();
|
|
void end() {terminate();}
|
|
|
|
PITimer timer;
|
|
PIThread write_thread;
|
|
PIByteArray buffer_in, buffer_tr;
|
|
PIQueue<PIPair<PIByteArray, ullong> > write_queue;
|
|
ullong tri;
|
|
int readed_;
|
|
|
|
};
|
|
|
|
#endif // PIIODEVICE_H
|