git-svn-id: svn://db.shs.com.ru/pip@284 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2016-11-30 12:21:53 +00:00
parent e66e78ac16
commit 8b72323dd1
25 changed files with 254 additions and 227 deletions

View File

@@ -37,7 +37,7 @@ macro (pip_code_model SRC RESULT)
foreach (_A ${ARGN})
#message(STATUS ${_A})
if (_IS_OPT)
set (OPTS ${_A})
list (APPEND OPTS ${_A})
else ()
if ("${_A}" STREQUAL "OPTIONS")
set(_IS_OPT true)
@@ -73,7 +73,8 @@ macro (pip_code_model SRC RESULT)
if (NEED_PARSE)
message(STATUS "Creating code model based on \"${SRC}\", please wait ... ")
#message(STATUS "exec \"-qP ${OPTS} -o ${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${SRC}\"")
execute_process(COMMAND ${PIP_CMG} -qP ${OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/${SRC} OUTPUT_VARIABLE CMG_OUT)
#message(STATUS "exec ${PIP_CMG} -P ${OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/${SRC}")
execute_process(OUTPUT_VARIABLE CMG_OUT COMMAND ${PIP_CMG} -qP ${OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_ccm -I${PIP_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/${SRC})
message(STATUS "Creating code model done, to use it include \"${PROJECT_NAME}_ccm.h\"")
string(REPLACE "\n" ";" CMG_LIST "${CMG_OUT}")
string(REPLACE "\n" " " CMG_LIST_S "${CMG_OUT}")

View File

@@ -334,7 +334,7 @@ int PIBinaryLog::readBinLog(int id, void *read_to, int max_size, PISystemTime *
}
int PIBinaryLog::read(void *read_to, int max_size) {
int PIBinaryLog::readDevice(void *read_to, int max_size) {
if (lastrecord.id == -1 || isEnd()) return 0;
if(!is_thread_ok && lastrecord.id > 0) return lastrecord.data.size();
if (!canRead()) return -1;
@@ -531,8 +531,8 @@ PIBinaryLog::BinLogInfo PIBinaryLog::getLogInfo(const PIString & path) {
}
PIString PIBinaryLog::constructFullPath() const {
PIString ret(fullPathPrefix() + "://");
PIString PIBinaryLog::constructFullPathDevice() const {
PIString ret;
ret << logDir() << ":" << filePrefix() << ":" << defaultID() << ":";
switch (play_mode) {
case PlayRealTime:
@@ -609,7 +609,7 @@ bool PIBinaryLog::seek(llong filepos) {
}
void PIBinaryLog::configureFromFullPath(const PIString & full_path) {
void PIBinaryLog::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);

View File

@@ -200,22 +200,20 @@ public:
//! Returns if BinLog file is empty
int lastReadedID() const {return lastrecord.id;}
//! Set position in file to reading/playing
#ifdef DOXYGEN
//! 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(default_id, data, size);}
int write(const void * data, int size);
#endif
//! 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;
//! Get binlog info \a BinLogInfo
BinLogInfo logInfo() const {if (is_indexed) return binfo; return getLogInfo(path());}
@@ -231,6 +229,8 @@ public:
//! Go to nearest record
bool seek(const PISystemTime & time);
//! Set position in file to reading/playing
bool seek(llong filepos);
//! Get current record index (position record in file)
@@ -269,7 +269,10 @@ public:
protected:
PIString fullPathPrefix() const {return "binlog";}
void configureFromFullPath(const PIString & full_path);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
int readDevice(void *read_to, int max_size);
int writeDevice(const void * data, int size) {return writeBinLog(default_id, data, size);}
bool openDevice();
bool closeDevice();
void propertyChanged(const PIString &);

View File

@@ -136,7 +136,7 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) {
if (fn.isEmpty()) continue;
PIString & n(name_list[i]);
PIIODevice::DeviceMode dm = PIIODevice::ReadWrite;
splitFullPathWithMode(fn, &fn, &dm);
PIIODevice::splitFullPath(fn, &fn, &dm);
//piCout << fn;
PIIODevice * dev = addDevice(fn, dm);
if (!dev) continue;
@@ -253,10 +253,7 @@ PIString PIConnection::makeConfig() const {
PIStringList dnl(deviceNames(d));
if (dnl.isEmpty()) dnl << PIString::fromNumber(++dn);
piForeachC (PIString & dname, dnl) {
ret << "device." << dname << " = " << d->constructFullPath();
if (d->mode() == PIIODevice::ReadOnly) ret << " (ro)";
if (d->mode() == PIIODevice::WriteOnly) ret << " (wo)";
ret << " #s\n";
ret << "device." << dname << " = " << d->constructFullPath() << " #s\n";
PIDiagnostics * diag = diags_.value(const_cast<PIIODevice * >(d), 0);
if (diag != 0)
ret << "device." << dname << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n";
@@ -840,10 +837,7 @@ PIDiagnostics * PIConnection::diagnostic(const PIString & full_path_name) const
int PIConnection::writeByFullPath(const PIString & full_path, const PIByteArray & data) {
PIString fp(full_path);
if (fp.endsWith(")"))
splitFullPathWithMode(fp, &fp, 0);
fp = PIIODevice::normalizeFullPath(fp);
PIString fp = PIIODevice::normalizeFullPath(full_path);
PIIODevice * dev = __device_pool__->device(fp);
//piCout << "SEND" << full_path << fp;
return write(dev, data);
@@ -1091,22 +1085,6 @@ void PIConnection::DevicePool::deviceReaded(PIConnection::DevicePool::DeviceData
}
void PIConnection::splitFullPathWithMode(PIString fpwm, PIString * full_path, PIIODevice::DeviceMode * mode) {
PIIODevice::DeviceMode dm = PIIODevice::ReadWrite;
if (fpwm.find("(") > 0 && fpwm.find(")") > 0) {
PIString dms(fpwm.right(fpwm.length() - fpwm.find("(")).takeRange("(", ")").trim().toLowerCase().removeAll(" "));
//piCout << dms;
if (dms == "r" || dms == "ro" || dms == "read" || dms == "readonly")
dm = PIIODevice::ReadOnly;
if (dms == "w" || dms == "wo" || dms == "write" || dms == "writeonly")
dm = PIIODevice::WriteOnly;
fpwm.cutRight(fpwm.length() - fpwm.find("(")).trim();
}
if (full_path) *full_path = fpwm;
if (mode) *mode = dm;
}
bool PIConnection::filterValidateHeaderS(void * c, uchar * src, uchar * rec, int size) {
PIPair<PIConnection * , PIString> * p((PIPair<PIConnection * , PIString> * )c);
return p->first->filterValidateHeader(p->second, src, rec, size);

View File

@@ -321,8 +321,6 @@ public:
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data)
EVENT3(qualityChanged, const PIIODevice * , dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality)
static void splitFullPathWithMode(PIString fpwm, PIString * full_path, PIIODevice::DeviceMode * mode);
//! \events
//! \{

View File

@@ -495,7 +495,7 @@ bool PIEthernet::listen(bool threaded) {
}
//#include <QDebug>
int PIEthernet::read(void * read_to, int max_size) {
int PIEthernet::readDevice(void * read_to, int max_size) {
//piCout << "read" << sock;
if (sock == -1) init();
if (sock == -1 || read_to == 0) return -1;
@@ -598,7 +598,7 @@ int PIEthernet::read(void * read_to, int max_size) {
}
int PIEthernet::write(const void * data, int max_size) {
int PIEthernet::writeDevice(const void * data, int max_size) {
if (sock == -1) init();
if (sock == -1 || !isWriteable()) {
//piCoutObj << "Can`t send to uninitialized socket";
@@ -740,8 +740,8 @@ void PIEthernet::propertyChanged(const PIString & name) {
}
PIString PIEthernet::constructFullPath() const {
PIString ret(fullPathPrefix() + "://");
PIString PIEthernet::constructFullPathDevice() const {
PIString ret;
ret << (type() == PIEthernet::UDP ? "UDP" : "TCP") << ":" << readIP() << ":" << readPort();
if (type() == PIEthernet::UDP) {
ret << ":" << sendIP() << ":" << sendPort();
@@ -752,7 +752,7 @@ PIString PIEthernet::constructFullPath() const {
}
void PIEthernet::configureFromFullPath(const PIString & full_path) {
void PIEthernet::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
bool mcast = false;
for (int i = 0; i < pl.size_s(); ++i) {

View File

@@ -218,21 +218,9 @@ public:
//! Send data "data" to address "ip_port" for UDP
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
//! Wait for some data and read it to "read_to"
int read(void * read_to, int max_size);
//! Send data "read_to" with size "max_size" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
int write(const void * data, int max_size);
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
virtual bool canWrite() const {return mode() & WriteOnly;}
PIString constructFullPath() const;
EVENT1(newConnection, PIEthernet * , client)
EVENT0(connected)
EVENT1(disconnected, bool, withError)
@@ -383,9 +371,12 @@ protected:
void propertyChanged(const PIString & name);
PIString fullPathPrefix() const {return PIStringAscii("eth");}
void configureFromFullPath(const PIString & full_path);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0);
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
//! Executes when any read function was successful. Default implementation does nothing
virtual void received(const void * data, int size) {;}

View File

@@ -281,12 +281,12 @@ bool PIFile::remove(const PIString & path) {
}
PIString PIFile::constructFullPath() const {
return fullPathPrefix() + "://" + path();
PIString PIFile::constructFullPathDevice() const {
return path();
}
void PIFile::configureFromFullPath(const PIString & full_path) {
void PIFile::configureFromFullPathDevice(const PIString & full_path) {
setPath(full_path);
}
@@ -365,13 +365,13 @@ void PIFile::setPrecision(int prec) {
}
int PIFile::read(void * read_to, int max_size) {
int PIFile::readDevice(void * read_to, int max_size) {
if (!canRead() || fd == 0) return -1;
return fread(read_to, 1, max_size, fd);
}
int PIFile::write(const void * data, int max_size) {
int PIFile::writeDevice(const void * data, int max_size) {
if (!canWrite() || fd == 0) return -1;
return fwrite(data, 1, max_size, fd);
}

View File

@@ -148,15 +148,6 @@ public:
void setPrecision(int prec);
//! Read from file to "read_to" no more than "max_size" and return readed bytes count
int read(void * read_to, int max_size);
//! Write to file "data" with size "max_size" and return written bytes count
int write(const void * data, int max_size);
//! Write "data" to device
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
PIFile & writeToBinLog(ushort id, const void * data, int size); /// DEPRECATED
@@ -243,8 +234,6 @@ public:
//! Read from file text representation of "v"
PIFile & operator >>(double & v) {if (canRead() && fd != 0) ret = fscanf(fd, "%lf", &v); return *this;}
PIString constructFullPath() const;
EVENT_HANDLER(void, clear);
EVENT_HANDLER(void, remove);
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
@@ -301,7 +290,10 @@ public:
protected:
PIString fullPathPrefix() const {return "file";}
void configureFromFullPath(const PIString & full_path);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
bool openDevice();
bool closeDevice();

View File

@@ -54,7 +54,7 @@ bool PIIOByteArray::open(const PIByteArray &buffer) {
}
int PIIOByteArray::read(void * read_to, int size) {
int PIIOByteArray::readDevice(void * read_to, int size) {
// piCout << "PIIOByteArray::read" << data_ << size << canRead();
if (!canRead() || !data_) return -1;
int ret = piMini(size, data_->size_s() - pos);
@@ -67,7 +67,7 @@ int PIIOByteArray::read(void * read_to, int size) {
}
int PIIOByteArray::write(const void * data, int size) {
int PIIOByteArray::writeDevice(const void * data, int size) {
// piCout << "PIIOByteArray::write" << data << size << canWrite();
if (!canWrite() || !data) return -1;
//piCout << "write" << data;

View File

@@ -3,7 +3,7 @@
*/
/*
PIP - Platform Independent Primitives
PIIODevice wrapper around PIString
PIIODevice wrapper around PIByteArray
Copyright (C) 2016 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
@@ -65,15 +65,14 @@ public:
void seekToEnd() {if (data_) pos = data_->size_s();}
int read(void * read_to, int size);
int write(const void * data_, int size);
//! Insert data \"ba\" into content at current position
int writeByteArray(const PIByteArray & ba);
protected:
bool openDevice();
int readDevice(void * read_to, int size);
int writeDevice(const void * data_, int size);
ssize_t pos;
PIByteArray * data_;

View File

@@ -140,12 +140,27 @@ PIIODevice::~PIIODevice() {
}
void PIIODevice::setOptions(PIIODevice::DeviceOptions o) {
options_ = o;
optionsChanged();
}
bool PIIODevice::setOption(PIIODevice::DeviceOption o, bool yes) {
bool ret = isOptionSet(o);
options_.setFlag(o, yes);
optionsChanged();
return ret;
}
void PIIODevice::_init() {
opened_ = init_ = thread_started_ = false;
raise_threaded_read_ = true;
ret_func_ = 0;
ret_data_ = 0;
tri = 0;
setOptions(0);
setReopenEnabled(true);
setReopenTimeout(1000);
setThreadedReadBufferSize(4096);
@@ -284,6 +299,62 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
}
PIString PIIODevice::constructFullPath() const {
return fullPathPrefix() + "://" + constructFullPathDevice() + fullPathOptions();
}
void PIIODevice::configureFromFullPath(const PIString & full_path) {
PIString fp;
DeviceMode dm = ReadWrite;
DeviceOptions op = 0;
splitFullPath(full_path, &fp, &dm, &op);
setMode(dm);
setOptions(op);
configureFromFullPathDevice(fp);
}
void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * mode, DeviceOptions * opts) {
int dm = 0;
DeviceOptions op = 0;
if (fpwm.find("(") > 0 && fpwm.find(")") > 0) {
PIString dms(fpwm.right(fpwm.length() - fpwm.findLast("(")).takeRange("(", ")").trim().toLowerCase().removeAll(" "));
PIStringList opts(dms.split(","));
piForeachC (PIString & o, opts) {
//piCout << dms;
if (o == "r" || o == "ro" || o == "read" || o == "readonly")
dm |= ReadOnly;
if (o == "w" || o == "wo" || o == "write" || o == "writeonly")
dm |= WriteOnly;
if (o == "br" || o == "blockr" || o == "blockread" || o == "blockingread")
op |= BlockingRead;
if (o == "bw" || o == "blockw" || o == "blockwrite" || o == "blockingwrite")
op |= BlockingRead;
if (o == "brw" || o == "bwr" || o == "blockrw" || o == "blockwr" || o == "blockreadrite" || o == "blockingreadwrite")
op |= BlockingRead | BlockingWrite;
}
fpwm.cutRight(fpwm.length() - fpwm.findLast("(")).trim();
}
if (dm == 0) dm = ReadWrite;
if (full_path) *full_path = fpwm;
if (mode) *mode = (DeviceMode)dm;
if (opts) *opts = op;
}
PIString PIIODevice::fullPathOptions() const {
if (mode_ == ReadWrite && options_ == 0) return PIString();
PIString ret(" (");
bool f = true;
if (mode_ == ReadOnly) {if (!f) ret += ","; f = false; ret += "ro";}
if (mode_ == WriteOnly) {if (!f) ret += ","; f = false; ret += "wo";}
if (options_[BlockingRead]) {if (!f) ret += ","; f = false; ret += "br";}
if (options_[BlockingWrite]) {if (!f) ret += ","; f = false; ret += "bw";}
return ret + ")";
}
PIIODevice * PIIODevice::createFromFullPath(const PIString & full_path) {
PIString prefix = full_path.left(full_path.find(":"));
if (prefix.isEmpty()) return 0;
@@ -306,15 +377,10 @@ PIString PIIODevice::normalizeFullPath(const PIString & full_path) {
PIString ret = nfp_cache.value(full_path);
if (!ret.isEmpty())
return ret;
//piCout << "normalizeFullPath" << full_path;
PIString fp; PIIODevice::DeviceMode md;
PIConnection::splitFullPathWithMode(full_path, &fp, &md);
PIIODevice * d = createFromFullPath(fp);
PIIODevice * d = createFromFullPath(full_path);
//piCout << "normalizeFullPath" << d;
if (d == 0) return PIString();
ret = d->constructFullPath();
if (md == PIIODevice::ReadOnly) ret += " (ro)";
if (md == PIIODevice::WriteOnly) ret += " (wo)";
delete d;
nfp_cache[full_path] = ret;
return ret;

View File

@@ -63,6 +63,14 @@ public:
ReadWrite /*! Device can both read and write */ = 0x03
};
//! \brief Options for PIIODevice, works with some devices
enum DeviceOption {
BlockingRead /*! \a read block until data is received, default off */ = 0x01,
BlockingWrite /*! \a write block until data is sent, default off */ = 0x02
};
typedef PIFlags<DeviceOption> DeviceOptions;
PIIODevice(const PIString & path, DeviceMode mode = ReadWrite);
virtual ~PIIODevice();
@@ -71,7 +79,19 @@ public:
//! Set open mode of device
void setMode(DeviceMode m) {mode_ = m;}
//! Current device options
DeviceOptions options() const {return options_;}
//! Current device option "o" state
bool isOptionSet(DeviceOption o) const {return options_[o];}
//! Set device options
void setOptions(DeviceOptions o);
//! Set device option "o" to "yes" and return previous state
bool setOption(DeviceOption o, bool yes = true);
//! Current path of device
PIString path() const {return property(PIStringAscii("path")).toString();}
@@ -168,22 +188,22 @@ public:
void stop(bool wait = false) {stopThreadedRead(); stopThreadedWrite(); if (wait) while (write_thread.isRunning() || isRunning()) msleep(1);}
//! Reimplement this function to read from your device
virtual int read(void * read_to, int max_size) {piCoutObj << "\"read\" is not implemented!"; return -2;}
//! Read from device maximum "max_size" bytes to "read_to"
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
//! Reimplement this function to write to your device
virtual int write(const void * data, int max_size) {piCoutObj << "\"write\" is 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);}
PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = readDevice(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);}
//! Write maximum "max_size" bytes of "data" to device
int write(const void * data, int max_size) {return writeDevice(data, max_size);}
//! Write "data" to device
int write(const PIByteArray & data) {return writeDevice(data.data(), data.size_s());}
//! Read from device for "timeout_ms" milliseconds and return readed data as PIByteArray. Timeout should to be greater than 0
PIByteArray readForTime(double timeout_ms);
//! Write "data" to device
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
//! Add task to threaded write queue and return task ID
ullong writeThreaded(const void * data, int max_size) {return writeThreaded(PIByteArray(data, uint(max_size)));}
@@ -200,15 +220,20 @@ public:
virtual PIString fullPathPrefix() const {return PIString();}
//! Reimplement to construct full unambiguous string, describes this device, default returns \a fullPathPrefix() + "://" + \a path()
virtual PIString constructFullPath() const {return fullPathPrefix() + "://" + path();}
PIString constructFullPath() const;
//! Reimplement to configure your device with parameters of full unambiguous string. Default implementation does nothing
void configureFromFullPath(const PIString & full_path);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromFullPath() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://".
//! See \ref PIIODevice_sec7
static PIIODevice * createFromFullPath(const PIString & full_path);
static PIString normalizeFullPath(const PIString & full_path);
static void splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * mode = 0, DeviceOptions * opts = 0);
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
@@ -262,7 +287,7 @@ public:
//! \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 task with ID "id"
//! \brief Raise if write thread successfull write some data of task with ID "id"
//! \}
//! \ioparams
@@ -292,19 +317,31 @@ protected:
//! Reimplement to close device, inverse return value will be set to "opened_" variable
virtual bool closeDevice() {return true;} // use path_, type_, opened_, init_ variables
//! Reimplement this function to read from your device
virtual int readDevice(void * read_to, int max_size) {piCoutObj << "\"read\" is not implemented!"; return -2;}
//! Reimplement this function to write to your device
virtual int writeDevice(const void * data, int max_size) {piCoutObj << "\"write\" is not implemented!"; return -2;}
//! Function executed when thread read some data, default implementation execute external slot "ret_func_"
virtual bool threadedRead(uchar * readed, int size);
//! Reimplement to construct full unambiguous string, describes this device. Default implementation returns \a path()
virtual PIString constructFullPathDevice() const {return path();}
//! Reimplement to configure your device with parameters of full unambiguous string. Default implementation does nothing
virtual void configureFromFullPath(const PIString & full_path) {;}
virtual void configureFromFullPathDevice(const PIString & full_path) {;}
//! Reimplement to apply new device options
virtual void optionsChanged() {;}
void terminate();
DeviceMode mode_;
DeviceOptions options_;
ReadRetFunc ret_func_;
bool opened_;
void * ret_data_;
@@ -314,6 +351,7 @@ private:
EVENT_HANDLER(void, write_func);
virtual PIIODevice * copy() const {return 0;}
PIString fullPathOptions() const;
void _init();
void begin();
void run();

View File

@@ -64,7 +64,7 @@ PIString PIIOString::readLine() {
}
int PIIOString::read(void * read_to, int max_size) {
int PIIOString::readDevice(void * read_to, int max_size) {
if (!canRead() || !str) return -1;
PIString rs = str->mid(pos, max_size);
pos += max_size;
@@ -75,7 +75,7 @@ int PIIOString::read(void * read_to, int max_size) {
}
int PIIOString::write(const void * data, int max_size) {
int PIIOString::writeDevice(const void * data, int max_size) {
if (!canWrite() || !str) return -1;
//piCout << "write" << data;
if (pos > str->size_s()) pos = str->size_s();

View File

@@ -68,15 +68,14 @@ public:
//! Read one text line and return it
PIString readLine();
int read(void * read_to, int max_size);
int write(const void * data, int max_size);
//! Insert string \"string\" into content at current position
int writeString(const PIString & string);
protected:
bool openDevice();
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
ssize_t pos;
PIString * str;

View File

@@ -296,6 +296,6 @@ bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
}
PIString PIPacketExtractor::constructFullPath() const {
return fullPathPrefix() + "://";
PIString PIPacketExtractor::constructFullPathDevice() const {
return "";
}

View File

@@ -119,14 +119,6 @@ public:
// //! Returns pointer to \a missedPackets() count. Useful for output to PIConsole
const ullong * missedPackets_ptr() const {return &missed_packets;}
//! Directly call \a read() function of child %device
int read(void * read_to, int max_size) {if (dev == 0) return -1; return dev->read(read_to, max_size);}
//! Directly call \a write() function of child %device
int write(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
PIString constructFullPath() const;
EVENT2(packetReceived, uchar * , data, int, size)
//! \events
@@ -162,8 +154,11 @@ protected:
private:
void construct();
void propertyChanged(const PIString & );
int readDevice(void * read_to, int max_size) {if (dev == 0) return -1; return dev->read(read_to, max_size);}
int writeDevice(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
bool threadedRead(uchar * readed, int size);
PIString fullPathPrefix() const {return "pckext";}
PIString constructFullPathDevice() const;
bool openDevice() {if (dev == 0) return false; return dev->open();}
PIIODevice * dev;

View File

@@ -907,14 +907,14 @@ void PIPeer::changeName(const PIString &new_name) {
}
PIString PIPeer::constructFullPath() const {
PIString ret(fullPathPrefix() + "://");
PIString PIPeer::constructFullPathDevice() const {
PIString ret;
ret << self_info.name << ":" << trustPeerName();
return ret;
}
int PIPeer::read(void *read_to, int max_size) {
int PIPeer::readDevice(void *read_to, int max_size) {
read_buffer_mutex.lock();
bool empty = read_buffer.isEmpty();
read_buffer_mutex.unlock();
@@ -937,7 +937,7 @@ int PIPeer::read(void *read_to, int max_size) {
}
int PIPeer::write(const void *data, int size) {
int PIPeer::writeDevice(const void *data, int size) {
if (trust_peer.isEmpty()) {
sendToAll(data, size);
return size;
@@ -956,7 +956,7 @@ void PIPeer::newTcpClient(PIEthernet *client) {
}
void PIPeer::configureFromFullPath(const PIString & full_path) {
void PIPeer::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);

View File

@@ -135,9 +135,6 @@ public:
const PIString & trustPeerName() const {return trust_peer;}
void setTrustPeerName(const PIString & peer_name) {trust_peer = peer_name;}
void setTcpServerIP(const PIString & ip) {server_ip = ip; tcpClientReconnect();}
PIString constructFullPath() const;
int read(void * read_to, int max_size);
int write(const void * data, int size);
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data)
@@ -148,7 +145,7 @@ protected:
virtual void dataReceived(const PIString & from, const PIByteArray & data) {;}
virtual void peerConnected(const PIString & name) {;}
virtual void peerDisconnected(const PIString & name) {;}
EVENT_HANDLER2(bool, dataRead, uchar *, readed, int, size);
EVENT_HANDLER2(bool, mbcastRead, uchar *, readed, int, size);
@@ -184,7 +181,10 @@ private:
bool openDevice();
bool closeDevice();
PIString fullPathPrefix() const {return "peer";}
void configureFromFullPath(const PIString &full_path);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString &full_path);
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int size);
PeerInfo * quickestPeer(const PIString & to);

View File

@@ -165,8 +165,6 @@ void PISerial::construct() {
fd = -1;
piMonitor.serials++;
setPriority(piHigh);
block_read = false;
block_write = true;
vtime = 10;
sending = false;
setParameters(0);
@@ -358,23 +356,25 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
if (data == 0 || size <= 0) return false;
int ret, all = 0;
if (timeout_ms > 0.) {
setReadIsBlocking(false);
all = read(data, 1);
bool br = setOption(BlockingRead, false);
all = readDevice(data, 1);
tm_.reset();
while (all < size && tm_.elapsed_m() < timeout_ms) {
ret = read(&((uchar * )data)[all], size - all);
ret = readDevice(&((uchar * )data)[all], size - all);
if (ret > 0) all += ret;
else msleep(1);
}
setOption(BlockingRead, br);
received(data, all);
return (all == size);
} else {
setReadIsBlocking(true);
all = read(data, 1);
bool br = setOption(BlockingRead, true);
all = readDevice(data, 1);
while (all < size) {
ret = read(&((uchar * )data)[all], size - all);
ret = readDevice(&((uchar * )data)[all], size - all);
if (ret > 0) all += ret;
}
setOption(BlockingRead, br);
received(data, all);
return (all == size);
}
@@ -396,17 +396,17 @@ PIString PISerial::read(int size, double timeout_ms) {
int ret, all = 0;
uchar td[1024];
if (timeout_ms > 0.) {
setReadIsBlocking(false);
bool br = setOption(BlockingRead, false);
tm_.reset();
if (size <= 0) {
while (tm_.elapsed_m() < timeout_ms) {
ret = read(td, 1024);
ret = readDevice(td, 1024);
if (ret <= 0) msleep(1);
else str << PIString((char*)td, ret);
}
} else {
while (all < size && tm_.elapsed_m() < timeout_ms) {
ret = read(td, size - all);
ret = readDevice(td, size - all);
if (ret <= 0) msleep(1);
else {
str << PIString((char*)td, ret);
@@ -414,18 +414,20 @@ PIString PISerial::read(int size, double timeout_ms) {
}
}
}
setOption(BlockingRead, br);
} else {
setReadIsBlocking(true);
all = read(td, 1);
bool br = setOption(BlockingRead, true);
all = readDevice(td, 1);
str << PIString((char*)td, all);
while (all < size) {
ret = read(td, size - all);
ret = readDevice(td, size - all);
if (ret <= 0) msleep(1);
else {
str << PIString((char*)td, ret);
all += ret;
}
}
setOption(BlockingRead, br);
}
received(str.data(), str.size_s());
return str;
@@ -446,17 +448,17 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
int ret, all = 0;
uchar td[1024];
if (timeout_ms > 0.) {
setReadIsBlocking(false);
bool br = setOption(BlockingRead, false);
tm_.reset();
if (size <= 0) {
while (tm_.elapsed_m() < timeout_ms) {
ret = read(td, 1024);
ret = readDevice(td, 1024);
if (ret <= 0) msleep(1);
else str.append(td, ret);
}
} else {
while (all < size && tm_.elapsed_m() < timeout_ms) {
ret = read(td, size - all);
ret = readDevice(td, size - all);
if (ret <= 0) msleep(1);
else {
str.append(td, ret);
@@ -464,18 +466,20 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
}
}
}
setOption(BlockingRead, br);
} else {
setReadIsBlocking(true);
all = read(td, 1);
bool br = setOption(BlockingRead, true);
all = readDevice(td, 1);
str.append(td, all);
while (all < size) {
ret = read(td, size - all);
ret = readDevice(td, size - all);
if (ret <= 0) msleep(1);
else {
str.append(td, ret);
all += ret;
}
}
setOption(BlockingRead, br);
}
received(str.data(), str.size_s());
return str;
@@ -594,36 +598,25 @@ void PISerial::applySettings() {
void PISerial::setTimeouts() {
#ifdef WINDOWS
COMMTIMEOUTS times;
times.ReadIntervalTimeout = block_read ? vtime : MAXDWORD;
times.ReadTotalTimeoutConstant = block_read ? 0 : 1;
times.ReadTotalTimeoutMultiplier = block_read ? 0 : MAXDWORD;
times.WriteTotalTimeoutConstant = block_write ? 0 : 1;
times.ReadIntervalTimeout = isOptionSet(BlockingRead) ? vtime : MAXDWORD;
times.ReadTotalTimeoutConstant = isOptionSet(BlockingRead) ? 0 : 1;
times.ReadTotalTimeoutMultiplier = isOptionSet(BlockingRead) ? 0 : MAXDWORD;
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
times.WriteTotalTimeoutMultiplier = 0;
if (SetCommTimeouts(PRIVATE->hCom, &times) == -1)
piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
#else
fcntl(fd, F_SETFL, block_read ? 0 : O_NONBLOCK);
fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK);
#endif
}
void PISerial::setReadIsBlocking(bool yes) {
block_read = yes;
if (isOpened()) setTimeouts();
}
void PISerial::setWriteIsBlocking(bool yes) {
block_write = yes;
if (isOpened()) setTimeouts();
}
/** \brief Basic read function
* \details Read to pointer "read_to" no more than "max_size". If read is
* set to blocking this function will be wait at least one byte.
* \returns Readed bytes count
* \sa \a readData() */
int PISerial::read(void * read_to, int max_size) {
int PISerial::readDevice(void * read_to, int max_size) {
#ifdef WINDOWS
if (!canRead()) return -1;
if (sending) return -1;
@@ -640,7 +633,7 @@ int PISerial::read(void * read_to, int max_size) {
}
int PISerial::write(const void * data, int max_size) {
int PISerial::writeDevice(const void * data, int max_size) {
if (fd == -1 || !canWrite()) {
//piCoutObj << "Can`t write to uninitialized COM";
return -1;
@@ -661,7 +654,7 @@ int PISerial::write(const void * data, int max_size) {
#else
int wrote;
wrote = ::write(fd, data, max_size);
if (block_write) tcdrain(fd);
if (isOptionSet(BlockingWrite)) tcdrain(fd);
#endif
return (int)wrote;
//piCoutObj << "Error while sending";
@@ -681,8 +674,8 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
}
PIString PISerial::constructFullPath() const {
PIString ret(fullPathPrefix() + "://");
PIString PISerial::constructFullPathDevice() const {
PIString ret;
ret << path() << ":" << int(inSpeed()) << ":" << dataBitsCount();
if (parameters()[ParityControl]) {
if (parameters()[ParityOdd]) ret << ":O";
@@ -690,19 +683,16 @@ PIString PISerial::constructFullPath() const {
} else ret << ":N";
if (parameters()[TwoStopBits]) ret << ":2";
else ret << ":1";
ret << ":block";
if (block_read) ret << "R";
if (block_write) ret << "W";
return ret;
}
void PISerial::configureFromFullPath(const PIString & full_path) {
void PISerial::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0: setProperty(PIStringAscii("path"), p); break;
case 0: setProperty("path", p); break;
case 1: setProperty("outSpeed", p.toInt()); setProperty("inSpeed", p.toInt()); break;
case 2: setProperty("dataBitsCount", p.toInt()); break;
case 3:
@@ -711,25 +701,6 @@ void PISerial::configureFromFullPath(const PIString & full_path) {
if (p == "o") setParameter(ParityOdd);
break;
case 4: if (p.toInt() == 2) setParameter(TwoStopBits); break;
case 5:
p = p.toLowerCase();
PIString bs = "block";
if (bs == p.mid(0, bs.length())) {
block_write = false;
block_read = false;
p = p.mid(bs.length());
if (p == "r") {
block_read = true;
}
if (p == "w") {
block_write = true;
}
if (p == "rw" || p == "wr") {
block_read = true;
block_write = true;
}
}
break;
}
}
applySettings();
@@ -847,3 +818,8 @@ PIStringList PISerial::availableDevices(bool test) {
}
return dl;
}
void PISerial::optionsChanged() {
if (isOpened()) setTimeouts();
}

View File

@@ -138,12 +138,6 @@ public:
void setVTime(int t) {vtime = t; applySettings();}
//! Set read is blocking for function \a read
void setReadIsBlocking(bool yes);
//! Set write is blocking for functions \a write and \a send
void setWriteIsBlocking(bool yes);
//! Returns device name
@@ -162,16 +156,12 @@ public:
void flush();
int read(void * read_to, int max_size);
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
bool read(void * read_to, int max_size, double timeout_ms);
PIString read(int size = -1, double timeout_ms = 1000.);
PIByteArray readData(int size = -1, double timeout_ms = 1000.);
//! \brief Write to device data "data" with maximum size "max_size" and wait for data written if "wait" is \b true.
//! \returns sended bytes count
int write(const void * data, int max_size);
//! \brief Write to device data "data" with maximum size "size" and wait for data written if "wait" is \b true.
//! \returns \b true if sended bytes count = "size"
bool send(const void * data, int size) {return (write(data, size) == size);}
@@ -184,9 +174,6 @@ public:
//! \brief Write to device byte array "data" and wait for data written if "wait" is \b true.
//! \returns \b true if sended bytes count = size of string
bool send(const PIByteArray & data) {return (write(data.data(), data.size_s()) == data.size_s());}
PIString constructFullPath() const;
//! \brief Returns all available speeds for serial devices
static PIVector<int> availableSpeeds();
@@ -219,9 +206,12 @@ public:
protected:
PIString fullPathPrefix() const {return "ser";}
void configureFromFullPath(const PIString & full_path);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0);
// int write(const void * data, int max_size) {return write(data, max_size);}
void optionsChanged();
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
//! Executes when any read function was successful. Default implementation does nothing
virtual void received(const void * data, int size) {;}
@@ -238,7 +228,7 @@ protected:
PRIVATE_DECLARATION
int fd, vtime;
bool block_read, block_write, sending;
bool sending;
PITimeMeasurer tm_;
};

View File

@@ -71,6 +71,8 @@ public:
protected:
bool openDevice();
bool closeDevice();
int readDevice(void * read_to, int max_size) {return read(read_to, max_size, 0);}
int writeDevice(const void * data, int max_size) {return write(data, max_size, 0);}
private:
void initPrivate();

View File

@@ -295,7 +295,7 @@ bool PIUSB::closeDevice() {
}
int PIUSB::read(void * read_to, int max_size) {
int PIUSB::readDevice(void * read_to, int max_size) {
#ifdef PIP_USB
if (isClosed() || ep_read.isNull()) return -1;
switch (ep_read.transfer_type) {
@@ -310,7 +310,7 @@ int PIUSB::read(void * read_to, int max_size) {
}
int PIUSB::write(const void * data, int max_size) {
int PIUSB::writeDevice(const void * data, int max_size) {
#ifdef PIP_USB
if (isClosed() || ep_write.isNull()) return -1;
switch (ep_read.transfer_type) {
@@ -387,14 +387,14 @@ PICout operator<<(PICout s, const PIUSB::Endpoint & v) {
}
PIString PIUSB::constructFullPath() const {
PIString ret(fullPathPrefix() + "://");
PIString PIUSB::constructFullPathDevice() const {
PIString ret;
ret << PIString::fromNumber(vendorID(), 16).toLowerCase() << ":" << PIString::fromNumber(productID(), 16).toLowerCase() << ":" << deviceNumber() << ":" << endpointRead().address << ":" << endpointWrite().address;
return ret;
}
void PIUSB::configureFromFullPath(const PIString & full_path) {
void PIUSB::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);

View File

@@ -121,18 +121,17 @@ public:
void setTimeoutRead(int t) {setProperty("timeoutRead", t);}
void setTimeoutWrite(int t) {setProperty("timeoutWrite", t);}
int read(void * read_to, int max_size);
int write(const void * data, int max_size);
int controlWrite(const void * data, int max_size);
void flush();
PIString constructFullPath() const;
protected:
PIString fullPathPrefix() const {return "usb";}
void configureFromFullPath(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0);
PIString constructFullPathDevice() const;
void configureFromFullPathDevice(const PIString & full_path);
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
//bool init();
bool openDevice();
bool closeDevice();

View File

@@ -3,7 +3,7 @@
#define PIVERSION_H
#define PIP_VERSION_MAJOR 0
#define PIP_VERSION_MINOR 6
#define PIP_VERSION_MINOR 7
#define PIP_VERSION_REVISION 0
#define PIP_VERSION_SUFFIX ""