17.10.2013 - Adjusted for QNX, PIPeer release for Windows, Remote console
This commit is contained in:
@@ -2,7 +2,7 @@ project(pip)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||
include(CheckFunctionExists)
|
||||
set(VERSION "0.0305")
|
||||
set(VERSION "0.0306")
|
||||
set(SOVERSION ${VERSION})
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(LIBS)
|
||||
@@ -51,12 +51,12 @@ endif ()
|
||||
|
||||
if (${WIN32})
|
||||
list(APPEND LIBS ws2_32 Iphlpapi)
|
||||
include(GenerateExportHeader)
|
||||
execute_process(COMMAND "make_rc_win.bat" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(APPEND CPPS "pip_resource_win.o")
|
||||
add_library(pip SHARED ${CPPS})
|
||||
generate_export_header(pip)
|
||||
if (${CMAKE_C_COMPILER} STREQUAL "cl")
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(pip)
|
||||
add_definitions("/O2 /Ob2 /Ot")
|
||||
else ()
|
||||
add_definitions("-O2")
|
||||
@@ -65,13 +65,12 @@ else ()
|
||||
add_definitions("-O2")
|
||||
if (DEFINED ENV{QNX_HOST})
|
||||
list(APPEND LIBS socket)
|
||||
add_definitions("-ftemplate-depth-32")
|
||||
add_library(pip STATIC ${CPPS})
|
||||
else ()
|
||||
list(APPEND LIBS pthread rt)
|
||||
include(GenerateExportHeader)
|
||||
add_definitions("-Wall -g3")
|
||||
add_library(pip SHARED ${CPPS})
|
||||
generate_export_header(pip)
|
||||
endif ()
|
||||
endif ()
|
||||
target_link_libraries(pip ${LIBS})
|
||||
|
||||
4
main.cpp
4
main.cpp
@@ -245,8 +245,10 @@ int main (int argc, char * argv[]) {
|
||||
console.enableExitCapture();
|
||||
PIProtocol p("/home/peri4/work/ISPUM/nosit_VM6/protocols.conf", "gas", 0, 0, &a__, 4, &b__, 4);
|
||||
p.start();
|
||||
console.addTab("ftab", 'f');
|
||||
console.addVariable("service", &p);
|
||||
console.start();
|
||||
console.addTab("stab", 's');
|
||||
//console.start();
|
||||
console.startServer("cons");
|
||||
console.waitForFinish();
|
||||
return 0;
|
||||
|
||||
@@ -19,6 +19,74 @@
|
||||
|
||||
#include "pibytearray.h"
|
||||
|
||||
/*! \class PIByteArray
|
||||
* \brief Byte array
|
||||
* \details This class based on PIVector<uchar> and provide some handle function
|
||||
* to manipulate it.
|
||||
*
|
||||
* \section PIByteArray_sec0 Usage
|
||||
* PIByteArray can be used to store custom data and manipulate it. There are many
|
||||
* stream operators to store/restore common types to byte array. Store operators
|
||||
* places data at the end of arraym restore operators takes data from the beginning
|
||||
* of array.
|
||||
* In addition there are Base 64 convertions and checksums:
|
||||
* * plain 8-bit
|
||||
* * plain 32-bit
|
||||
* * CRC 8-bit
|
||||
* * CRC 16-bit
|
||||
* * CRC 32-bit
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
const char PIByteArray::base64Table[64] = {
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f};
|
||||
|
||||
const char PIByteArray::base64InvTable[256] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3F,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
|
||||
0x3C, 0x3D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
|
||||
0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE,
|
||||
0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||
0x17, 0x18, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||
0x31, 0x32, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
int PIHuffman::nodeCompare(const void * f, const void * s) {
|
||||
return (reinterpret_cast<node * >(const_cast<void * >(s))->freq -
|
||||
|
||||
142
pibytearray.h
142
pibytearray.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pibytearray.h
|
||||
* \brief Byte array
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
@@ -20,56 +23,13 @@
|
||||
#ifndef PIBYTEARRAY_H
|
||||
#define PIBYTEARRAY_H
|
||||
|
||||
#ifdef DOXYGEN
|
||||
//! This macro allow stream template operators for write and read any type from byte array. Use it with attention!
|
||||
# define PIP_BYTEARRAY_STREAM_ANY_TYPE
|
||||
#endif
|
||||
|
||||
#include "pibitarray.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
static const char base64Table[64] = {
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f};
|
||||
|
||||
static const char base64InvTable[256] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3F,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
|
||||
0x3C, 0x3D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
|
||||
0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE,
|
||||
0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||
0x17, 0x18, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||
0x31, 0x32, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
class PIByteArray;
|
||||
|
||||
class PIHuffman {
|
||||
@@ -90,17 +50,28 @@ private:
|
||||
PIVector<node> nodes;
|
||||
};
|
||||
|
||||
class PIP_EXPORT PIByteArray: public PIVector<uchar> {
|
||||
class PIP_EXPORT PIByteArray: public PIVector<uchar>
|
||||
{
|
||||
public:
|
||||
|
||||
//! Contructs an empty byte array
|
||||
PIByteArray() {;}
|
||||
|
||||
//! Contructs 0-filled byte array size "size"
|
||||
PIByteArray(const uint size) {resize(size);}
|
||||
|
||||
//! Contructs byte array from data "data" and size "size"
|
||||
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
||||
|
||||
|
||||
|
||||
//! Help struct to store/restore custom blocks of data to/from PIByteArray
|
||||
struct RawData {
|
||||
friend PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v);
|
||||
friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v);
|
||||
public:
|
||||
//! Contructs data block
|
||||
RawData(void * data, int size) {d = data; s = size;}
|
||||
//! Contructs data block
|
||||
RawData(const void * data, const int size) {d = const_cast<void * >(data); s = size;}
|
||||
RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;}
|
||||
private:
|
||||
@@ -108,11 +79,19 @@ public:
|
||||
int s;
|
||||
};
|
||||
|
||||
//! Return resized byte array
|
||||
PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
||||
|
||||
//! Convert data to Base 64 and return this byte array
|
||||
PIByteArray & convertToBase64();
|
||||
|
||||
//! Convert data from Base 64 and return this byte array
|
||||
PIByteArray & convertFromBase64();
|
||||
|
||||
//! Return converted to Base 64 data
|
||||
PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
|
||||
|
||||
//! Return converted from Base 64 data
|
||||
PIByteArray fromBase64() {PIByteArray ba(*this); ba.convertFromBase64(); return ba;}
|
||||
|
||||
PIByteArray & compressRLE(uchar threshold = 192);
|
||||
@@ -122,7 +101,10 @@ public:
|
||||
|
||||
PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
|
||||
|
||||
//! Add to the end data "data" with size "size"
|
||||
PIByteArray & append(void * data, int size) {for (int i = 0; i < size; ++i) push_back(((uchar*)data)[i]); return *this;}
|
||||
|
||||
//! Add to the end byte array "data"
|
||||
PIByteArray & append(const PIByteArray & data) {for (int i = 0; i < data.size_s(); ++i) push_back(data[i]); return *this;}
|
||||
/*PIByteArray & operator <<(short v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
PIByteArray & operator <<(ushort v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}
|
||||
@@ -132,10 +114,19 @@ public:
|
||||
PIByteArray & operator <<(ullong v) {for (uint i = 0; i < sizeof(v); ++i) push_back(((uchar*)(&v))[i]); return *this;}*/
|
||||
//PIByteArray & operator <<(const PIByteArray & v) {for (uint i = 0; i < v.size(); ++i) push_back(v[i]); return *this;}
|
||||
|
||||
//! Returns plain 8-bit checksum
|
||||
uchar checksumPlain8();
|
||||
|
||||
//! Returns plain 32-bit checksum
|
||||
uint checksumPlain32();
|
||||
|
||||
//! Returns CRC 8-bit checksum
|
||||
uchar checksumCRC8();
|
||||
|
||||
//! Returns CRC 16-bit checksum
|
||||
ushort checksumCRC16();
|
||||
|
||||
//! Returns CRC 32-bit checksum
|
||||
uint checksumCRC32();
|
||||
|
||||
void operator =(const PIVector<uchar> & d) {resize(d.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = d[i];}
|
||||
@@ -156,65 +147,108 @@ private:
|
||||
} byte;
|
||||
};
|
||||
|
||||
static const char base64Table[64];
|
||||
static const char base64InvTable[256];
|
||||
static PIHuffman huffman;
|
||||
|
||||
};
|
||||
|
||||
//! \relatesalso PIByteArray \brief Output to std::ostream operator
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; return s;}
|
||||
|
||||
//! \relatesalso PIByteArray \brief Output to PICout operator
|
||||
inline PICout operator <<(PICout s, const PIByteArray & ba) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||
|
||||
#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v));
|
||||
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const short v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const double & v) {PBA_OPERATOR_TO return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {s << v.size_s(); int os = s.size_s(); s.enlarge(v.size_s()); if (v.size_s() > 0) memcpy(s.data(os), v.data(), v.size()); return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIList<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||
//! \relatesalso PIByteArray \brief Store operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||
//template <typename T>
|
||||
//inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
|
||||
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
||||
template <typename T>
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
|
||||
#endif
|
||||
|
||||
#undef PBA_OPERATOR_TO
|
||||
#define PBA_OPERATOR_FROM memcpy(&v, s.data(), sizeof(v)); s.remove(0, sizeof(v));
|
||||
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, float & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, double & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); if (sz > 0) memcpy(v.data(), s.data(), v.size()); s.remove(0, v.size()); return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy(v.d, s.data(), v.s); s.remove(0, v.s); return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIList<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||
//! \relatesalso PIByteArray \brief Restore operator
|
||||
template <typename T>
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||
//template <typename T>
|
||||
//inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
||||
template <typename T>
|
||||
inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||
#endif
|
||||
|
||||
#undef PBA_OPERATOR_FROM
|
||||
|
||||
//! \relatesalso PIByteArray \brief Byte arrays compare operator
|
||||
inline bool operator ==(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return false; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return false; return true;}
|
||||
//! \relatesalso PIByteArray \brief Byte arrays compare operator
|
||||
inline bool operator !=(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return true; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return true; return false;}
|
||||
|
||||
#endif // PIBYTEARRAY_H
|
||||
|
||||
22
piconfig.cpp
22
piconfig.cpp
@@ -19,6 +19,28 @@
|
||||
|
||||
#include "piconfig.h"
|
||||
|
||||
/*! \class PIConfig
|
||||
* \brief Configuration file
|
||||
* \details This class provide handle access to configuration file.
|
||||
*
|
||||
* \section PIConfig_sec0 Synopsis
|
||||
* PIConfig reads configuration file and create internal dendritic
|
||||
* representation of all entries of this file. You can easily read
|
||||
* some values and write new.
|
||||
* \image html piconfig.png
|
||||
*
|
||||
* \section PIConfig_sec1 Concepts
|
||||
* Each entry of internal tree has type PIConfig::Entry. This class
|
||||
* has next properties:
|
||||
* * name
|
||||
* * value
|
||||
* * type
|
||||
* * comment
|
||||
* Entry class has many implicit convertions to common types: bolean,
|
||||
* integers, float, double, PIString, PIStringList.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
PIConfig::Entry PIConfig::Branch::_empty;
|
||||
PIConfig::Entry PIConfig::Entry::_empty;
|
||||
|
||||
22
piconfig.h
22
piconfig.h
@@ -1,3 +1,6 @@
|
||||
/*! \file piconfig.h
|
||||
* \brief Configuration file
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Config parser
|
||||
@@ -54,7 +57,9 @@ class PIP_EXPORT PIConfig: public PIFile
|
||||
friend class Entry;
|
||||
friend class Branch;
|
||||
public:
|
||||
//! Contructs and read configuration file at path "path" in mode "mode"
|
||||
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
|
||||
~PIConfig() {/*piForeach (Entry * i, root._children) deleteEntry(i); close();*/}
|
||||
|
||||
class Entry;
|
||||
@@ -172,10 +177,13 @@ public:
|
||||
int _line;
|
||||
};
|
||||
|
||||
//! Returns top-level entry with name "vname", if doesn`t exists return entry with value "def" and set *exist to false
|
||||
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0);
|
||||
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast<PIConfig * >(this)->getValue(vname, def, exist);}
|
||||
|
||||
PICONFIG_GET_VALUE
|
||||
|
||||
//! Returns top-level entries with names matches "vname"
|
||||
Branch getValues(const PIString & vname);
|
||||
|
||||
void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
|
||||
@@ -192,12 +200,21 @@ public:
|
||||
void setValue(const PIString & name, const float value, bool write = true) {setValue(name, ftos(value), "f", write);}
|
||||
void setValue(const PIString & name, const double value, bool write = true) {setValue(name, dtos(value), "f", write);}
|
||||
|
||||
//! Returns root entry
|
||||
Entry & rootEntry() {return root;}
|
||||
|
||||
//! Returns top-level entries count
|
||||
int entriesCount() const {return childCount(&root);}
|
||||
|
||||
//! Returns if top-level entry with name "name" exists
|
||||
bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
|
||||
|
||||
//! Returns all top-level entries
|
||||
Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;}
|
||||
|
||||
//! Returns all entries without children
|
||||
Branch allLeaves() {Branch b; allLeaves(b, &root); b.sort(Entry::compare); return b;}
|
||||
|
||||
int entryIndex(const PIString & name);
|
||||
|
||||
PIString getName(uint number) {return entryByIndex(number)._name;}
|
||||
@@ -216,8 +233,11 @@ public:
|
||||
|
||||
void readAll();
|
||||
void writeAll();
|
||||
|
||||
|
||||
//! Returns current tree delimiter
|
||||
const PIString & delimiter() const {return delim;}
|
||||
|
||||
//! Set current tree delimiter
|
||||
void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();}
|
||||
|
||||
private:
|
||||
|
||||
@@ -356,7 +356,10 @@ void PIConsole::run() {
|
||||
const void * ptr = 0;
|
||||
if (tv.remote) {
|
||||
if (tv.type == 0) {
|
||||
rstr << PIByteArray(tv.rdata);
|
||||
rstr.clear();
|
||||
PIByteArray tba(tv.rdata);
|
||||
tba >> rstr;
|
||||
rstr.trim();
|
||||
ptr = &rstr;
|
||||
} else
|
||||
ptr = tv.rdata.data();
|
||||
@@ -380,12 +383,13 @@ void PIConsole::run() {
|
||||
case 14: clen = printValue(bitsValue(ptr, tv.bitFrom, tv.bitCount), tv.format); break;
|
||||
}
|
||||
if (clen + tv.offset < (uint)col_wid) {
|
||||
PIString ts = PIString(
|
||||
#if defined(QNX) || defined(FREE_BSD)
|
||||
string ts = PIString(col_wid - clen - tv.offset - 1, ' ').stdString();
|
||||
col_wid - clen - tv.offset - 1, ' ');
|
||||
#else
|
||||
string ts = PIString(col_wid - clen - tv.offset, ' ').stdString();
|
||||
col_wid - clen - tv.offset, ' ');
|
||||
#endif
|
||||
printf("%s", ts.c_str());
|
||||
printf("%s", ts.data());
|
||||
}
|
||||
newLine();
|
||||
}
|
||||
@@ -878,6 +882,7 @@ void PIConsole::peerReceived(const PIString & from, const PIByteArray & data) {
|
||||
|
||||
void PIConsole::peerTimer(void * data, int delim) {
|
||||
if (peer == 0) return;
|
||||
//piCout << "timer" << delim;
|
||||
if (server_mode) {
|
||||
if (delim == 20)
|
||||
serverSendInfo();
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file piconsole.h
|
||||
* \brief Console output class
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Console output/input
|
||||
@@ -158,7 +161,7 @@ public:
|
||||
void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));}
|
||||
void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));}
|
||||
void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = y; SetConsoleCursorPosition(hOut, ccoord);}
|
||||
void clearScreen() {FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
|
||||
void clearScreen() {toUpperLeft(); FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
|
||||
FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);}
|
||||
void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written);
|
||||
FillConsoleOutputCharacter(hOut, ' ', width * height - width * ccoord.Y + ccoord.X, ccoord, &written);}
|
||||
|
||||
@@ -712,6 +712,7 @@ public:
|
||||
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;}
|
||||
Type & at(const Key & key_) {return value(key_);}
|
||||
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
||||
};
|
||||
|
||||
|
||||
3
picrc.h
3
picrc.h
@@ -1,3 +1,6 @@
|
||||
/*! \file picrc.h
|
||||
* \brief CRC checksum calculator
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pidiagnostics.h
|
||||
* \brief Connection quality diagnostics
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Speed and quality in/out diagnostics
|
||||
|
||||
@@ -72,6 +72,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
PIEthernet::~PIEthernet() {
|
||||
piMonitor.ethernets--;
|
||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||
stop();
|
||||
closeSocket(sock);
|
||||
//if (buffer_ != 0) delete buffer_;
|
||||
//buffer_ = 0;
|
||||
@@ -110,7 +111,6 @@ bool PIEthernet::init() {
|
||||
#else
|
||||
BOOL bv = TRUE;
|
||||
if (params[PIEthernet::ReuseAddress]) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char * )&bv, sizeof(bv));
|
||||
setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (const char * )&bv, sizeof(bv));
|
||||
#endif
|
||||
//cout << "inited " << sock << ": bc = " << params << endl;
|
||||
//fcntl(sock, F_SETFL, 0/*O_NONBLOCK*/);
|
||||
@@ -170,6 +170,20 @@ bool PIEthernet::closeDevice() {
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::closeSocket(int & sd) {
|
||||
if (sd != -1) {
|
||||
#ifdef WINDOWS
|
||||
shutdown(sd, SD_BOTH);
|
||||
closesocket(sd);
|
||||
#else
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
::close(sd);
|
||||
#endif
|
||||
}
|
||||
sd = -1;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
@@ -195,7 +209,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
piCoutObj << "[PIEthernet] Can`t join multicast group " << group << ", " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
leafs.insert(group, ret);
|
||||
if (ret != sock) leafs.insert(group, ret);
|
||||
#else
|
||||
# ifndef QNX
|
||||
if (!params[Broadcast])
|
||||
@@ -385,11 +399,13 @@ int PIEthernet::write(const void * data, int max_size) {
|
||||
/*if (params[PIEthernet::Broadcast]) saddr_.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
else*/ saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
saddr_.sin_family = AF_INET;
|
||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << max_size << "bytes ...";
|
||||
#ifdef WINDOWS
|
||||
return sendto(sock, (const char * )data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
#else
|
||||
return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
#endif
|
||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||
case TCP_Client:
|
||||
return ::send(sock, (const char *)data, max_size, 0);
|
||||
default: break;
|
||||
@@ -519,12 +535,22 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.address = getSockAddr(ret->ifa_addr);
|
||||
ci.netmask = getSockAddr(ret->ifa_netmask);
|
||||
ci.mac.clear();
|
||||
#ifdef QNX
|
||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).data(), O_RDONLY);
|
||||
if (fd != 0) {
|
||||
nic_config_t nic;
|
||||
devctl(fd, DCMD_IO_NET_GET_CONFIG, &nic, sizeof(nic), 0);
|
||||
::close(fd);
|
||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||
}
|
||||
#else
|
||||
if (s != -1) {
|
||||
struct ifreq ir;
|
||||
strcpy(ir.ifr_name, ret->ifa_name);
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0)
|
||||
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||
}
|
||||
#endif
|
||||
ci.flags = 0;
|
||||
if (ret->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||
if (ret->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file piethernet.h
|
||||
* \brief Ethernet device
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP/TCP Broadcast/Multicast
|
||||
@@ -145,10 +148,8 @@ protected:
|
||||
bool init();
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
#ifdef WINDOWS
|
||||
void closeSocket(int & sd) {if (sd != -1) {shutdown(sd, SD_BOTH); closesocket(sd);} sd = -1;}
|
||||
#else
|
||||
void closeSocket(int & sd) {if (sd != -1) {shutdown(sock, SHUT_RDWR); ::close(sd);} sd = -1;}
|
||||
void closeSocket(int & sd);
|
||||
#ifndef WINDOWS
|
||||
static PIString getSockAddr(sockaddr * s) {return s == 0 ? PIString() : PIString(inet_ntoa(((sockaddr_in*)s)->sin_addr));}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -970,22 +970,22 @@ inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci)
|
||||
tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.);
|
||||
break;
|
||||
case PIEvaluatorTypes::bfJ0:
|
||||
tmpvars[oi].value = j0(value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piJ0(value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfJ1:
|
||||
tmpvars[oi].value = j1(value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piJ1(value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfJN:
|
||||
tmpvars[oi].value = jn(round(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piJn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfY0:
|
||||
tmpvars[oi].value = y0(value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piY0(value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfY1:
|
||||
tmpvars[oi].value = y1(value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piY1(value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfYN:
|
||||
tmpvars[oi].value = yn(round(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
tmpvars[oi].value = piYn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
break;
|
||||
case PIEvaluatorTypes::bfRandom:
|
||||
tmp = static_cast<ldouble>(rand()) / RAND_MAX;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pievaluator.h
|
||||
* \brief Mathematic expressions calculator
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
|
||||
3
pifile.h
3
pifile.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pifile.h
|
||||
* \brief Local file
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
File
|
||||
|
||||
@@ -214,6 +214,34 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
}
|
||||
|
||||
|
||||
/*! \mainpage Title
|
||||
* This is main page
|
||||
/*! \mainpage What is PIP
|
||||
* PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
|
||||
* It is wrap around STL and pure C++. This library can help developers write non-GUI
|
||||
* projects much more quickly, efficiently and customizable than on pure C++.
|
||||
* Library contains more classes, some of them are pure abstract, some classes
|
||||
* can be used as they are, some classes should be inherited to new classes.
|
||||
* PIP provide classes:
|
||||
* * direct output to console (\a PICout)
|
||||
* * containers (\a PIVector, \a PIList, \a PIMap, \a PIStack)
|
||||
* * string (\a PIString, \a PIStringList)
|
||||
* * base object (events and handlers) (\a PIObject)
|
||||
* * thread (\a PIThread)
|
||||
* * timer (\a PITimer)
|
||||
* * console (information output) (\a PIConsole)
|
||||
* * stand-alone
|
||||
* * server
|
||||
* * client
|
||||
* * i/o devices
|
||||
* * base class (\a PIIODevice)
|
||||
* * file (\a PIFile)
|
||||
* * serial port (\a PISerial)
|
||||
* * ethernet (\a PIEthernet)
|
||||
* * USB (\a PIUSB)
|
||||
* * packets extractor (\a PIPacketExtractor)
|
||||
* * command-line arguments parser (\a PICLI)
|
||||
* * math evaluator (\a PIEvaluator)
|
||||
* * peering net node (\a PIPeer)
|
||||
* * process (\a PIProcess)
|
||||
* * state machine (\a PIStateMachine)
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||
|
||||
//! Suffix of PIP version
|
||||
#define PIP_VERSION_SUFFIX ""
|
||||
#define PIP_VERSION_SUFFIX "_r1"
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
@@ -207,6 +207,11 @@
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
# include <ifaddrs.h>
|
||||
# ifdef QNX
|
||||
# include <net/if_dl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <sys/dcmd_io-net.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
# include <mach/mach_traps.h>
|
||||
@@ -813,6 +818,7 @@ public:
|
||||
case Quote: std::cout << '"'; break;
|
||||
};
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
//! Output operator for \a PIFlags<PICoutFormat> values
|
||||
|
||||
@@ -100,6 +100,16 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool
|
||||
}
|
||||
|
||||
|
||||
PIIODevice::~PIIODevice() {
|
||||
stop();
|
||||
if (opened_) {
|
||||
closeDevice();
|
||||
if (!opened_)
|
||||
closed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::check_start(void * data, int delim) {
|
||||
//cout << "check " << tread_started_ << endl;
|
||||
if (open()) {
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
};
|
||||
|
||||
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
||||
virtual ~PIIODevice() {stop(); if (opened_) {closeDevice(); if (!opened_) closed();}}
|
||||
virtual ~PIIODevice();
|
||||
|
||||
//! Current open mode of device
|
||||
DeviceMode mode() const {return mode_;}
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) PIThread::start();}
|
||||
|
||||
//! Stop threaded read
|
||||
void stopThreadedRead() {PIThread::stop();}
|
||||
void stopThreadedRead() {PIThread::terminate();}
|
||||
|
||||
|
||||
//! Return \b true if threaded write is started
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
void startThreadedWrite() {if (!write_thread.isRunning()) write_thread.startOnce();}
|
||||
|
||||
//! Stop threaded write
|
||||
void stopThreadedWrite() {write_thread.stop();}
|
||||
void stopThreadedWrite() {write_thread.terminate();}
|
||||
|
||||
//! Clear threaded write task queue
|
||||
void clearThreadedWriteQueue() {write_thread.lock(); write_queue.clear(); write_thread.unlock();}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pikbdlistener.h
|
||||
* \brief Keyboard console input listerner
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
|
||||
58
pimath.cpp
58
pimath.cpp
@@ -20,8 +20,8 @@
|
||||
#include "pimath.h"
|
||||
|
||||
|
||||
double piJ0(const double & v) {
|
||||
#ifndef PIP_MATH_J0
|
||||
double j0(const double & v) {
|
||||
double x = v;
|
||||
double xsq;
|
||||
double nn;
|
||||
@@ -92,12 +92,14 @@ double j0(const double & v) {
|
||||
q1 = 5428918384092285160.200195092 + xsq * q1;
|
||||
q1 = 493378725179413356211.3278438 + xsq * q1;
|
||||
return p1 / q1;
|
||||
}
|
||||
#else
|
||||
return j0(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double piJ1(const double & v) {
|
||||
#ifndef PIP_MATH_J1
|
||||
double j1(const double & v) {
|
||||
double x = v;
|
||||
double s;
|
||||
double xsq;
|
||||
@@ -172,12 +174,14 @@ double j1(const double & v) {
|
||||
q1 = 1162398708003212287858.529400 + xsq * q1;
|
||||
result = s * x * p1 / q1;
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
return j1(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double piJn(int n, const double & v) {
|
||||
#ifndef PIP_MATH_JN
|
||||
double jn(const int & n, const double & v) {
|
||||
double x = v;
|
||||
double pkm2;
|
||||
double pkm1;
|
||||
@@ -202,18 +206,18 @@ double jn(const int & n, const double & v) {
|
||||
x = -x;
|
||||
}
|
||||
if (n == 0) {
|
||||
result = sg * j0(x);
|
||||
result = sg * piJ0(x);
|
||||
return result;
|
||||
}
|
||||
if (n == 1) {
|
||||
result = sg * j1(x);
|
||||
result = sg * piJ1(x);
|
||||
return result;
|
||||
}
|
||||
if (n == 2) {
|
||||
if (x == 0)
|
||||
result = 0;
|
||||
else
|
||||
result = sg * (2.0 * j1(x) / x - j0(x));
|
||||
result = sg * (2.0 * piJ1(x) / x - piJ0(x));
|
||||
return result;
|
||||
}
|
||||
if (x < 1E-16) {
|
||||
@@ -242,17 +246,19 @@ double jn(const int & n, const double & v) {
|
||||
k = k - 1;
|
||||
} while (k != 0);
|
||||
if (fabs(pk) > fabs(pkm1))
|
||||
ans = j1(x) / pk;
|
||||
ans = piJ1(x) / pk;
|
||||
else
|
||||
ans = j0(x) / pkm1;
|
||||
ans = piJ0(x) / pkm1;
|
||||
result = sg * ans;
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
return jn(n, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double piY0(const double & v) {
|
||||
#ifndef PIP_MATH_Y0
|
||||
double y0(const double & v) {
|
||||
double x = v;
|
||||
double nn;
|
||||
double xsq;
|
||||
@@ -321,14 +327,16 @@ double y0(const double & v) {
|
||||
q4 = 23928830434997818.57439356652 + xsq * q4;
|
||||
q4 = 4192417043410839973.904769661 + xsq * q4;
|
||||
q4 = 372645883898616588198.9980 + xsq * q4;
|
||||
result = p4 / q4 + 2 / M_PI * j0(x) * log(x);
|
||||
result = p4 / q4 + 2 / M_PI * piJ0(x) * log(x);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
return y0(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double piY1(const double & v) {
|
||||
#ifndef PIP_MATH_Y1
|
||||
double y1(const double & v) {
|
||||
double x = v;
|
||||
double nn;
|
||||
double xsq;
|
||||
@@ -396,14 +404,16 @@ double y1(const double & v) {
|
||||
q4 = 29549879358971486742.90758119 + xsq * q4;
|
||||
q4 = 5435310377188854170800.653097 + xsq * q4;
|
||||
q4 = 508206736694124324531442.4152 + xsq * q4;
|
||||
result = x * p4 / q4 + 2 / M_PI * (j1(x) * log(x) - 1 / x);
|
||||
result = x * p4 / q4 + 2 / M_PI * (piJ1(x) * log(x) - 1 / x);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
return y1(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double piYn(int n, const double & v) {
|
||||
#ifndef PIP_MATH_YN
|
||||
double yn(const int & n, const double & v) {
|
||||
int i;
|
||||
double x = v;
|
||||
double a;
|
||||
@@ -418,15 +428,15 @@ double yn(const int & n, const double & v) {
|
||||
s = -1;
|
||||
}
|
||||
if (n == 0) {
|
||||
result = y0(x);
|
||||
result = piY0(x);
|
||||
return result;
|
||||
}
|
||||
if (n == 1) {
|
||||
result = s * y1(x);
|
||||
result = s * piY1(x);
|
||||
return result;
|
||||
}
|
||||
a = y0(x);
|
||||
b = y1(x);
|
||||
a = piY0(x);
|
||||
b = piY1(x);
|
||||
for (i = 1; i <= n - 1; i++) {
|
||||
tmp = b;
|
||||
b = 2 * i / x * b - a;
|
||||
@@ -434,8 +444,10 @@ double yn(const int & n, const double & v) {
|
||||
}
|
||||
result = s * b;
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
return yn(n, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double randomn(double dv, double sv) {
|
||||
|
||||
33
pimath.h
33
pimath.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pimath.h
|
||||
* \brief Many mathematical functions and classes
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Math
|
||||
@@ -27,6 +30,12 @@
|
||||
#else
|
||||
# include <complex.h>
|
||||
# include <math.h>
|
||||
# undef PIP_MATH_J0
|
||||
# undef PIP_MATH_J1
|
||||
# undef PIP_MATH_JN
|
||||
# undef PIP_MATH_Y0
|
||||
# undef PIP_MATH_Y1
|
||||
# undef PIP_MATH_YN
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
@@ -110,24 +119,12 @@ inline complexd log2(const complexd & c) {return log(c) / M_LN2;}
|
||||
inline complexd log10(const complexd & c) {return log(c) / M_LN10;}
|
||||
# endif
|
||||
#endif
|
||||
#ifndef PIP_MATH_J0
|
||||
__attribute__ ((unused)) static double j0(const double & v);
|
||||
#endif
|
||||
#ifndef PIP_MATH_J1
|
||||
__attribute__ ((unused)) static double j1(const double & v);
|
||||
#endif
|
||||
#ifndef PIP_MATH_JN
|
||||
__attribute__ ((unused)) static double jn(const int & n, const double & v);
|
||||
#endif
|
||||
#ifndef PIP_MATH_Y0
|
||||
__attribute__ ((unused)) static double y0(const double & v);
|
||||
#endif
|
||||
#ifndef PIP_MATH_Y1
|
||||
__attribute__ ((unused)) static double y1(const double & v);
|
||||
#endif
|
||||
#ifndef PIP_MATH_YN
|
||||
__attribute__ ((unused)) static double yn(const int & n, const double & v);
|
||||
#endif
|
||||
double piJ0(const double & v);
|
||||
double piJ1(const double & v);
|
||||
double piJn(int n, const double & v);
|
||||
double piY0(const double & v);
|
||||
double piY1(const double & v);
|
||||
double piYn(int n, const double & v);
|
||||
inline double toDb(double val) {return 10. * log10(val);}
|
||||
inline double fromDb(double val) {return pow(10., val / 10.);}
|
||||
inline double toRad(double deg) {return deg * M_PI_180;}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pimutex.h
|
||||
* \brief Mutex
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Mutex
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pipacketextractor.h
|
||||
* \brief Packets extractor
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Packets extractor
|
||||
|
||||
70
pipeer.cpp
70
pipeer.cpp
@@ -21,7 +21,7 @@
|
||||
|
||||
#define _PIPEER_PORT_SYNC_START 13313
|
||||
#define _PIPEER_PORT_SYNC_END 13353
|
||||
#define _PIPEER_IP_MULTICAST "239.13.3.12"
|
||||
#define _PIPEER_IP_MULTICAST "230.13.3.12"
|
||||
#define _PIPEER_MSG_SIZE 8192
|
||||
|
||||
PIPeer::PIPeer(const PIString & name): PIObject() {
|
||||
@@ -29,6 +29,7 @@ PIPeer::PIPeer(const PIString & name): PIObject() {
|
||||
setName(name);
|
||||
self_info.name = name_;
|
||||
self_info.dist = 0;
|
||||
eth_send = 0;
|
||||
//joinMulticastGroup("239.240.241.242");
|
||||
srand(uint(PITimer::elapsed_system_m()));
|
||||
//id_ = name() + "_" + PIString::fromNumber(rand());
|
||||
@@ -37,21 +38,24 @@ PIPeer::PIPeer(const PIString & name): PIObject() {
|
||||
sl.removeAll("127.0.0.1"); sl << "127.0.0.1";
|
||||
initMulticasts(sl);
|
||||
initEths(sl);
|
||||
//piCout << "Peer" << name_;
|
||||
sendSelfInfo();
|
||||
timer.addDelimiter(5);
|
||||
timer.start(1000);
|
||||
sendSelfInfo();
|
||||
}
|
||||
|
||||
|
||||
PIPeer::~PIPeer() {
|
||||
piForeach (PIEthernet * i, mc_eths)
|
||||
i->stopThreadedRead();
|
||||
if (eth_send != 0)
|
||||
eth_send->stopThreadedRead();
|
||||
sendSelfRemove();
|
||||
destroyMulticasts();
|
||||
piForeach (PIEthernet * i, eths)
|
||||
delete i;
|
||||
eths.clear();
|
||||
if (eth_send != 0)
|
||||
delete eth_send;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +92,9 @@ void PIPeer::initEths(const PIStringList & al) {
|
||||
}
|
||||
}
|
||||
}
|
||||
eth_send = new PIEthernet();
|
||||
eth_send->setParameters(0);
|
||||
eth_send->setDebug(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +123,7 @@ void PIPeer::initMulticasts(const PIStringList & al) {
|
||||
if (!ce->open()) continue;
|
||||
if (is_main) if (!ce->joinMulticastGroup(_PIPEER_IP_MULTICAST)) continue;
|
||||
//piCout << "mc binded to" << ce->path();
|
||||
ce->setName(is_main ? "no_send" : "");
|
||||
mc_eths << ce;
|
||||
if (is_main || is_bc) {
|
||||
if (is_main) rec_mc = true;
|
||||
@@ -175,14 +183,6 @@ PIPeer::PeerInfo * PIPeer::quickestPeer(const PIString & to) {
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
|
||||
if (peer->_neth == 0) return false;
|
||||
//piCout << "send to" << peer->name << peer->_naddress << ba.size_s() << "bytes";
|
||||
diag_d.sended(ba.size_s());
|
||||
return peer->_neth->send(peer->_naddress, ba.data(), ba.size_s());
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::send(const PIString & to, const void * data, int size) {
|
||||
PeerInfo * dp = quickestPeer(to);
|
||||
if (dp == 0) {
|
||||
@@ -193,6 +193,7 @@ bool PIPeer::send(const PIString & to, const void * data, int size) {
|
||||
ba << int(4) << self_info.name << to << int(0) << size;
|
||||
PIByteArray fmsg(data, size), cmsg;
|
||||
int msg_count = (size - 1) / _PIPEER_MSG_SIZE + 1;
|
||||
//piCout << "[PIPeer] send" << size << "bytes in" << msg_count << "packets ...";
|
||||
for (int i = 0; i < msg_count; ++i) {
|
||||
int csize = (i == msg_count - 1) ? ((size - 1) % _PIPEER_MSG_SIZE + 1) : _PIPEER_MSG_SIZE;
|
||||
cmsg.clear();
|
||||
@@ -201,17 +202,23 @@ bool PIPeer::send(const PIString & to, const void * data, int size) {
|
||||
cmsg.append(fmsg.data(i * _PIPEER_MSG_SIZE), csize);
|
||||
if (!sendToNeighbour(dp, cmsg)) return false;
|
||||
}
|
||||
//piCout << "[PIPeer] send" << size << "bytes ok";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::dataRead(uchar * readed, int size) {
|
||||
diag_d.received(size);
|
||||
if (size < 16) return true;
|
||||
PIByteArray ba(readed, size), sba;
|
||||
int type, cnt, rec_size;
|
||||
PIString from, to;
|
||||
ba >> type >> from >> to >> cnt >> rec_size;
|
||||
//piCout << "[PIPeer \"" + name_ + "\"] Received packet" << type << from << to << cnt << rec_size;
|
||||
ba >> type;
|
||||
//piCout << "[PIPeer \"" + name_ + "\"] Received packet" << type;
|
||||
if (type != 4) return true;
|
||||
PIMutexLocker locker(eth_mutex);
|
||||
diag_d.received(size);
|
||||
ba >> from >> to >> cnt >> rec_size;
|
||||
//piCout << "[PIPeer \"" + name_ + "\"] Received packet" << /*type << from << to << cnt <<*/ rec_size;
|
||||
if (type == 4) { // data packet
|
||||
if (to == self_info.name) { // my packet
|
||||
int msg_count, cmsg;
|
||||
@@ -256,17 +263,20 @@ bool PIPeer::dataRead(uchar * readed, int size) {
|
||||
|
||||
|
||||
bool PIPeer::multicastRead(uchar * data, int size) {
|
||||
if (size < 8) return true;
|
||||
int type;
|
||||
PIByteArray ba(data, size);
|
||||
ba >> type;
|
||||
if (type <= 0 || type >= 4) return true;
|
||||
PeerInfo pi;
|
||||
PIVector<PeerInfo> rpeers;
|
||||
ba >> pi.name;
|
||||
//piCout << "read type" << type << "from" << pi.name;
|
||||
if (pi.name == name_) return true;
|
||||
PIMutexLocker locker(mc_mutex);
|
||||
diag_s.received(size);
|
||||
int header;
|
||||
PeerInfo pi;
|
||||
PIByteArray ba(data, size);
|
||||
PIVector<PeerInfo> rpeers;
|
||||
ba >> header >> pi.name;
|
||||
//piCout << "read type" << header << "from" << pi.name;
|
||||
if (pi.name == name_) return true;
|
||||
//piCout << "analyz ...";
|
||||
switch (header) {
|
||||
switch (type) {
|
||||
case 1: // new peer accepted
|
||||
//piCout << "new peer packet ...";
|
||||
if (hasPeer(pi.name)) break;
|
||||
@@ -346,17 +356,31 @@ bool PIPeer::multicastRead(uchar * data, int size) {
|
||||
}
|
||||
|
||||
|
||||
bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
|
||||
if (peer->_neth == 0) return false;
|
||||
//piCout << "[PIPeer] sendToNeighbour" << (eth_send->readAddress()) << peer->_naddress << ba.size_s() << "bytes ...";
|
||||
//bool ok = peer->_neth->send(peer->_naddress, ba.data(), ba.size_s());
|
||||
bool ok = eth_send->send(peer->_naddress, ba.data(), ba.size_s());
|
||||
//piCout << "[PIPeer] sendToNeighbour" << (ok ? "ok" : "fail");
|
||||
if (ok) diag_d.sended(ba.size_s());
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::sendMulticast(const PIByteArray & ba) {
|
||||
//piCout << "send muticast ...";
|
||||
piForeach (PIEthernet * e, mc_eths) {
|
||||
if (e->name() == "no_send") continue;
|
||||
for (int p = _PIPEER_PORT_SYNC_START; p < _PIPEER_PORT_SYNC_END; ++p) {
|
||||
e->setSendPort(p);
|
||||
//errorClear();
|
||||
//piCout << "send to" << e->sendAddress() << e->send(ba);
|
||||
//piCout << "send to" << e->path() << e->sendAddress();// << e->send(ba);
|
||||
//piCout << PIEthernet::ethErrorString();
|
||||
e->send(ba);
|
||||
diag_s.sended(ba.size_s());
|
||||
}
|
||||
}
|
||||
//piCout << "send muticast ok";
|
||||
}
|
||||
|
||||
|
||||
|
||||
6
pipeer.h
6
pipeer.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pipeer.h
|
||||
* \brief Peering net node
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Peer - named I/O ethernet node, forming self-organized peering network
|
||||
@@ -145,8 +148,9 @@ private:
|
||||
|
||||
PIVector<PIEthernet * > eths;
|
||||
PIVector<PIEthernet * > mc_eths;
|
||||
PIEthernet * eth_send;
|
||||
PITimer timer;
|
||||
PIMutex mc_mutex;
|
||||
PIMutex mc_mutex, eth_mutex;
|
||||
bool rec_mc, rec_bc;
|
||||
|
||||
PeerInfo self_info;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file piprocess.h
|
||||
* \brief Process
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file piprotocol.h
|
||||
* \brief Highly configurable from file device
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file piserial.h
|
||||
* \brief Serial device
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pisignals.h
|
||||
* \brief System signals
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Signals
|
||||
|
||||
@@ -249,10 +249,10 @@ PIString & PIString::cutMid(const int start, const int len) {
|
||||
PIString & PIString::trim() {
|
||||
int st = 0, fn = 0;
|
||||
for (int i = 0; i < length(); ++i)
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r')
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
||||
{st = i; break;}
|
||||
for (int i = length() - 1; i >= 0; --i)
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r')
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
||||
{fn = i; break;}
|
||||
*this = mid(st, fn - st + 1);
|
||||
return *this;
|
||||
@@ -262,10 +262,10 @@ PIString & PIString::trim() {
|
||||
PIString PIString::trimmed() const {
|
||||
int st = 0, fn = 0;
|
||||
for (int i = 0; i < length(); ++i)
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r')
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
||||
{st = i; break;}
|
||||
for (int i = length() - 1; i >= 0; --i)
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r')
|
||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
||||
{fn = i; break;}
|
||||
return mid(st, fn - st + 1);
|
||||
}
|
||||
|
||||
@@ -676,7 +676,7 @@ inline PICout operator <<(PICout s, const PIString & v) {s.space(); s.quote(); s
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {int l = v.lengthAscii(); s << l; if (l <= 0) return s; int os = s.size_s(); s.enlarge(l); memcpy(s.data(os), v.data(), l); return s;}
|
||||
|
||||
//! \relatesalso PIString \relatesalso PIByteArray \brief Input operator from PIByteArray
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {int l; s >> l; if (l <= 0) return s; v = PIString((const char * )s.data(), l); s.remove(0, l); return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {if (s.size() < 4) {v.clear(); return s;} int l; s >> l; if (l <= 0) return s; v = PIString((const char * )s.data(), l); s.remove(0, l); return s;}
|
||||
|
||||
|
||||
//! \relatesalso PIString \brief Return concatenated string
|
||||
|
||||
@@ -63,6 +63,7 @@ void piUSleep(int usecs) {
|
||||
|
||||
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
||||
piMonitor.threads++;
|
||||
thread = 0;
|
||||
data_ = data;
|
||||
ret_func = func;
|
||||
running = lockRun = false;
|
||||
@@ -74,6 +75,7 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay)
|
||||
|
||||
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
piMonitor.threads++;
|
||||
thread = 0;
|
||||
ret_func = 0;
|
||||
running = lockRun = false;
|
||||
priority_ = piNormal;
|
||||
@@ -84,7 +86,7 @@ PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
|
||||
PIThread::~PIThread() {
|
||||
piMonitor.threads--;
|
||||
if (!running) return;
|
||||
if (!running || thread == 0) return;
|
||||
#ifndef WINDOWS
|
||||
pthread_cancel(thread);
|
||||
#else
|
||||
|
||||
29
pitimer.cpp
29
pitimer.cpp
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*ccc
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
@@ -20,6 +20,33 @@
|
||||
#include "pitimer.h"
|
||||
#include "pisystemtests.h"
|
||||
|
||||
|
||||
/*! \class PITimer
|
||||
* \brief Timer
|
||||
*
|
||||
* \section PITimer_sec0 Synopsis
|
||||
* This class implements timer function. PIP timers supports 3 way to tick notify,
|
||||
* frequency delimiters and time measurements.
|
||||
* \section PITimer_sec1 Notify variants
|
||||
* Notify variants:
|
||||
* * "slot" - static function with format void func(void * data, int delimiter);
|
||||
* * event - \a void timeout(void * data, int delimiter);
|
||||
* * virtual function - \a void tick(void * data, int delimiter).
|
||||
* All this variant are equivalent, use most applicable.
|
||||
* \section PITimer_sec2 Frequency delimiters
|
||||
* Frequency delimiter is an integer number and "slot" function. If "slot" function is null
|
||||
* timer main "slot" will be used. Each delimiter numbers tick timer will be execute
|
||||
* delimiters or timer main "slot" function with \b delimiter value = delimiter number.
|
||||
* Example: \snippet pitimer.cpp delimiter
|
||||
* \section PITimer_sec3 Time measurements
|
||||
* PITimer can be used as time measurer. Function \a reset() set time mark to current
|
||||
* system time, then functions double elapsed_*() returns time elapsed from this mark.
|
||||
* These functions can returns nano-, micro-, milli- and seconds with suffixes "n", "u", "m"
|
||||
* and "s";
|
||||
* Example: \snippet pitimer.cpp elapsed
|
||||
*/
|
||||
|
||||
|
||||
bool operator ==(const PITime & t0, const PITime & t1) {
|
||||
return (t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||
}
|
||||
|
||||
111
pitimer.h
111
pitimer.h
@@ -1,3 +1,6 @@
|
||||
/*! \file pitimer.h
|
||||
* \brief Timer
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
@@ -153,31 +156,38 @@ class PIP_EXPORT PITimer
|
||||
{
|
||||
PIOBJECT(PITimer)
|
||||
public:
|
||||
|
||||
//! \brief Constructs timer with execution function \b slot and common data \b data.
|
||||
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
||||
PITimer(bool threaded);
|
||||
virtual ~PITimer();
|
||||
|
||||
|
||||
//! \brief Set custom data.
|
||||
void setData(void * data_) {data = data_;}
|
||||
|
||||
//! \brief Set timer execution function.
|
||||
void setSlot(TimerEvent slot) {ret_func = slot;}
|
||||
|
||||
//! \brief Returns current loop delay.
|
||||
double interval() const {return interval_;}
|
||||
#ifndef PIP_TIMER_RT
|
||||
|
||||
EVENT_HANDLER0(void, reset) {
|
||||
# ifdef WINDOWS
|
||||
EVENT_HANDLER0(void, reset) {t_st = GetCurrentTime();}
|
||||
t_st = GetCurrentTime();
|
||||
# elif defined(MAC_OS)
|
||||
EVENT_HANDLER0(void, reset) {clock_get_time(__pi_mac_clock, &t_st);}
|
||||
clock_get_time(__pi_mac_clock, &t_st);
|
||||
# else
|
||||
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||
clock_gettime(0, &t_st);
|
||||
# endif
|
||||
EVENT_HANDLER1(bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
||||
}
|
||||
EVENT_HANDLER1(void, start, int, msecs) {start(double(msecs));}
|
||||
EVENT_HANDLER1(void, start, double, msecs);
|
||||
EVENT_HANDLER0(void, stop) {running_ = false;}
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||
#ifndef PIP_TIMER_RT
|
||||
EVENT_HANDLER0(void, stop) {running_ = false; PIThread::stop();}
|
||||
#else
|
||||
EVENT_HANDLER0(void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(void, start, double, msecs);
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||
EVENT_HANDLER2(void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||
EVENT_HANDLER0(void, stop);
|
||||
EVENT_HANDLER0(bool, waitForFinish) {return waitForFinish(-1);}
|
||||
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs);
|
||||
@@ -186,9 +196,17 @@ public:
|
||||
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
||||
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
||||
#endif
|
||||
|
||||
//! \brief Add frequency delimiter \b delim with optional delimiter slot \b slot.
|
||||
void addDelimiter(int delim, TimerEvent slot = 0) {ret_funcs << TimerSlot(slot, delim);}
|
||||
|
||||
//! \brief Remove all frequency delimiters \b delim.
|
||||
void removeDelimiter(int delim) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
||||
|
||||
//! \brief Remove all frequency delimiters with slot \b slot.
|
||||
void removeDelimiter(TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot) {ret_funcs.remove(i); i--;}}
|
||||
|
||||
//! \brief Remove all frequency delimiters \b delim with slot \b slot.
|
||||
void removeDelimiter(int delim, TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot && ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}}
|
||||
void setDelimiterValue(int delim, int value) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].delim == delim) ret_funcs[i].tick = value;}
|
||||
void setDelimiterValue(TimerEvent slot, int value) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot) ret_funcs[i].tick = value;}
|
||||
@@ -197,20 +215,40 @@ public:
|
||||
int delimiterValue(int delim, TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot && ret_funcs[i].delim == delim) return ret_funcs[i].tick; return -1;}
|
||||
EVENT_HANDLER0(void, clearDelimiters) {ret_funcs.clear();}
|
||||
|
||||
|
||||
//! \brief Returns nanoseconds elapsed from last \a reset() execution or from timer creation.
|
||||
double elapsed_n(); // nanoseconds
|
||||
|
||||
//! \brief Returns microseconds elapsed from last \a reset() execution or from timer creation.
|
||||
double elapsed_u(); // microseconds
|
||||
|
||||
//! \brief Returns milliseconds elapsed from last \a reset() execution or from timer creation.
|
||||
double elapsed_m(); // milliseconds
|
||||
|
||||
//! \brief Returns seconds elapsed from last \a reset() execution or from timer creation.
|
||||
double elapsed_s(); // seconds
|
||||
|
||||
|
||||
double reset_time_n(); // nanoseconds
|
||||
double reset_time_u(); // microseconds
|
||||
double reset_time_m(); // milliseconds
|
||||
double reset_time_s(); // seconds
|
||||
|
||||
|
||||
//! \brief Returns time mark of last \a reset() execution or timer creation.
|
||||
PISystemTime reset_time();
|
||||
|
||||
|
||||
//! \brief Returns nanoseconds representation of current system time.
|
||||
static double elapsed_system_n(); // nanoseconds
|
||||
|
||||
//! \brief Returns microseconds representation of current system time.
|
||||
static double elapsed_system_u(); // microseconds
|
||||
|
||||
//! \brief Returns milliseconds representation of current system time.
|
||||
static double elapsed_system_m(); // milliseconds
|
||||
|
||||
//! \brief Returns seconds representation of current system time.
|
||||
static double elapsed_system_s(); // seconds
|
||||
|
||||
|
||||
@@ -244,7 +282,60 @@ public:
|
||||
|
||||
EVENT2(timeout, void * , data, int, delimiter)
|
||||
|
||||
//! \handlers
|
||||
//! \{
|
||||
|
||||
/** \fn void reset()
|
||||
* \brief Set internal time mark to current system time
|
||||
* \details This function used for set start time mark. Later
|
||||
* you can find out elapsed time from this time mark to any
|
||||
* moment of time with \a elapsed_s(), \a elapsed_m(),
|
||||
* \a elapsed_u() or \a elapsed_n() function.
|
||||
* \sa \a elapsed_s(), \a elapsed_m(), \a elapsed_u(), \a elapsed_n() */
|
||||
|
||||
/** \fn void start(int msecs)
|
||||
* \brief Start timer with \b msecs loop delay
|
||||
* \details Start execution of timer functions with frequency = 1 / msecs Hz. */
|
||||
|
||||
/** \fn void start(double msecs)
|
||||
* \brief Start timer with \b msecs loop delay
|
||||
* \details Start execution of timer functions with frequency = 1. / msecs Hz.
|
||||
* Instead of \a start(int msecs) function this variant allow start timer
|
||||
* with frequencies more than 1 kHz. */
|
||||
|
||||
//! \fn void stop()
|
||||
//! \brief Stop timer
|
||||
|
||||
/** \fn void deferredStart(double interval_msecs, double delay_msecs)
|
||||
* \brief Start timer with \b interval_msecs loop delay after \b delay_msecs delay.
|
||||
* \details Timer wait \b delay_msecs milliseconds and then normally starts with
|
||||
* \b interval_msecs loop delay.
|
||||
* \sa \a void start(double msecs), \a void deferredStart(double interval_msecs, const PIDateTime & start_datetime) */
|
||||
|
||||
/** \fn void deferredStart(double interval_msecs, const PIDateTime & start_datetime)
|
||||
* \brief Start timer with \b interval_msecs loop delay after \b start_datetime date and time.
|
||||
* \details Timer wait until \b start_datetime and then normally starts with
|
||||
* \b interval_msecs loop delay.
|
||||
* \sa \a void start(double msecs), \a void deferredStart(double interval_msecs, double delay_msecs) */
|
||||
|
||||
//! \fn void clearDelimiters()
|
||||
//! \brief Remove all frequency delimiters.
|
||||
|
||||
//! \}
|
||||
//! \events
|
||||
//! \{
|
||||
|
||||
/** \fn void timeout(void * data, int delimiter)
|
||||
* \brief Raise on timer tick
|
||||
* \details \b Data can be set with function \a setData(void * data) or from constructor.
|
||||
* \b Delimiter if frequency delimiter, 1 for main loop. */
|
||||
|
||||
|
||||
//! \}
|
||||
|
||||
protected:
|
||||
//! Virtual timer execution function, similar to "slot" or event \a void timeout(void * data, int delimiter).
|
||||
//! By default is empty.
|
||||
virtual void tick(void * data, int delimiter) {;}
|
||||
|
||||
private:
|
||||
|
||||
3
piusb.h
3
piusb.h
@@ -1,3 +1,6 @@
|
||||
/*! \file piusb.h
|
||||
* \brief USB device
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
USB, based on libusb
|
||||
|
||||
@@ -31,8 +31,6 @@ void key_event(char key, void * ) {
|
||||
if (ind < 0 || ind >= as.size_s()) return;
|
||||
selected = true;
|
||||
console.connectToServer(as[ind]);
|
||||
console.clearScreen();
|
||||
piCout << "Connecting to" << console.selectedServer() << "...";
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@@ -52,7 +50,7 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
if (!selected) return 0;
|
||||
console.clearScreen();
|
||||
//console.clearScreen();
|
||||
piCout << "Connecting to" << console.selectedServer() << "...";
|
||||
while (!PIKbdListener::exiting) {
|
||||
msleep(20);
|
||||
|
||||
BIN
serial.odg
BIN
serial.odg
Binary file not shown.
BIN
serial_.emf
BIN
serial_.emf
Binary file not shown.
BIN
serial_.odg
BIN
serial_.odg
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 42 KiB |
Reference in New Issue
Block a user