17.10.2013 - Adjusted for QNX, PIPeer release for Windows, Remote console

This commit is contained in:
peri4
2013-10-17 16:12:10 +04:00
parent 4b90f2818e
commit 0f1b528ac6
42 changed files with 585 additions and 171 deletions

View File

@@ -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})

View File

@@ -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;

View File

@@ -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 -

View File

@@ -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

View File

@@ -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;

View File

@@ -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:

View File

@@ -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();

View File

@@ -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);}

View File

@@ -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;}
};

View File

@@ -1,3 +1,6 @@
/*! \file picrc.h
* \brief CRC checksum calculator
*/
/*
PIP - Platform Independent Primitives
Abstract input/output device

View File

@@ -1,3 +1,6 @@
/*! \file pidiagnostics.h
* \brief Connection quality diagnostics
*/
/*
PIP - Platform Independent Primitives
Speed and quality in/out diagnostics

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -1,3 +1,6 @@
/*! \file pievaluator.h
* \brief Mathematic expressions calculator
*/
/*
PIP - Platform Independent Primitives
Evaluator designed for stream computing

View File

@@ -1,3 +1,6 @@
/*! \file pifile.h
* \brief Local file
*/
/*
PIP - Platform Independent Primitives
File

View 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)
*
*/

View File

@@ -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

View File

@@ -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()) {

View File

@@ -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();}

View File

@@ -1,3 +1,6 @@
/*! \file pikbdlistener.h
* \brief Keyboard console input listerner
*/
/*
PIP - Platform Independent Primitives
Keyboard grabber for console

View File

@@ -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) {

View File

@@ -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;}

View File

@@ -1,3 +1,6 @@
/*! \file pimutex.h
* \brief Mutex
*/
/*
PIP - Platform Independent Primitives
Mutex

View File

@@ -1,3 +1,6 @@
/*! \file pipacketextractor.h
* \brief Packets extractor
*/
/*
PIP - Platform Independent Primitives
Packets extractor

View File

@@ -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";
}

View File

@@ -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;

View File

@@ -1,3 +1,6 @@
/*! \file piprocess.h
* \brief Process
*/
/*
PIP - Platform Independent Primitives
Process

View File

@@ -1,3 +1,6 @@
/*! \file piprotocol.h
* \brief Highly configurable from file device
*/
/*
PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP)

View File

@@ -1,3 +1,6 @@
/*! \file piserial.h
* \brief Serial device
*/
/*
PIP - Platform Independent Primitives
COM

View File

@@ -1,3 +1,6 @@
/*! \file pisignals.h
* \brief System signals
*/
/*
PIP - Platform Independent Primitives
Signals

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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:

View File

@@ -1,3 +1,6 @@
/*! \file piusb.h
* \brief USB device
*/
/*
PIP - Platform Independent Primitives
USB, based on libusb

View File

@@ -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);

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 42 KiB