15.10.2012 - version 0.2.0 - PIIODevice - base of file, ethernet, serial and packets extractor. PIEthernet now support also TCP (client and server). PIConsole now can align labels in each column individually.
This commit is contained in:
@@ -2,14 +2,17 @@
|
||||
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
|
||||
|
||||
[CMake]
|
||||
BuildDirs=/home/peri4/pprojects/pip/
|
||||
Build Directory Count=1
|
||||
CMakeDir=/usr/share/cmake/Modules
|
||||
Current CMake Binary=file:///usr/bin/cmake
|
||||
CurrentBuildDir=file:///home/peri4/pprojects/pip/
|
||||
CurrentBuildType=Debug
|
||||
CurrentInstallDir=
|
||||
Current Build Directory Index=0
|
||||
ProjectRootRelative=./
|
||||
|
||||
[CMake][CMake Build Directory 0]
|
||||
Build Directory Path=file:///home/peri4/pprojects/pip/
|
||||
Build Type=
|
||||
CMake Binary=file:///usr/bin/cmake
|
||||
Install Directory=file:///usr/local
|
||||
|
||||
[Launch]
|
||||
Launch Configurations=Launch Configuration 0
|
||||
|
||||
@@ -24,15 +27,15 @@ Arguments=
|
||||
Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
|
||||
Dependency Action=Build
|
||||
EnvironmentGroup=default
|
||||
Executable=
|
||||
Executable=file:///home/peri4/pprojects/pip/pip_test
|
||||
External Terminal=konsole --noclose --workdir %workdir -e %exe
|
||||
Project Target=pip,pip_test
|
||||
Project Target=
|
||||
Use External Terminal=false
|
||||
Working Directory=
|
||||
isExecutable=false
|
||||
isExecutable=true
|
||||
|
||||
[MakeBuilder]
|
||||
Number Of Jobs=5
|
||||
Number Of Jobs=8
|
||||
|
||||
[Project]
|
||||
VersionControlSupport=kdevgit
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
project(pip)
|
||||
find_package(Qt4)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} . ${QT_INCLUDES})
|
||||
file(GLOB CPPS "pi*.cpp")
|
||||
if (${WIN32})
|
||||
add_definitions(-Wall -O2)
|
||||
@@ -17,5 +18,5 @@ add_executable(pip_test "main.cpp")
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip_test pthread ws2_32 pip)
|
||||
else (${WIN32})
|
||||
target_link_libraries(pip_test pthread rt pip)
|
||||
target_link_libraries(pip_test pthread rt pip ${QT_QTCORE_LIBRARY})
|
||||
endif (${WIN32})
|
||||
|
||||
107
main.cpp
Normal file → Executable file
107
main.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Test program
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -117,66 +117,67 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Data {
|
||||
ushort header;
|
||||
int counter;
|
||||
float f0;
|
||||
float f1;
|
||||
ushort checksum;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class Prot: public PIProtocol {
|
||||
public:
|
||||
Prot() {
|
||||
setReceiverDevice("/dev/ttyS0", PISerial::S115200, true);
|
||||
setReceiverDataHeader(&rec, 2);
|
||||
setReceiverData(&rec.counter, sizeof(rec) - 2);
|
||||
setSenderData(&send, sizeof(send));
|
||||
setExpectedFrequency(20.f);
|
||||
setSenderFrequency(20.f);
|
||||
send.header = 0xAABB;
|
||||
rec.header = 0xAABB;
|
||||
start();
|
||||
}
|
||||
|
||||
virtual bool validate() {
|
||||
if (rec.checksum != PIByteArray(&rec, sizeof(rec)-2).checksumCRC16()) return false;
|
||||
return true;
|
||||
}
|
||||
virtual bool aboutSend() {
|
||||
send.counter++;
|
||||
send.checksum = PIByteArray(&send, sizeof(send)-2).checksumCRC16();
|
||||
return true;
|
||||
}
|
||||
|
||||
Data send, rec;
|
||||
struct Packet {
|
||||
int from;
|
||||
int to;
|
||||
float data;
|
||||
int cs;
|
||||
};
|
||||
|
||||
Prot p;
|
||||
bool retH(void * d, uchar * src, uchar * rec, int size) {
|
||||
return (*((int*)rec)) == 1;
|
||||
};
|
||||
|
||||
void key(char k, void*) {
|
||||
switch (k) {
|
||||
case '0': p.setSenderData(&p.send, sizeof(p.send)); break;
|
||||
case '1': p.setSenderData(&p.send, sizeof(p.send) - 1); break;
|
||||
case '2': p.send.header = 0xAABB; break;
|
||||
case '3': p.send.header = 0xACBD; break;
|
||||
}
|
||||
}
|
||||
bool retF(void * d, uchar * data, int size) {
|
||||
cout << "rec " << size << endl;
|
||||
return true;
|
||||
};
|
||||
|
||||
PIConsole c(false, key);
|
||||
int main(int argc, char * argv[]) {
|
||||
c.enableExitCapture();
|
||||
c.addVariable("prot", &p);
|
||||
if (argc > 1) c.start();
|
||||
c.waitForFinish();
|
||||
c.stop();
|
||||
/*Packet p, mp;
|
||||
p.from = mp.from = 1;
|
||||
p.to = mp.to = 2;
|
||||
PISerial ser("/dev/ttyS0");
|
||||
ser.setSpeed(PISerial::S115200);
|
||||
ser.open();
|
||||
ser.setReadIsBlocking(true);
|
||||
PIPacketExtractor pe(&ser, &mp, 8, 8);
|
||||
pe.setThreadedReadSlot(retF);
|
||||
pe.setHeaderCheckSlot(retH);
|
||||
pe.startThreadedRead();
|
||||
ser.write(&p, sizeof(p));
|
||||
p.from = 2;
|
||||
ser.write(&p, sizeof(p));
|
||||
msleep(1000);
|
||||
exit(0);*/
|
||||
PICodec codec;
|
||||
|
||||
exit(0);
|
||||
/*
|
||||
vec<int> my_v; vector<int> stl_v; QVector<int> qt_v;
|
||||
double el;
|
||||
PITimer tm;
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
my_v.push_back(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << endl;
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
stl_v.push_back(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << endl;
|
||||
|
||||
tm.reset();
|
||||
for (uint i = 0; i < 500000; ++i)
|
||||
qt_v.append(i);
|
||||
el = tm.elapsed_m();
|
||||
cout << el << endl;
|
||||
|
||||
exit(0);
|
||||
*/
|
||||
bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true;
|
||||
bool succ = true;
|
||||
cout << "== PIP test program ==" << endl;
|
||||
@@ -239,7 +240,7 @@ int main(int argc, char * argv[]) {
|
||||
else cout << "== Fail ==" << endl;
|
||||
|
||||
cout << endl << "== File test ==" << endl;
|
||||
PIFile file(" file_test", PIFile::New | PIFile::ReadWrite);
|
||||
PIFile file(" file_test", PIIODevice::ReadWrite);
|
||||
cout << " file \"" << file.path() << "\" is ";
|
||||
if (!file.isOpened()) cout << "not ";
|
||||
cout << "opened" << endl;
|
||||
|
||||
2
pibitarray.h
Normal file → Executable file
2
pibitarray.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Bit array
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pibytearray.cpp
Normal file → Executable file
2
pibytearray.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
4
pibytearray.h
Normal file → Executable file
4
pibytearray.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Byte array
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -96,6 +96,8 @@ public:
|
||||
PIByteArray(const uint size) {resize(size);}
|
||||
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
||||
|
||||
PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
||||
|
||||
PIByteArray & convertToBase64();
|
||||
PIByteArray & convertFromBase64();
|
||||
PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
|
||||
|
||||
2
pichar.h
Normal file → Executable file
2
pichar.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Unicode char
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
4
picli.cpp
Normal file → Executable file
4
picli.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Command-Line Parser
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -69,7 +69,7 @@ void PICLI::parse() {
|
||||
_args_opt << cra;
|
||||
continue;
|
||||
}
|
||||
cout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
||||
piCout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
||||
}
|
||||
if (last == 0 ? false : last->has_value) {
|
||||
last->value = cra;
|
||||
|
||||
2
picli.h
Normal file → Executable file
2
picli.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Command-Line Parser
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
picodec.cpp
Normal file → Executable file
2
picodec.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Text codings coder, based on "iconv"
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
6
picodec.h
Normal file → Executable file
6
picodec.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Text codings coder, based on "iconv"
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -25,8 +25,8 @@
|
||||
class PICodec: private PIProcess
|
||||
{
|
||||
public:
|
||||
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write); tf.open();}
|
||||
PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write);}
|
||||
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIIODevice::ReadWrite); tf.open();}
|
||||
PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIIODevice::ReadWrite);}
|
||||
~PICodec() {tf.remove();}
|
||||
|
||||
void setFromCoding(const PIString & from) {c_from = from;}
|
||||
|
||||
16
piconfig.cpp
Normal file → Executable file
16
piconfig.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Config parser
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -171,13 +171,13 @@ bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const
|
||||
}
|
||||
|
||||
|
||||
PIConfig::PIConfig(const PIString & path, PIFlags<Mode> mode): PIFile(path, mode) {
|
||||
PIConfig::PIConfig(const PIString & path, PIIODevice::DeviceMode mode): PIFile(path, mode) {
|
||||
delim = ".";
|
||||
root.delim = delim;
|
||||
empty.delim = delim;
|
||||
empty._parent = 0;
|
||||
if (!isOpened() && (mode[Write] || mode[New]))
|
||||
open(path, Read | Write | New);
|
||||
if (!isOpened())
|
||||
open(path, mode);
|
||||
parse();
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
||||
} else entry = te;
|
||||
}
|
||||
PIConfig::Branch ch = entry->_children;
|
||||
std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare);
|
||||
ch.sort(PIConfig::Entry::compare);
|
||||
te = (entry->isLeaf() ? 0 : ch.back());
|
||||
ce = new Entry();
|
||||
ce->delim = delim;
|
||||
@@ -249,7 +249,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS
|
||||
if (toRoot) ce->_line = other.size_s() - 1;
|
||||
else {
|
||||
ch = entry->_parent->_children;
|
||||
std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare);
|
||||
ch.sort(PIConfig::Entry::compare);
|
||||
ce->_line = ch.back()->_line + 1;
|
||||
}
|
||||
}
|
||||
@@ -369,8 +369,8 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
||||
if (b[i] == e) found = true;
|
||||
}
|
||||
if (!leaf) return;
|
||||
e->_parent->_children.remove(e);
|
||||
b.remove(e);
|
||||
e->_parent->_children.removeOne(e);
|
||||
b.removeOne(e);
|
||||
delete e;
|
||||
}
|
||||
|
||||
|
||||
11
piconfig.h
Normal file → Executable file
11
piconfig.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Config parser
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -54,8 +54,8 @@ class PIConfig: public PIFile
|
||||
friend class Entry;
|
||||
friend class Branch;
|
||||
public:
|
||||
PIConfig(const PIString & path, PIFlags<Mode> mode = Read | Write);
|
||||
~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i);}
|
||||
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||
~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i); close();}
|
||||
|
||||
class Entry;
|
||||
|
||||
@@ -151,7 +151,8 @@ public:
|
||||
operator PIStringList() {return _value.split("%|%");}
|
||||
|
||||
private:
|
||||
static bool compare(const PIConfig::Entry * f, const PIConfig::Entry * s) {return f->_line < s->_line;}
|
||||
typedef PIConfig::Entry * EntryPtr;
|
||||
static int compare(const EntryPtr * f, const EntryPtr * s) {return (*f)->_line == (*s)->_line ? 0 : (*f)->_line < (*s)->_line ? -1 : 1;}
|
||||
bool entryExists(const Entry * e, const PIString & name) const;
|
||||
void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
|
||||
void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
|
||||
@@ -196,7 +197,7 @@ public:
|
||||
bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
|
||||
|
||||
Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;}
|
||||
Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;}
|
||||
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;}
|
||||
|
||||
195
piconsole.cpp
Normal file → Executable file
195
piconsole.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Console output/input
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,6 +26,7 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
||||
ret_func = slot;
|
||||
num_format = 0;
|
||||
cur_tab = width = height = pwidth = pheight = my = 0;
|
||||
def_align = Nothing;
|
||||
#ifdef WINDOWS
|
||||
ulcoord.X = ulcoord.Y = 0;
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
@@ -142,7 +143,7 @@ void PIConsole::stop(bool clear) {
|
||||
if (clear) clearScreen();
|
||||
moveTo(0, my + 4);
|
||||
showCursor();
|
||||
couts(fstr(Normal).stdString());
|
||||
couts(fstr(Normal));
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hOut, smode);
|
||||
SetConsoleTextAttribute(hOut, dattr);
|
||||
@@ -243,7 +244,7 @@ PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
||||
#define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;}
|
||||
#define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;}
|
||||
|
||||
inline int PIConsole::couts(const string v) {return printf("%s", v.c_str());}
|
||||
inline int PIConsole::couts(const PIString & v) {return printf("%s", v.data());}
|
||||
inline int PIConsole::couts(const char * v) {return printf("%s", v);}
|
||||
inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));}
|
||||
inline int PIConsole::couts(const char v) {return printf("%c", v);}
|
||||
@@ -289,14 +290,15 @@ void PIConsole::run() {
|
||||
}
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
col_cnt = vars().size();
|
||||
col_cnt = columns().size();
|
||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||
for (uint i = 0; i < col_cnt; ++i) {
|
||||
PIVector<Variable> & cvars(tabs[cur_tab].columns[i].variables);
|
||||
cx = col_wid * i;
|
||||
toUpperLeft();
|
||||
if (my < vars()[i].size()) my = vars()[i].size();
|
||||
if (my < cvars.size()) my = cvars.size();
|
||||
j = 0;
|
||||
piForeachC (Variable & tv, vars()[i]) {
|
||||
piForeachC (Variable & tv, cvars) {
|
||||
if (j > height - 3) continue;
|
||||
j++;
|
||||
moveRight(cx);
|
||||
@@ -338,7 +340,7 @@ void PIConsole::run() {
|
||||
|
||||
|
||||
void PIConsole::fillLabels() {
|
||||
uint cx, cy, my = 0;
|
||||
uint cx, cy, my = 0, mx = 0, dx;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||
@@ -349,21 +351,31 @@ void PIConsole::fillLabels() {
|
||||
width = ws.ws_col;
|
||||
height = ws.ws_row;
|
||||
#endif
|
||||
col_cnt = vars().size();
|
||||
col_cnt = columns().size();
|
||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||
for (uint i = 0; i < col_cnt; ++i) {
|
||||
Column & ccol(tabs[cur_tab].columns[i]);
|
||||
PIVector<Variable> & cvars(ccol.variables);
|
||||
if (ccol.alignment != Nothing) {
|
||||
mx = 0;
|
||||
piForeachC (Variable & j, cvars)
|
||||
if (j.type != 0 && j.s != 0)
|
||||
if (mx < j.name.size())
|
||||
mx = j.name.size();
|
||||
mx += 2;
|
||||
}
|
||||
cx = col_wid * i;
|
||||
cy = 1;
|
||||
toUpperLeft();
|
||||
for (uint j = 0; j < vars()[i].size(); ++j) {
|
||||
for (uint j = 0; j < cvars.size(); ++j) {
|
||||
if (int(j) > height - 3) continue;
|
||||
if (my < j) my = j;
|
||||
moveRight(cx);
|
||||
tv = vars()[i][j];
|
||||
vars()[i][j].nx = cx;
|
||||
vars()[i][j].ny = cy;
|
||||
Variable & tv(cvars[j]);
|
||||
cvars[j].nx = cx;
|
||||
cvars[j].ny = cy;
|
||||
if (tv.name.size() == 0) {
|
||||
vars()[i][j].offset = 0;
|
||||
cvars[j].offset = 0;
|
||||
clearLine();
|
||||
newLine();
|
||||
cy++;
|
||||
@@ -371,16 +383,33 @@ void PIConsole::fillLabels() {
|
||||
}
|
||||
clearLine();
|
||||
if (tv.type == 0 && tv.s == 0) {
|
||||
vars()[i][j].offset = vars()[i][j].name.length();
|
||||
vars()[i][j].nx += vars()[i][j].offset;
|
||||
cvars[j].offset = cvars[j].name.length();
|
||||
cvars[j].nx += cvars[j].offset;
|
||||
printLine(tv.name, cx, tv.format);
|
||||
newLine();
|
||||
cy++;
|
||||
continue;
|
||||
}
|
||||
vars()[i][j].offset = (tv.name + ": ").length();
|
||||
vars()[i][j].nx += vars()[i][j].offset;
|
||||
switch (ccol.alignment) {
|
||||
case Nothing:
|
||||
cvars[j].offset = (tv.name + ": ").length();
|
||||
cvars[j].nx += cvars[j].offset;
|
||||
printValue(tv.name + ": ", tv.format);
|
||||
break;
|
||||
case Left:
|
||||
cvars[j].offset = mx;
|
||||
cvars[j].nx += cvars[j].offset;
|
||||
printValue(tv.name + ": ", tv.format);
|
||||
break;
|
||||
case Right:
|
||||
cvars[j].offset = mx;
|
||||
cvars[j].nx += cvars[j].offset;
|
||||
dx = mx - (tv.name + ": ").length();
|
||||
moveRight(dx);
|
||||
printValue(tv.name + ": ", tv.format);
|
||||
moveLeft(dx);
|
||||
break;
|
||||
}
|
||||
newLine();
|
||||
cy++;
|
||||
}
|
||||
@@ -428,70 +457,70 @@ int PIConsole::bitsValue(void * src, int offset, int count) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column);
|
||||
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(col);
|
||||
|
||||
void PIConsole::addString(const PIString & name, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIString* ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, bool * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, int * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, long * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, char * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, float * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, double * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, short * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uint * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ulong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ushort * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uchar * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, llong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ullong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
addString("protocol " + name, column, format | PIConsole::Bold);
|
||||
addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), column, format);
|
||||
addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), column, format);
|
||||
addVariable("Sended count", ptr->sendCount_ptr(), column, format);
|
||||
addVariable("Received count", ptr->receiveCount_ptr(), column, format);
|
||||
addVariable("Invalid count", ptr->wrongCount_ptr(), column, format);
|
||||
addVariable("Missed count", ptr->missedCount_ptr(), column, format);
|
||||
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), column, format);
|
||||
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), column, format);
|
||||
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), column, format);
|
||||
addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), column, format);
|
||||
addVariable("Sender history size", ptr->senderHistorySize_ptr(), column, format);
|
||||
addVariable("Quality", ptr->quality_ptr(), column, format);
|
||||
void PIConsole::addString(const PIString & name, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = 0; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIString* ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, bool * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 1; tv.b = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, int * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 2; tv.i = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, long * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 3; tv.l = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, char * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 4; tv.c = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, float * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 5; tv.f = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, double * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 6; tv.d = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, short * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uint * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ulong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ushort * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, uchar * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, llong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; column(col).push_back(tv);}
|
||||
void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
addString("protocol " + name, col, format | PIConsole::Bold);
|
||||
addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), col, format);
|
||||
addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), col, format);
|
||||
addVariable("Sended count", ptr->sendCount_ptr(), col, format);
|
||||
addVariable("Received count", ptr->receiveCount_ptr(), col, format);
|
||||
addVariable("Invalid count", ptr->wrongCount_ptr(), col, format);
|
||||
addVariable("Missed count", ptr->missedCount_ptr(), col, format);
|
||||
addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format);
|
||||
addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format);
|
||||
addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), col, format);
|
||||
addVariable("Receiver history size", ptr->receiverHistorySize_ptr(), col, format);
|
||||
addVariable("Sender history size", ptr->senderHistorySize_ptr(), col, format);
|
||||
addVariable("Quality", ptr->quality_ptr(), col, format);
|
||||
}
|
||||
void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
addString("monitor " + name, column, format | PIConsole::Bold);
|
||||
addVariable("state ", &(ptr->statistic().state), column, format);
|
||||
addVariable("threads ", &(ptr->statistic().threads), column, format);
|
||||
addVariable("priority", &(ptr->statistic().priority), column, format);
|
||||
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), column, format);
|
||||
addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), column, format);
|
||||
addVariable("cpu load", &(ptr->statistic().cpu_load_system), column, format);
|
||||
void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||
addString("monitor " + name, col, format | PIConsole::Bold);
|
||||
addVariable("state ", &(ptr->statistic().state), col, format);
|
||||
addVariable("threads ", &(ptr->statistic().threads), col, format);
|
||||
addVariable("priority", &(ptr->statistic().priority), col, format);
|
||||
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
|
||||
addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), col, format);
|
||||
addVariable("cpu load", &(ptr->statistic().cpu_load_system), col, format);
|
||||
}
|
||||
void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column, PIFlags<PIConsole::Format> format) {
|
||||
void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
|
||||
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
|
||||
checkColumn(column); vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addEmptyLine(int column, uint count) {
|
||||
checkColumn(col); column(col).push_back(tv);}
|
||||
void PIConsole::addEmptyLine(int col, uint count) {
|
||||
tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal;
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
checkColumn(column);
|
||||
vars()[column - 1].push_back(tv);
|
||||
checkColumn(col);
|
||||
column(col).push_back(tv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,15 +550,15 @@ PIString PIConsole::getString(int x, int y) {
|
||||
|
||||
|
||||
PIString PIConsole::getString(const PIString & name) {
|
||||
piForeachC (PIVector<Variable> & i, tabs[cur_tab].variables)
|
||||
piForeachC (Variable & j, i)
|
||||
piForeachC (Column & i, tabs[cur_tab].columns)
|
||||
piForeachC (Variable & j, i.variables)
|
||||
if (j.name == name)
|
||||
return getString(j.nx + 1, j.ny);
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
#define PRINT_VAR_BODY couts(fstr(format).stdString()); int ret = couts(value); couts(fstr(PIConsole::Dec).stdString()); return ret;
|
||||
#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); couts(fstr(PIConsole::Dec)); return ret;
|
||||
|
||||
inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConsole::Format> format) {
|
||||
int i = width - value.length() - dx;
|
||||
@@ -537,15 +566,15 @@ inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConso
|
||||
--i;
|
||||
#endif
|
||||
PIString ts = fstr(format);
|
||||
couts(ts.stdString());
|
||||
couts(ts);
|
||||
if (i >= 0) ts = value + PIString(i, ' ');
|
||||
else ts = value.left(value.size() + i);
|
||||
couts(ts.stdString());
|
||||
couts(fstr(Dec).stdString());
|
||||
couts(ts);
|
||||
couts(fstr(Dec));
|
||||
}
|
||||
inline int PIConsole::printValue(const PIString & value, PIFlags<PIConsole::Format> format) {
|
||||
couts(fstr(format).stdString());
|
||||
int ret = couts(value.stdString());
|
||||
couts(fstr(format));
|
||||
int ret = couts(value);
|
||||
fstr(PIConsole::Dec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
34
piconsole.h
Normal file → Executable file
34
piconsole.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Console output/input
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
Hex = 0x2000000,
|
||||
Oct = 0x4000000,
|
||||
Scientific = 0x8000000};
|
||||
enum Alignment {Nothing, Left, Right};
|
||||
|
||||
void addString(const PIString & name, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
@@ -106,9 +107,13 @@ public:
|
||||
|
||||
void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;}
|
||||
void clearCustomStatus() {tabs[cur_tab].status.clear();}
|
||||
Alignment defaultAlignment() const {return def_align;}
|
||||
void setDefaultAlignment(Alignment align) {def_align = align;}
|
||||
void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;}
|
||||
void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();}
|
||||
|
||||
EVENT_HANDLER0(PIConsole, void, clearVariables) {clearVariables(true);}
|
||||
EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();}
|
||||
EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} columns().clear();}
|
||||
|
||||
EVENT_HANDLER0(PIConsole, void, waitForFinish) {WAIT_FOR_EXIT}
|
||||
EVENT_HANDLER0(PIConsole, void, start) {start(false);}
|
||||
@@ -156,7 +161,7 @@ private:
|
||||
void showCursor() {printf("\e[?25h");}
|
||||
#endif
|
||||
void status();
|
||||
void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}}
|
||||
void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));}
|
||||
int bitsValue(void * src, int offset, int count);
|
||||
inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
@@ -203,21 +208,33 @@ private:
|
||||
void * ptr;
|
||||
};
|
||||
void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset;
|
||||
bitFrom = src.bitFrom; bitCount = src.bitCount; c = src.c; nx = src.nx; ny = src.ny;}
|
||||
bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny;}
|
||||
};
|
||||
|
||||
struct Column {
|
||||
PIVector<Variable> variables;
|
||||
Alignment alignment;
|
||||
Column(Alignment align = PIConsole::Right) { alignment = align;}
|
||||
uint size() const {return variables.size();}
|
||||
Variable & operator [](int index) {return variables[index];}
|
||||
const Variable & operator [](int index) const {return variables[index];}
|
||||
void push_back(const Variable & v) {variables.push_back(v);}
|
||||
void operator =(const Column & src) {variables = src.variables; alignment = src.alignment;}
|
||||
};
|
||||
|
||||
struct Tab {
|
||||
PIVector<PIVector<Variable> > variables;
|
||||
PIVector<Column> columns;
|
||||
PIString name;
|
||||
PIString status;
|
||||
char key;
|
||||
Tab() {;}
|
||||
Tab() {}
|
||||
Tab(PIString n, char k) {name = n; key = k;}
|
||||
~Tab() {;}
|
||||
};
|
||||
|
||||
PIVector<PIVector<Variable> > & vars() {return tabs[cur_tab].variables;}
|
||||
inline int couts(const string v);
|
||||
PIVector<Column> & columns() {return tabs[cur_tab].columns;}
|
||||
Column & column(int index) {return tabs[cur_tab].columns[index - 1];}
|
||||
inline int couts(const PIString & v);
|
||||
inline int couts(const char * v);
|
||||
inline int couts(const bool v);
|
||||
inline int couts(const char v);
|
||||
@@ -246,6 +263,7 @@ private:
|
||||
PIVector<Tab> tabs;
|
||||
Variable tv;
|
||||
PIKbdListener * listener;
|
||||
Alignment def_align;
|
||||
KBFunc ret_func;
|
||||
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
||||
uint my;
|
||||
|
||||
247
picontainers.h
Normal file → Executable file
247
picontainers.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Generic containers, based on STL
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -124,7 +124,7 @@ template <typename T> inline _PIForeachC<T> * _PIForeachCastC(_PIForeachBase & c
|
||||
|
||||
#define piForeachRC piForeachCR
|
||||
|
||||
#define piForTimes(c) for(int i = 0; i < c; ++i)
|
||||
#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
|
||||
|
||||
template<typename Enum>
|
||||
class PIFlags {
|
||||
@@ -133,27 +133,243 @@ public:
|
||||
PIFlags(Enum e): flags(e) {;}
|
||||
PIFlags(const PIFlags & f): flags(f.flags) {;}
|
||||
PIFlags(const int i): flags(i) {;}
|
||||
PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;}
|
||||
PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;}
|
||||
PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;}
|
||||
void operator =(const PIFlags & f) {flags = f.flags;}
|
||||
void operator =(const Enum & e) {flags = e;}
|
||||
void operator =(const int & i) {flags = i;}
|
||||
void operator |=(const PIFlags & f) {flags = flags | f.flags;}
|
||||
void operator |=(const Enum & e) {flags = flags | e;}
|
||||
void operator |=(const int i) {flags = flags | i;}
|
||||
void operator &=(const PIFlags & f) {flags = flags & f.flags;}
|
||||
void operator &=(const Enum & e) {flags = flags & e;}
|
||||
void operator &=(const int i) {flags = flags & i;}
|
||||
void operator |=(const PIFlags & f) {flags |= f.flags;}
|
||||
void operator |=(const Enum & e) {flags |= e;}
|
||||
void operator |=(const int i) {flags |= i;}
|
||||
void operator &=(const PIFlags & f) {flags &= f.flags;}
|
||||
void operator &=(const Enum & e) {flags &= e;}
|
||||
void operator &=(const int i) {flags &= i;}
|
||||
void operator ^=(const PIFlags & f) {flags ^= f.flags;}
|
||||
void operator ^=(const Enum & e) {flags ^= e;}
|
||||
void operator ^=(const int i) {flags ^= i;}
|
||||
PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
||||
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
||||
PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
||||
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
||||
PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
||||
PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
||||
PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;}
|
||||
PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;}
|
||||
PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;}
|
||||
bool operator [](Enum e) {return (flags & e) == e;}
|
||||
operator int() const {return flags;}
|
||||
private:
|
||||
int flags;
|
||||
};
|
||||
/*
|
||||
template <typename T>
|
||||
class PIVector {
|
||||
public:
|
||||
PIVector(uint size = 0, const T & f = T()): data_(0), size_(0), rsize_(0) {resize(size, f);}
|
||||
PIVector(T * d, uint size): data_(0), size_(0), rsize_(0) {alloc(size); for (uint i = 0; i < size; ++i) data_[i] = d[i];}
|
||||
~PIVector() {dealloc();}
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
class iterator {
|
||||
friend class PIVector<T>;
|
||||
private:
|
||||
iterator(PIVector<T> * v, int p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
int pos;
|
||||
public:
|
||||
iterator(): parent(0) {}
|
||||
T & operator *() {return (*parent)[pos];}
|
||||
const T & operator *() const {return (*parent)[pos];}
|
||||
void operator ++() {++pos;}
|
||||
void operator ++(int) {++pos;}
|
||||
void operator --() {--pos;}
|
||||
void operator --(int) {--pos;}
|
||||
bool operator ==(const iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const iterator & it) const {return (pos != it.pos);}
|
||||
};
|
||||
|
||||
class const_iterator {
|
||||
friend class PIVector<T>;
|
||||
private:
|
||||
const_iterator(const PIVector<T> * v, int p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
int pos;
|
||||
public:
|
||||
const_iterator(): parent(0) {}
|
||||
//T & operator *() {return (*parent)[pos];}
|
||||
const T & operator *() const {return (*parent)[pos];}
|
||||
void operator ++() {++pos;}
|
||||
void operator ++(int) {++pos;}
|
||||
void operator --() {--pos;}
|
||||
void operator --(int) {--pos;}
|
||||
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
||||
};
|
||||
|
||||
class reverse_iterator {
|
||||
friend class PIVector<T>;
|
||||
private:
|
||||
reverse_iterator(PIVector<T> * v, int p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
int pos;
|
||||
public:
|
||||
reverse_iterator(): parent(0) {}
|
||||
T & operator *() {return (*parent)[pos];}
|
||||
const T & operator *() const {return (*parent)[pos];}
|
||||
void operator ++() {--pos;}
|
||||
void operator ++(int) {--pos;}
|
||||
void operator --() {++pos;}
|
||||
void operator --(int) {++pos;}
|
||||
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
|
||||
};
|
||||
|
||||
class const_reverse_iterator {
|
||||
friend class PIVector<T>;
|
||||
private:
|
||||
const_reverse_iterator(const PIVector<T> * v, int p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
int pos;
|
||||
public:
|
||||
const_reverse_iterator(): parent(0) {}
|
||||
//T & operator *() {return (*parent)[pos];}
|
||||
const T & operator *() const {return (*parent)[pos];}
|
||||
void operator ++() {--pos;}
|
||||
void operator ++(int) {--pos;}
|
||||
void operator --() {++pos;}
|
||||
void operator --(int) {++pos;}
|
||||
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
||||
};
|
||||
|
||||
iterator begin() {return iterator(this, 0);}
|
||||
iterator end() {return iterator(this, size_);}
|
||||
const_iterator begin() const {return const_iterator(this, 0);}
|
||||
const_iterator end() const {return const_iterator(this, size_);}
|
||||
reverse_iterator rbegin() {return reverse_iterator(this, size_ - 1);}
|
||||
reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size_ - 1);}
|
||||
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||
|
||||
uint size() const {return size_;}
|
||||
int size_s() const {return size_;}
|
||||
int length() const {return size_;}
|
||||
bool isEmpty() const {return (size_ == 0);}
|
||||
|
||||
T & operator [](int index) {return data_[index];}
|
||||
T & at(uint index) {return data_[index];}
|
||||
const T & operator [](int index) const {return data_[index];}
|
||||
const T & at(uint index) const {return data_[index];}
|
||||
T & back() {return data_[size_ - 1];}
|
||||
const T & back() const {return data_[size_ - 1];}
|
||||
T & front() {return data_[0];}
|
||||
const T & front() const {return data_[0];}
|
||||
|
||||
bool operator ==(const PIVector<T> & t) const {if (size_ != t.size_) return false; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return false; return true;}
|
||||
bool operator !=(const PIVector<T> & t) const {if (size_ != t.size_) return true; for (uint i = 0; i < size_; ++i) if (t[i] != data_[i]) return true; return false;}
|
||||
bool contain(const T & v) const {for (uint i = 0; i < size_; ++i) if (v == data_[i]) return true; return false;}
|
||||
|
||||
T * data(int index = 0) {return &(data_[index]);}
|
||||
const T * data(int index = 0) const {return &(data_[index]);}
|
||||
PIVector<T> & clear() {resize(0); return *this;}
|
||||
PIVector<T> & fill(const T & f = T()) {
|
||||
if (sizeof(T) == 1) memset(data_, f, size_);
|
||||
else for (uint i = 0; i < size_; ++i) memcpy(&(data_[i]), &f, sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
||||
PIVector<T> & resize(uint new_size, const T & f = T()) {
|
||||
if (new_size < size_) {
|
||||
size_ = new_size;
|
||||
return *this;
|
||||
}
|
||||
if (new_size > size_) {
|
||||
os = size_;
|
||||
alloc(new_size);
|
||||
uint ds = size_ - os;
|
||||
//if (sizeof(T) == 1) memset(&(data_[os]), f, ds);
|
||||
for (uint i = 0; i < ds; ++i) data_[os + i] = f;
|
||||
return *this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
PIVector<T> & insert(int index, const T & v = T()) {
|
||||
push_back(v);
|
||||
if (index >= int(size_ - 1)) return *this;
|
||||
os = size_ - index;
|
||||
T * pd = new T[os * sizeof(T)];
|
||||
memcpy(pd, &(data_[index]), os * sizeof(T));
|
||||
memcpy(&(data_[index + 1]), pd, os * sizeof(T));
|
||||
delete[] pd;
|
||||
data_[index] = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PIVector<T> & remove(int index, int count = 1) {
|
||||
if (index + count >= int(size_)) {
|
||||
resize(index);
|
||||
return *this;
|
||||
}
|
||||
os = size_ - index - count;
|
||||
T * pd = new T[os * sizeof(T)];
|
||||
memcpy(pd, &(data_[index + count]), os * sizeof(T));
|
||||
memcpy(&(data_[index]), pd, os * sizeof(T));
|
||||
delete[] pd;
|
||||
resize(size_ - count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef int (*CompareFunc)(const T * , const T * );
|
||||
static int compare_func(const T * t0, const T * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
|
||||
PIVector<T> & sort(CompareFunc compare = compare_func) {qsort(data_, size_, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
|
||||
|
||||
PIVector<T> & removeOne(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); return *this;} return *this;}
|
||||
PIVector<T> & removeAll(const T & v) {for (uint i = 0; i < size_; ++i) if (data_[i] == v) {remove(i); --i;} return *this;}
|
||||
|
||||
PIVector<T> & push_back(const T & v) {alloc(size_ + 1); data_[size_ - 1] = v; return *this;}
|
||||
PIVector<T> & append(const T & v) {return push_back(v);}
|
||||
PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
||||
|
||||
PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
|
||||
PIVector<T> & prepend(const T & v) {return push_front(v);}
|
||||
//PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
||||
|
||||
PIVector<T> & pop_back() {if (size_ == 0) return *this; resize(size_ - 1); return *this;}
|
||||
PIVector<T> & pop_front() {if (size_ == 0) return *this; remove(0); return *this;}
|
||||
|
||||
private:
|
||||
uint asize(uint s) {if (s == 0) return 0; if (rsize_ + rsize_ >= s && rsize_ < s) return rsize_ + rsize_; uint t = 0, s_ = s - 1; while (s_ >> t) ++t; return (1 << t);}
|
||||
void dealloc() {if (data_ != 0) delete[] data_; data_ = 0;}
|
||||
void alloc(uint new_size) {
|
||||
if (new_size <= rsize_) {
|
||||
size_ = new_size;
|
||||
return;
|
||||
}
|
||||
os = size_;
|
||||
size_ = new_size;
|
||||
uint as = asize(new_size);
|
||||
if (as == rsize_) return;
|
||||
T * pd = 0;
|
||||
if (os > 0) {
|
||||
pd = new T[os * sizeof(T)];
|
||||
memcpy(pd, data_, os * sizeof(T));
|
||||
}
|
||||
rsize_ = as;
|
||||
dealloc();
|
||||
data_ = new T[rsize_ * sizeof(T)];
|
||||
if (os > 0) {
|
||||
memcpy(data_, pd, size_ * sizeof(T));
|
||||
delete[] pd;
|
||||
}
|
||||
}
|
||||
|
||||
T * data_;
|
||||
uint size_, rsize_, os;
|
||||
};
|
||||
*/
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIVector: public vector<Type, Allocator> {
|
||||
typedef PIVector<Type, Allocator> _CVector;
|
||||
@@ -172,15 +388,20 @@ public:
|
||||
Type * data(uint index = 0) {return &(*this)[index];}
|
||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
bool isEmpty() const {return _stlc::empty();}
|
||||
typedef int (*CompareFunc)(const Type * , const Type * );
|
||||
static int compare_func(const Type * t0, const Type * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
|
||||
_CVector & sort(CompareFunc compare = compare_func) {qsort(&at(0), _stlc::size(), sizeof(Type), (int(*)(const void * , const void * ))compare); return *this;}
|
||||
_CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||
_CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||
_CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||
_CVector & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
_CVector & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
_CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
//_CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
_CVector & removeOne(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
|
||||
_CVector & removeAll(const Type & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
_CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||
_CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||
_CVector & operator <<(const _CVector & t) {for (typename _stlc::iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
||||
_CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
|
||||
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
|
||||
bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
|
||||
bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||
@@ -212,7 +433,7 @@ public:
|
||||
_CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
_CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||
_CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
|
||||
@@ -232,7 +453,7 @@ public:
|
||||
_CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
_CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
||||
bool operator [](const Type & t) {return _stlc::find(t);}
|
||||
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
@@ -265,7 +486,7 @@ public:
|
||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
bool isEmpty() const {return _stlc::empty();}
|
||||
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
||||
PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
|
||||
4
pidir.cpp
Normal file → Executable file
4
pidir.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Directory
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -35,7 +35,7 @@ PIDir::PIDir() {
|
||||
|
||||
|
||||
PIDir::PIDir(const PIString & dir) {
|
||||
path_ = dir.stdString();
|
||||
path_ = dir;
|
||||
dir_ = 0;
|
||||
open();
|
||||
}
|
||||
|
||||
2
pidir.h
Normal file → Executable file
2
pidir.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Directory
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
301
piethernet.cpp
Normal file → Executable file
301
piethernet.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,182 +20,217 @@
|
||||
#include "piethernet.h"
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot): PIThread() {
|
||||
PIEthernet::PIEthernet(void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
data = data_;
|
||||
ip_ = ip_s = ip;
|
||||
port_ = port_s = port;
|
||||
sock = sock_s = -1;
|
||||
ret_func = slot;
|
||||
tries = 0;
|
||||
//buffer_ = new char[BUFFER_SIZE];
|
||||
type_ = UDP;
|
||||
ret_data_ = data;
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = -1;
|
||||
ret_func_ = slot;
|
||||
connected_ = false;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(PIEthernet::Type type, void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
type_ = type;
|
||||
ret_data_ = data;
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = -1;
|
||||
ret_func_ = slot;
|
||||
connected_ = false;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
type_ = TCP_Client;
|
||||
parseAddress(ip_port, &ip_s, &port_s);
|
||||
sock = sock_;
|
||||
server_thread_.setData(this);
|
||||
init_ = opened_ = connected_ = true;
|
||||
setThreadedReadBufferSize(65536);
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
initSend();
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::~PIEthernet() {
|
||||
piMonitor.ethernets--;
|
||||
terminate();
|
||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||
closeSocket(sock);
|
||||
#ifdef WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
if (sock != -1) {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
sock = -1;
|
||||
}
|
||||
if (sock_s != -1) {
|
||||
shutdown(sock_s, SHUT_RDWR);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock_s);
|
||||
#else
|
||||
close(sock_s);
|
||||
#endif
|
||||
sock_s = -1;
|
||||
}
|
||||
//if (buffer_ != 0) delete buffer_;
|
||||
//buffer_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::terminate() {
|
||||
if (!receiverInitialized()) return;
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
PIThread::terminate();
|
||||
}
|
||||
tries = 0;
|
||||
/*if (sock != -1) {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
close(sock);
|
||||
sock = -1;
|
||||
}
|
||||
if (sock_s != -1) {
|
||||
shutdown(sock_s, SHUT_RDWR);
|
||||
close(sock_s);
|
||||
sock_s = -1;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::begin() {
|
||||
if (!init()) stop();
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::run() {
|
||||
/*#ifdef WINDOWS
|
||||
int addr_len = sizeof(sockaddr);
|
||||
#else
|
||||
socklen_t addr_len = sizeof(sockaddr_storage);
|
||||
#endif*/
|
||||
//cout << "[PIEthernet] reading from " << &addr_ << endl;
|
||||
readed = recv(sock, buffer_, BUFFER_SIZE, 0/*, (sockaddr * )&addr_, &addr_len*/);
|
||||
//cout << WSAGetLastError() << endl;
|
||||
if (readed < 0) {
|
||||
cout << "[PIEthernet] Error while reading, " << errorString() << endl;
|
||||
//stop();
|
||||
//init();
|
||||
return;
|
||||
}
|
||||
if (ret_func != 0) ret_func(data, buffer_, readed);
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::end() {
|
||||
terminate();
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::init() {
|
||||
//cout << "init " << type_ << endl;
|
||||
closeSocket(sock);
|
||||
int st = 0, so = 1;
|
||||
if (type_ == UDP) st = SOCK_DGRAM;
|
||||
if (type_ == TCP_Client || type_ == TCP_Server) st = SOCK_STREAM;
|
||||
sock = socket(PF_INET, st, 0);
|
||||
if (sock == -1) {
|
||||
piCout << "[PIEthernet] Cant`t create socket, " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
||||
//fcntl(sock, F_SETFL, 0/*O_NONBLOCK*/);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
|
||||
if (ip != 0) *ip = ipp.left(ipp.find(":"));
|
||||
if (port != 0) *port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::openDevice() {
|
||||
if (connected_) return true;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
//cout << " bind to " << path_ << " ..." <<endl;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
addr_.sin_port = htons(port_);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
//cout << "openDevice\n";
|
||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
||||
tries++;
|
||||
if (tries < 10) {
|
||||
if (init()) {
|
||||
tries = 0;
|
||||
return true;
|
||||
} else return false;
|
||||
} else
|
||||
cout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
//cout << "!" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::initSend() {
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock_s);
|
||||
#else
|
||||
close(sock_s);
|
||||
#endif
|
||||
sock_s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sock_s == -1) {
|
||||
tries++;
|
||||
if (tries < 10) {
|
||||
if (init()) {
|
||||
tries = 0;
|
||||
return true;
|
||||
} else return false;
|
||||
} else
|
||||
cout << "[PIEthernet] Unable to create socket, " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
bool PIEthernet::closeDevice() {
|
||||
//cout << "close\n";
|
||||
if (sock != -1) shutdown(sock, SHUT_RDWR);
|
||||
closeSocket(sock);
|
||||
piForeach (PIEthernet * i, clients_)
|
||||
delete i;
|
||||
clients_.clear();
|
||||
if (server_thread_.isRunning()) server_thread_.terminate();
|
||||
connected_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::send(PIString ip, int port, char * data, int size) {
|
||||
if (sock_s == -1) {
|
||||
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
|
||||
bool PIEthernet::connect(PIString ip, int port) {
|
||||
if (sock == -1) return false;
|
||||
addr_.sin_port = htons(port);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
//piCout << "[PIEthernet] connect to " << ip << ":" << port << endl;
|
||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||
if (!connected_)
|
||||
piCout << "[PIEthernet] Cant`t connect to " << ip << ":" << port << ", " << errorString() << endl;
|
||||
opened_ = connected_;
|
||||
return connected_;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::listen() {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
||||
piCout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
saddr_.sin_port = htons(port);
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip.data());
|
||||
saddr_.sin_family = PF_INET;
|
||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
if (wrote != size) {
|
||||
//cout << "[PIEthernet] Error while sending" << endl;
|
||||
if (::listen(sock, 64) == -1) {
|
||||
piCout << "[PIEthernet] Can`t listen on "<< ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
//cout << "[PIEthernet] Wrote " << wrote << " bytes in " << devName << endl;
|
||||
//piCout << "[PIEthernet] listen on " << ip_ << ":" << port_ << endl;
|
||||
server_thread_.start(server_func);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::send(uchar * data, int size) {
|
||||
if (sock_s == -1) {
|
||||
//cout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
|
||||
return false;
|
||||
int PIEthernet::read(void * read_to, int max_size) {
|
||||
//cout << "read " << sock << endl;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return -1;
|
||||
//piCout << "[PIEthernet] read from " << ip_ << ":" << port_ << endl;
|
||||
switch (type_) {
|
||||
case UDP: case TCP_Client:
|
||||
return recv(sock, read_to, max_size, 0);
|
||||
//return ::read(sock, read_to, max_size);
|
||||
default: break;
|
||||
//return ::read(sock, (char * )read_to, max_size);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int PIEthernet::write(const void * data, int max_size) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || !isWriteable()) {
|
||||
//piCout << "[PIEthernet] Can`t send to uninitialized socket" << endl;
|
||||
return -1;
|
||||
}
|
||||
//piCout << "[PIEthernet] sending to " << ip_s << ":" << port_s << " " << max_size << " bytes" << endl;
|
||||
switch (type_) {
|
||||
case UDP:
|
||||
saddr_.sin_port = htons(port_s);
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
saddr_.sin_family = PF_INET;
|
||||
//cout << "[PIEthernet] sending in " << sock_s << endl;
|
||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
if (wrote != size) {
|
||||
//cout << "[PIEthernet] Error while sending" << endl;
|
||||
return false;
|
||||
return sendto(sock, data, max_size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
case TCP_Client:
|
||||
return ::write(sock, data, max_size);
|
||||
default: break;
|
||||
//return ::read(sock, read_to, max_size);
|
||||
}
|
||||
//cout << "[PIEthernet] Wrote " << wrote << " bytes" << endl;
|
||||
return true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PIEthernet::server_func(void * eth) {
|
||||
PIEthernet * ce = (PIEthernet * )eth;
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
int s;
|
||||
s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
if (s == -1) {
|
||||
piCout << "[PIEthernet] Cant`t accept new connection, " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
PIString ip(inet_ntoa(client_addr.sin_addr));
|
||||
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
|
||||
ce->clients_ << new PIEthernet(s, ip);
|
||||
cout << "connected " << ip << endl;
|
||||
//char d[256];
|
||||
//cout << " recv " << recv(s, d, 256, 0) << endl;
|
||||
//cout << recv(ce->clients_.back()->sock, d, 256, 0) << endl;
|
||||
|
||||
}
|
||||
|
||||
83
piethernet.h
Normal file → Executable file
83
piethernet.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,12 +20,13 @@
|
||||
#ifndef PIETHERNET_H
|
||||
#define PIETHERNET_H
|
||||
|
||||
#include "pithread.h"
|
||||
#include "pistring.h"
|
||||
#include "pitimer.h"
|
||||
#include "piiodevice.h"
|
||||
#ifndef WINDOWS
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# ifdef CC_VC
|
||||
# include <winsock.h>
|
||||
@@ -36,42 +37,66 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
typedef bool (*EthernetFunc)(void * , uchar * , int );
|
||||
|
||||
class PIEthernet: public PIThread
|
||||
class PIEthernet: public PIIODevice
|
||||
{
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||
PIEthernet(PIString ip = "", int port = 0, void * data = 0, EthernetFunc slot = 0);
|
||||
PIEthernet(void * data, ReadRetFunc slot);
|
||||
|
||||
enum Type {UDP, TCP_Client, TCP_Server};
|
||||
|
||||
PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0);
|
||||
~PIEthernet();
|
||||
|
||||
void setSlot(EthernetFunc func) {ret_func = func;}
|
||||
void setData(void * d) {data = d;}
|
||||
void setReadAddress(PIString ip, int port) {ip_ = ip; port_ = port;}
|
||||
void setReadAddress(PIString ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
|
||||
void setReadAddress(PIString ip_port) {path_ = ip_port;}
|
||||
void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = port;}
|
||||
void setSendAddress(PIString ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
|
||||
|
||||
Type type() const {return type_;}
|
||||
|
||||
bool connect(PIString ip, int port);
|
||||
bool connect(PIString ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
|
||||
bool isConnected() const {return connected_;}
|
||||
|
||||
bool listen();
|
||||
bool listen(PIString ip, int port) {setReadAddress(ip, port); return listen();}
|
||||
bool listen(PIString ip_port) {setReadAddress(ip_port); return listen();}
|
||||
|
||||
PIEthernet * client(int index) {return clients_[index];}
|
||||
int clientsCount() const {return clients_.size_s();}
|
||||
PIVector<PIEthernet * > clients() {return clients_;}
|
||||
|
||||
bool send(PIString ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);}
|
||||
bool send(PIString ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
|
||||
bool send(const void * data, int size) {return (write(data, size) == size);}
|
||||
|
||||
int read(void * read_to, int max_size);
|
||||
int write(const void * data, int max_size);
|
||||
|
||||
protected:
|
||||
PIEthernet(int sock, PIString ip_port);
|
||||
|
||||
bool send(PIString ip, int port, char * data, int size);
|
||||
bool send(uchar * data, int size);
|
||||
bool init();
|
||||
bool initSend();
|
||||
bool receiverInitialized() const {return sock != -1;}
|
||||
bool senderInitialized() const {return sock_s != -1;}
|
||||
void terminate();
|
||||
const uchar * buffer() const {return buffer_;}
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
#ifdef WINDOWS
|
||||
void closeSocket(int & sd) {if (sd != -1) closesocket(sd); sd = -1;}
|
||||
#else
|
||||
void closeSocket(int & sd) {if (sd != -1) ::close(sd); sd = -1;}
|
||||
#endif
|
||||
void parseAddress(const PIString & ipp, PIString * ip, int * port);
|
||||
|
||||
int sock, port_, port_s, port_c, wrote;
|
||||
bool connected_;
|
||||
sockaddr_in addr_, saddr_;
|
||||
PIString ip_, ip_s, ip_c;
|
||||
PIThread server_thread_;
|
||||
PIVector<PIEthernet * > clients_;
|
||||
Type type_;
|
||||
|
||||
private:
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
|
||||
int sock, sock_s, port_, port_s, wrote, readed, tries;
|
||||
sockaddr_in addr_, saddr_;
|
||||
PIString ip_, ip_s;
|
||||
EthernetFunc ret_func;
|
||||
void * data;
|
||||
uchar buffer_[BUFFER_SIZE];
|
||||
static void server_func(void * eth);
|
||||
|
||||
};
|
||||
|
||||
|
||||
2
pievaluator.cpp
Normal file → Executable file
2
pievaluator.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pievaluator.h
Normal file → Executable file
2
pievaluator.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
88
pifile.cpp
Normal file → Executable file
88
pifile.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
File
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,35 +20,46 @@
|
||||
#include "pifile.h"
|
||||
|
||||
|
||||
bool PIFile::open(const PIString & path_, PIFlags<Mode> mode_) {
|
||||
cpath = path_;
|
||||
cmode = mode_;
|
||||
string st = cpath.stdString();
|
||||
if (cmode[New]) {
|
||||
stream.open(st.c_str(), fstream::in | fstream::out | fstream::trunc | fstream::binary);
|
||||
stream.close();
|
||||
cmode &= ~New;
|
||||
stream.open(st.c_str(), (fstream::openmode)(int)cmode | fstream::binary);
|
||||
} else stream.open(st.c_str(), (fstream::openmode)(int)cmode | fstream::binary);
|
||||
return isOpened();
|
||||
bool PIFile::openDevice() {
|
||||
if (opened_) close();
|
||||
if (path_.isEmpty()) return false;
|
||||
//cout << "fopen " << path_.data() << ": " << strType(mode_).data() << endl;
|
||||
fd = fopen(path_.data(), strType(mode_).data());
|
||||
opened_ = (fd != 0);
|
||||
seekToBegin();
|
||||
return opened_;
|
||||
}
|
||||
|
||||
|
||||
bool PIFile::closeDevice() {
|
||||
if (!opened_) return true;
|
||||
return (fclose(fd) != 0);
|
||||
}
|
||||
|
||||
|
||||
PIString PIFile::readLine() {
|
||||
char * buff = new char[4096];
|
||||
stream.getline(buff, 4096);
|
||||
return PIString(buff);
|
||||
PIString str;
|
||||
if (!opened_) return str;
|
||||
char cc;
|
||||
int cp = 0;
|
||||
while (!isEnd() && cp < 4095) {
|
||||
cc = char(fgetc(fd));
|
||||
if (cc == '\n') break;
|
||||
str.push_back(cc);
|
||||
}
|
||||
//cout << "readline: " << buff << endl;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
llong PIFile::readAll(void * data) {
|
||||
llong cp = pos(), s = size(), i = -1;
|
||||
stream.seekg(0);
|
||||
seekToBegin();
|
||||
if (s < 0) {
|
||||
while (!stream.eof())
|
||||
stream.read(&(((char*)data)[++i]), 1);
|
||||
while (!isEnd())
|
||||
read(&(((char*)data)[++i]), 1);
|
||||
} else
|
||||
stream.read((char * )data, s);
|
||||
read((char * )data, s);
|
||||
seek(cp);
|
||||
return s;
|
||||
}
|
||||
@@ -56,14 +67,11 @@ llong PIFile::readAll(void * data) {
|
||||
|
||||
PIByteArray PIFile::readAll(bool forceRead) {
|
||||
llong cp = pos(), s = size();
|
||||
char c;
|
||||
PIByteArray a;
|
||||
if (s < 0) {
|
||||
if (!forceRead) return a;
|
||||
while (!stream.eof()) {
|
||||
stream.read(&c, 1);
|
||||
a.push_back(c);
|
||||
}
|
||||
while (!isEnd())
|
||||
a.push_back(readChar());
|
||||
seek(cp);
|
||||
return a;
|
||||
}
|
||||
@@ -75,12 +83,11 @@ PIByteArray PIFile::readAll(bool forceRead) {
|
||||
|
||||
|
||||
llong PIFile::size() {
|
||||
if (!stream.is_open()) return -1;
|
||||
llong s, cp = stream.tellg();
|
||||
stream.seekg(0, fstream::end);
|
||||
s = stream.tellg();
|
||||
stream.seekg(cp, fstream::beg);
|
||||
stream.clear();
|
||||
if (!opened_) return -1;
|
||||
llong s, cp = pos();
|
||||
seekToEnd();
|
||||
s = pos();
|
||||
seek(cp);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -91,23 +98,18 @@ void PIFile::resize(llong new_size, char fill_) {
|
||||
if (ds > 0) {
|
||||
char * buff = new char[ds];
|
||||
memset(buff, fill_, ds);
|
||||
stream.write(buff, ds);
|
||||
delete buff;
|
||||
write(buff, ds);
|
||||
delete[] buff;
|
||||
return;
|
||||
}
|
||||
cout << "[PIFile] Downsize is not support yet :-(" << endl;
|
||||
piCout << "[PIFile] Downsize is not support yet :-(" << endl;
|
||||
}
|
||||
|
||||
|
||||
llong PIFile::pos() {
|
||||
if (cmode[Write]) return stream.tellp();
|
||||
if (cmode[Read]) return stream.tellg();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PIFile PIFile::openTemporary(PIFlags<PIFile::Mode> mode) {
|
||||
char * rc;
|
||||
rc = tmpnam(0);
|
||||
return PIFile(PIString(rc), mode);
|
||||
bool PIFile::isExists(const PIString & path) {
|
||||
FILE * f = fopen(PIString(path).data(), "r");
|
||||
bool ok = (f != 0);
|
||||
if (ok) fclose(f);
|
||||
return ok;
|
||||
}
|
||||
|
||||
139
pifile.h
Normal file → Executable file
139
pifile.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
File
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,100 +20,89 @@
|
||||
#ifndef PIFILE_H
|
||||
#define PIFILE_H
|
||||
|
||||
#include "piobject.h"
|
||||
#include <fstream>
|
||||
#include "piiodevice.h"
|
||||
#include <cstdio>
|
||||
|
||||
using std::fstream;
|
||||
|
||||
class PIFile: public PIObject
|
||||
class PIFile: public PIIODevice
|
||||
{
|
||||
public:
|
||||
PIFile(): PIObject() {;}
|
||||
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {openDevice();}
|
||||
|
||||
enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app, ReadWrite = Read | Write};
|
||||
//PIFile & operator =(const PIFile & f) {path_ = f.path_; type_ = f.type_; return *this;}
|
||||
|
||||
PIFile(const PIString & path, PIFlags<Mode> mode = ReadWrite): PIObject(path) {open(path, mode);}
|
||||
PIFile(const PIFile & file): PIObject(file.cpath) {cpath = file.cpath; cmode = file.cmode;}
|
||||
~PIFile() {close();}
|
||||
|
||||
PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;}
|
||||
|
||||
EVENT_HANDLER2(PIFile, bool, open, const PIString & , path, PIFlags<Mode>, mode);
|
||||
EVENT_HANDLER1(PIFile, bool, open, PIFlags<Mode>, mode) {return open(cpath, mode);}
|
||||
EVENT_HANDLER1(PIFile, bool, open, const PIString & , path) {return open(path, cmode);}
|
||||
EVENT_HANDLER0(PIFile, bool, open) {return open(cpath, cmode);}
|
||||
EVENT_HANDLER0(PIFile, void, close) {stream.clear(); stream.close();}
|
||||
EVENT_HANDLER0(PIFile, void, clear) {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);}
|
||||
void seek(llong position) {stream.clear(); stream.seekg(position); stream.seekp(position);}
|
||||
void seekToBegin() {stream.clear(); stream.seekg(0, fstream::beg); stream.seekp(0, fstream::beg);}
|
||||
void seekToEnd() {stream.clear(); stream.seekg(0, fstream::end); stream.seekp(0, fstream::end);}
|
||||
void seekToLine(llong line) {stream.clear(); seekToBegin(); piForTimes (line) readLine();} // line 0 - begin of file
|
||||
void flush() {fflush(fd);}
|
||||
EVENT_HANDLER(PIFile, void, clear) {close(); fd = fopen(path_.data(), "w"); close(); open();}
|
||||
void seek(llong position) {if (!opened_) return; fseek(fd, position, SEEK_SET); clearerr(fd);}
|
||||
void seekToBegin() {if (!opened_) return; fseek(fd, 0, SEEK_SET); clearerr(fd);}
|
||||
void seekToEnd() {if (!opened_) return; fseek(fd, 0, SEEK_END); clearerr(fd);}
|
||||
void seekToLine(llong line) {if (!opened_) return; seekToBegin(); piForTimes (line) readLine(); clearerr(fd);} // line 0 - begin of file
|
||||
EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);}
|
||||
EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill);
|
||||
void fill(char c) {stream.fill(c);}
|
||||
EVENT_HANDLER0(PIFile, void, flush) {stream.flush();}
|
||||
//void fill(char c) {stream.fill(c);}
|
||||
char readChar() {return (char)fgetc(fd);}
|
||||
PIString readLine();
|
||||
llong readAll(void * data);
|
||||
PIByteArray readAll(bool forceRead = false);
|
||||
EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(cpath.data());}
|
||||
EVENT_HANDLER0(PIFile, void, remove) {close(); std::remove(path_.data());}
|
||||
|
||||
PIString path() const {return cpath;}
|
||||
void setPath(const PIString & path) {cpath = path;}
|
||||
PIFlags<Mode> mode() const {return cmode;}
|
||||
void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();}
|
||||
llong size();
|
||||
llong pos();
|
||||
bool isOpened() {return stream.is_open();}
|
||||
bool isEnd() {return stream.eof();}
|
||||
llong pos() {if (!opened_) return -1; return ftell(fd);}
|
||||
bool isEnd() {return (feof(fd) || ferror(fd));}
|
||||
bool isEmpty() {return (size() <= 0);}
|
||||
|
||||
PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;}
|
||||
PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;}
|
||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {writeBinary(id).writeBinary((ushort)size).writeData(data, size); flush(); return *this;}
|
||||
int read(void * read_to, int max_size) {if (!canRead()) return -1; return fread(read_to, max_size, 1, fd);}
|
||||
int write(const void * data, int max_size) {if (!canWrite()) return -1; return fwrite(data, max_size, 1, fd);}
|
||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable()) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
||||
|
||||
PIFile & writeBinary(const char v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const short v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const int v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const long v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uchar v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ushort v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uint v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ulong v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const float v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const double v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const char v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const short v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const int v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const long v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uchar v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ushort v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const uint v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const ulong v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const float v) {write(&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
|
||||
|
||||
PIFile & operator <<(const char & v) {stream.write(&v, 1); return *this;}
|
||||
//PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;}
|
||||
PIFile & operator <<(const PIString & v) {string s = v.stdString(); stream.write(s.c_str(), s.size()); return *this;}
|
||||
PIFile & operator <<(const PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;}
|
||||
PIFile & operator <<(const short & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const int & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const long & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const uchar & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const ushort & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const uint & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const ulong & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const float & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const double & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const char & v) {if (!isWriteable()) return *this; write(&v, 1); return *this;}
|
||||
//PIFile & operator <<(const string & v) {write(v.c_str(), v.size()); return *this;}
|
||||
PIFile & operator <<(const PIString & v) {if (!isWriteable()) return *this; write(v.data(), v.lengthAscii()); return *this;}
|
||||
PIFile & operator <<(const PIByteArray & v) {if (!isWriteable()) return *this; write(v.data(), v.size()); return *this;}
|
||||
PIFile & operator <<(short v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(int v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(long v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(uchar v) {if (!isWriteable()) return *this; fprintf(fd, "%c", v); return *this;}
|
||||
PIFile & operator <<(ushort v) {if (!isWriteable()) return *this; fprintf(fd, "%hd", v); return *this;}
|
||||
PIFile & operator <<(uint v) {if (!isWriteable()) return *this; fprintf(fd, "%d", v); return *this;}
|
||||
PIFile & operator <<(ulong v) {if (!isWriteable()) return *this; fprintf(fd, "%ld", v); return *this;}
|
||||
PIFile & operator <<(float v) {if (!isWriteable()) return *this; fprintf(fd, "%f", v); return *this;}
|
||||
PIFile & operator <<(double v) {if (!isWriteable()) return *this; fprintf(fd, "%lf", v); return *this;}
|
||||
|
||||
PIFile & operator >>(char & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(short & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(int & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(long & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(uchar & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(ushort & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(uint & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(ulong & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(float & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(double & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(char & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(short & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(int & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(long & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(uchar & v) {if (!isWriteable()) return *this; fscanf(fd, "%hhn", &v); return *this;}
|
||||
PIFile & operator >>(ushort & v) {if (!isWriteable()) return *this; fscanf(fd, "%hn", &v); return *this;}
|
||||
PIFile & operator >>(uint & v) {if (!isWriteable()) return *this; fscanf(fd, "%n", &v); return *this;}
|
||||
PIFile & operator >>(ulong & v) {if (!isWriteable()) return *this; fscanf(fd, "%ln", &v); return *this;}
|
||||
PIFile & operator >>(float & v) {if (!isWriteable()) return *this; fscanf(fd, "%f", &v); return *this;}
|
||||
PIFile & operator >>(double & v) {if (!isWriteable()) return *this; fscanf(fd, "%lf", &v); return *this;}
|
||||
|
||||
static PIFile openTemporary(PIFlags<PIFile::Mode> mode = PIFile::ReadWrite);
|
||||
static bool isExists(const PIString & path) {return std::ifstream(path.stdString().c_str()).good();}
|
||||
static bool remove(const PIString & path) {return std::remove(path.stdString().c_str()) == 0;}
|
||||
static PIFile openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite) {return PIFile(PIString(tmpnam(0)), mode);}
|
||||
static bool isExists(const PIString & path);
|
||||
static bool remove(const PIString & path) {return std::remove(path.data()) == 0;}
|
||||
|
||||
protected:
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
|
||||
private:
|
||||
fstream stream;
|
||||
PIString cpath;
|
||||
PIFlags<Mode> cmode;
|
||||
PIString strType(const PIIODevice::DeviceMode type) {switch (type) {case PIIODevice::ReadOnly: return "rb"; case WriteOnly: return "ab"; case ReadWrite: return "a+b";} return "rb";}
|
||||
|
||||
FILE * fd;
|
||||
|
||||
};
|
||||
|
||||
|
||||
2
pigeometry.h
Normal file → Executable file
2
pigeometry.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Geometry
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
23
piincludes.cpp
Normal file
23
piincludes.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Global includes
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes.h"
|
||||
|
||||
bool isPIInit = false;
|
||||
bool piDebug = true;
|
||||
11
piincludes.h
Normal file → Executable file
11
piincludes.h
Normal file → Executable file
@@ -20,10 +20,11 @@
|
||||
#ifndef PIINCLUDES_H
|
||||
#define PIINCLUDES_H
|
||||
|
||||
#define PIP_VERSION 0x000102
|
||||
#define PIP_VERSION 0x000200
|
||||
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
||||
#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8
|
||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||
#define PIP_VERSION_SUFFIX ""
|
||||
|
||||
#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__
|
||||
# define WINDOWS
|
||||
@@ -119,13 +120,17 @@ static locale_t currentLocale_t = 0;
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
|
||||
static bool isPIInit = false;
|
||||
extern bool isPIInit;
|
||||
extern bool piDebug;
|
||||
|
||||
#define piCout if (piDebug) cout
|
||||
|
||||
class PIInit {
|
||||
public:
|
||||
PIInit() {
|
||||
if (isPIInit) return;
|
||||
isPIInit = true;
|
||||
//piDebug = true;
|
||||
#ifdef LINUX
|
||||
if (currentLocale_t != 0) {
|
||||
freelocale(currentLocale_t);
|
||||
@@ -215,6 +220,6 @@ inline string dtos(const double num) {
|
||||
#endif
|
||||
return string(ch); };
|
||||
|
||||
inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION);}
|
||||
inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION) + PIP_VERSION_SUFFIX;}
|
||||
|
||||
#endif // PIINCLUDES_H
|
||||
|
||||
107
piiodevice.cpp
Executable file
107
piiodevice.cpp
Executable file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piiodevice.h"
|
||||
|
||||
|
||||
PIIODevice::PIIODevice(): PIThread() {
|
||||
mode_ = ReadOnly;
|
||||
opened_ = init_ = thread_started_ = false;
|
||||
reopen_enabled_ = true;
|
||||
reopen_timeout_ = 1000;
|
||||
ret_func_ = 0;
|
||||
ret_data_ = 0;
|
||||
buffer_tr.resize(4096);
|
||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() {
|
||||
path_ = path;
|
||||
mode_ = type;
|
||||
opened_ = init_ = thread_started_ = false;
|
||||
reopen_enabled_ = true;
|
||||
reopen_timeout_ = 1000;
|
||||
ret_func_ = 0;
|
||||
ret_data_ = 0;
|
||||
buffer_tr.resize(4096);
|
||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||
if (initNow) init();
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::check_start(void * data, int delim) {
|
||||
//cout << "check " << tread_started_ << endl;
|
||||
if (open()) {
|
||||
thread_started_ = true;
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::terminate() {
|
||||
thread_started_ = false;
|
||||
if (!isInitialized()) return;
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
PIThread::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::begin() {
|
||||
//cout << " begin\n";
|
||||
thread_started_ = false;
|
||||
if (!opened_) {
|
||||
if (open()) {
|
||||
thread_started_ = true;
|
||||
//cout << " open && ok\n";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
thread_started_ = true;
|
||||
//cout << " ok\n";
|
||||
return;
|
||||
}
|
||||
//init();
|
||||
if (!timer.isRunning() && reopen_enabled_) timer.start(reopen_timeout_);
|
||||
}
|
||||
|
||||
|
||||
void PIIODevice::run() {
|
||||
if (!isReadable()) {
|
||||
//cout << "not readable\n";
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
if (!thread_started_) {
|
||||
msleep(1);
|
||||
//cout << "not started\n";
|
||||
return;
|
||||
}
|
||||
|
||||
readed_ = read(buffer_tr.data(), buffer_tr.size_s());
|
||||
if (readed_ <= 0) {
|
||||
msleep(10);
|
||||
//cout << readed_ << ", " << errno << ", " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
threadedRead(buffer_tr.data(), readed_);
|
||||
}
|
||||
121
piiodevice.h
Executable file
121
piiodevice.h
Executable file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Abstract input/output device
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIIODEVICE_H
|
||||
#define PIIODEVICE_H
|
||||
|
||||
#include "pitimer.h"
|
||||
|
||||
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||
typedef bool (*ReadRetFunc)(void * , uchar * , int );
|
||||
|
||||
class PIIODevice: public PIThread {
|
||||
public:
|
||||
PIIODevice();
|
||||
|
||||
enum DeviceMode {ReadOnly = 0x01, WriteOnly = 0x02, ReadWrite = 0x03};
|
||||
|
||||
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true);
|
||||
~PIIODevice() {if (opened_) closeDevice();}
|
||||
|
||||
|
||||
DeviceMode mode() const {return mode_;}
|
||||
PIString path() const {return path_;}
|
||||
bool isReadable() const {return (mode_ & ReadOnly);}
|
||||
bool isWriteable() const {return (mode_ & WriteOnly);}
|
||||
bool isInitialized() const {return init_;}
|
||||
bool isOpened() const {return opened_;}
|
||||
bool isClosed() const {return !opened_;}
|
||||
bool canRead() const {return opened_ && (mode_ & ReadOnly);}
|
||||
bool canWrite() const {return opened_ && (mode_ & WriteOnly);}
|
||||
|
||||
|
||||
// Enable timer to periodically open device until it will be opened
|
||||
void setReopenEnabled(bool yes = true) {reopen_enabled_ = yes;}
|
||||
void setReopenTimeout(int msecs = 1000) {reopen_timeout_ = msecs;}
|
||||
|
||||
bool isReopenEnabled() const {return reopen_enabled_;}
|
||||
int reopenTimeout() {return reopen_timeout_;}
|
||||
|
||||
|
||||
// set return function executed when successful read in thread
|
||||
void setThreadedReadSlot(ReadRetFunc func) {ret_func_ = func;}
|
||||
void setThreadedReadData(void * d) {ret_data_ = d;}
|
||||
void setThreadedReadBufferSize(int new_size) {buffer_tr.resize(new_size);}
|
||||
|
||||
int threadedReadBufferSize() const {return buffer_tr.size_s();}
|
||||
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
||||
|
||||
void startThreadedRead() {if (!isRunning()) start();}
|
||||
void startThreadedRead(ReadRetFunc func) {ret_func_ = func; if (!isRunning()) start();}
|
||||
|
||||
|
||||
EVENT_HANDLER(PIIODevice, bool, open) {if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER1(PIIODevice, bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER2(PIIODevice, bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); return opened_;}
|
||||
EVENT_HANDLER(PIIODevice, bool, close) {opened_ = !closeDevice(); return !opened_;}
|
||||
|
||||
// Flush device
|
||||
EVENT_VHANDLER(PIIODevice, void, flush) {;}
|
||||
|
||||
|
||||
// Read from device to "read_to" maximum "max_size" bytes, return readed bytes count
|
||||
virtual int read(void * read_to, int max_size) {piCout << "[PIIODevice] \"read\" not implemented!" << endl; return -2;}
|
||||
|
||||
// Write to device "data" maximum "max_size" bytes, return written bytes count
|
||||
virtual int write(const void * data, int max_size) {piCout << "[PIIODevice] \"write\" not implemented!" << endl; return -2;}
|
||||
|
||||
// Read from device maximum "max_size" bytes and return them as PIByteArray
|
||||
PIByteArray read(int max_size) {buffer_in.resize(max_size); int ret = read(buffer_in.data(), max_size); if (ret < 0) return PIByteArray(); return buffer_in.resized(ret);}
|
||||
|
||||
|
||||
protected:
|
||||
// Function executed before first openDevice() or from constructor
|
||||
virtual bool init() {return true;}
|
||||
|
||||
// Functions to open and close device, return value will set to "opened_" variable
|
||||
virtual bool openDevice() = 0; // use path_, type_, opened_, init_ variables
|
||||
virtual bool closeDevice() {return true;} // use path_, type_, opened_, init_ variables
|
||||
|
||||
// Function executed when thread read some data, default implementation execute external slot "ret_func_"
|
||||
virtual bool threadedRead(uchar * readed, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, readed, size); return true;}
|
||||
|
||||
PIString path_;
|
||||
DeviceMode mode_;
|
||||
ReadRetFunc ret_func_;
|
||||
bool init_, opened_, thread_started_, reopen_enabled_;
|
||||
int reopen_timeout_;
|
||||
void * ret_data_;
|
||||
|
||||
private:
|
||||
EVENT_HANDLER2(PIIODevice, void, check_start, void * , data, int, delim);
|
||||
void terminate();
|
||||
|
||||
void begin();
|
||||
void run();
|
||||
void end() {terminate();}
|
||||
|
||||
PITimer timer;
|
||||
PIByteArray buffer_in, buffer_tr;
|
||||
int readed_;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIIODEVICE_H
|
||||
7
pikbdlistener.cpp
Normal file → Executable file
7
pikbdlistener.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -60,7 +60,10 @@ void PIKbdListener::run() {
|
||||
#else
|
||||
ret = read(0, &rc, 1);
|
||||
#endif
|
||||
if (exit_enabled && rc == exit_key) PIKbdListener::exiting = true;
|
||||
if (exit_enabled && rc == exit_key) {
|
||||
PIKbdListener::exiting = true;
|
||||
return;
|
||||
}
|
||||
if (ret_func != 0 && ret > 0) ret_func(rc, data);
|
||||
}
|
||||
|
||||
|
||||
2
pikbdlistener.h
Normal file → Executable file
2
pikbdlistener.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimath.cpp
Normal file → Executable file
2
pimath.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Math
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimath.h
Normal file → Executable file
2
pimath.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Math
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimonitor.cpp
Normal file → Executable file
2
pimonitor.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Counter of some PIP types
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimonitor.h
Normal file → Executable file
2
pimonitor.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Counter of some PIP types
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimultiprotocol.cpp
Normal file → Executable file
2
pimultiprotocol.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Multiprotocol
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
10
pimultiprotocol.h
Normal file → Executable file
10
pimultiprotocol.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Multiprotocol
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -62,14 +62,14 @@ private:
|
||||
class PIRepeater: public PIMultiProtocol {
|
||||
public:
|
||||
PIRepeater(const PIString & config, const PIString & name) {
|
||||
PIConfig conf(config, PIFile::Read);
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
if (!conf.isOpened()) {
|
||||
cout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
piCout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
return;
|
||||
}
|
||||
PIConfig::Entry & b(conf.getValue(name));
|
||||
if (b.childCount() != 2) {
|
||||
cout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl;
|
||||
piCout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl;
|
||||
return;
|
||||
}
|
||||
addProtocol(config, b.child(0)->fullName());
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;}
|
||||
|
||||
private:
|
||||
void received(PIProtocol * prot, bool , char * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);}
|
||||
void received(PIProtocol * prot, bool , uchar * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);}
|
||||
|
||||
};
|
||||
|
||||
|
||||
2
pimutex.h
Normal file → Executable file
2
pimutex.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Mutex
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
piobject.cpp
Normal file → Executable file
2
piobject.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
11
piobject.h
Normal file → Executable file
11
piobject.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -39,6 +39,13 @@
|
||||
#define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||
#define EVENT_HANDLER EVENT_HANDLER0
|
||||
|
||||
#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name()
|
||||
#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} virtual ret name(a0 n0)
|
||||
#define EVENT_VHANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1)
|
||||
#define EVENT_VHANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2)
|
||||
#define EVENT_VHANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
|
||||
#define EVENT_VHANDLER EVENT_VHANDLER0
|
||||
|
||||
#define CONNECT0(ret, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_##handler##__));
|
||||
#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_##handler##__));
|
||||
@@ -51,7 +58,7 @@ class PIObject
|
||||
friend class PIObjectManager;
|
||||
public:
|
||||
PIObject(const PIString & name = PIString()) {piMonitor.objects++; setName(name); objects << this;}
|
||||
~PIObject() {piMonitor.objects--; objects.remove(this);}
|
||||
~PIObject() {piMonitor.objects--; objects.removeAll(this);}
|
||||
|
||||
const PIString & name() const {return name_;}
|
||||
void setName(const PIString & name) {name_ = name;}
|
||||
|
||||
2
pip.h
Normal file → Executable file
2
pip.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
All includes
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
75
pipacketextractor.cpp
Normal file
75
pipacketextractor.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Packets extractor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pipacketextractor.h"
|
||||
|
||||
|
||||
PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) {
|
||||
ret_func_header = 0;
|
||||
setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
setBufferSize(4096);
|
||||
setDevice(device_);
|
||||
allReaded = addSize = curInd = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIPacketExtractor::setDevice(PIIODevice * device_) {
|
||||
dev = device_;
|
||||
if (dev == 0) return;
|
||||
}
|
||||
|
||||
|
||||
bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
|
||||
//cout << "extractor readed " << size_ << endl;
|
||||
memcpy(buffer.data(allReaded), readed, size_);
|
||||
allReaded += size_;
|
||||
if (allReaded < packetSize + addSize) return true;
|
||||
if (headerSize > 0) {
|
||||
if (allReaded + curInd >= buffer_size) {
|
||||
memcpy(sbuffer.data(), buffer.data(), buffer_size);
|
||||
memcpy(buffer.data(), sbuffer.data(buffer_size - packetSize), allReaded);
|
||||
allReaded = packetSize;
|
||||
addSize = curInd = 0;
|
||||
}
|
||||
while (!packetHeaderValidate((uchar * )headerPtr, buffer.data(curInd), headerSize)) {
|
||||
curInd++; missed++;
|
||||
if (packetSize > 0) missed_packets = missed / packetSize;
|
||||
if (curInd > addSize) {
|
||||
addSize += packetSize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
memcpy(mheader.data(), buffer.data(curInd + headerSize), headerSize);
|
||||
if (!packetValidate(buffer.data(curInd + headerSize), dataSize)) {
|
||||
curInd++; missed++;
|
||||
if (packetSize > 0) missed_packets = missed / packetSize;
|
||||
return true;
|
||||
}
|
||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||
memcpy(buffer.data(), sbuffer.data(packetSize + curInd), allReaded);
|
||||
allReaded -= packetSize + curInd;
|
||||
curInd = addSize = 0;
|
||||
} else {
|
||||
packetValidate(buffer.data(), dataSize);
|
||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||
memcpy(buffer.data(), sbuffer.data(packetSize), allReaded);
|
||||
allReaded -= packetSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
71
pipacketextractor.h
Normal file
71
pipacketextractor.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Packets extractor
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PIPACKETEXTRACTOR_H
|
||||
#define PIPACKETEXTRACTOR_H
|
||||
|
||||
#include "piiodevice.h"
|
||||
|
||||
// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false.
|
||||
typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
|
||||
|
||||
class PIPacketExtractor: public PIIODevice
|
||||
{
|
||||
public:
|
||||
PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0);
|
||||
|
||||
PIIODevice * device() {return dev;}
|
||||
void setDevice(PIIODevice * device_);
|
||||
|
||||
int bufferSize() const {return buffer_size;}
|
||||
void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size);}
|
||||
|
||||
void setHeaderCheckSlot(HeaderCheckFunc f) {ret_func_header = f;}
|
||||
void setPacketData(void * recHeaderPtr, int recHeaderSize, int recDataSize) {headerPtr = recHeaderPtr; headerSize = recHeaderSize; dataSize = recDataSize; packetSize = headerSize + dataSize; if (headerSize > 0) mheader.resize(headerSize);}
|
||||
|
||||
ullong missedBytes() const {return missed;}
|
||||
ullong missedPackets() const {return missed / packetSize;}
|
||||
const ullong * missedBytes_ptr() const {return &missed;}
|
||||
const ullong * missedPackets_ptr() const {return &missed_packets;}
|
||||
|
||||
PIByteArray lastHeader() {return mheader;}
|
||||
|
||||
int read(void * read_to, int max_size) {if (dev == 0) return -1; return dev->read(read_to, max_size);}
|
||||
int write(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
|
||||
|
||||
protected:
|
||||
virtual bool packetValidate(uchar * rec, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, rec, size); return true;}
|
||||
virtual bool packetHeaderValidate(uchar * src, uchar * rec, int size) {if (ret_func_header != 0) return ret_func_header(ret_data_, src, rec, size); for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
||||
|
||||
private:
|
||||
bool threadedRead(uchar * readed, int size);
|
||||
bool openDevice() {if (dev == 0) return false; return dev->isOpened();}
|
||||
|
||||
PIIODevice * dev;
|
||||
PIByteArray mheader, buffer, sbuffer;
|
||||
HeaderCheckFunc ret_func_header;
|
||||
void * headerPtr, * data;
|
||||
int buffer_size, dataSize, headerSize, packetSize, allReaded, addSize, curInd;
|
||||
ullong missed, missed_packets;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // PIPACKETEXTRACTOR_H
|
||||
22
piprocess.cpp
Normal file → Executable file
22
piprocess.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -59,7 +59,7 @@ void PIProcess::run() {
|
||||
#ifdef WINDOWS
|
||||
//args.pop_front();
|
||||
piForeachC (PIString & i, args)
|
||||
as += i.stdString().length() + 1;
|
||||
as += i.lengthAscii() + 1;
|
||||
char * a = new char[as];
|
||||
memset(a, ' ', as - 1);
|
||||
as = 0;
|
||||
@@ -93,20 +93,20 @@ void PIProcess::run() {
|
||||
/// files for stdin/out/err
|
||||
t_in = t_out = t_err = false;
|
||||
if (f_in.path().isEmpty()) {
|
||||
f_in = PIFile::openTemporary(PIFile::New | PIFile::Read);
|
||||
f_in = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_in = true;
|
||||
}
|
||||
f_in.open(PIFile::New | PIFile::Read); f_in.close();
|
||||
f_in.open(PIIODevice::ReadWrite); f_in.close();
|
||||
if (f_out.path().isEmpty()) {
|
||||
f_out = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||
f_out = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_out = true;
|
||||
}
|
||||
f_out.open(PIFile::New | PIFile::Write); f_out.close();
|
||||
f_out.open(PIIODevice::WriteOnly); f_out.close();
|
||||
if (f_err.path().isEmpty()) {
|
||||
f_err = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||
f_err = PIFile::openTemporary(PIIODevice::ReadWrite);
|
||||
t_err = true;
|
||||
}
|
||||
f_err.open(PIFile::New | PIFile::Write); f_err.close();
|
||||
f_err.open(PIIODevice::WriteOnly); f_err.close();
|
||||
|
||||
str = args.front().stdString();
|
||||
is_exec = true;
|
||||
@@ -114,7 +114,7 @@ void PIProcess::run() {
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
#endif
|
||||
FILE * tf;
|
||||
FILE * tf = 0;
|
||||
//cout << "exec" << endl;
|
||||
//cout << f_out.path() << endl;
|
||||
if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
|
||||
@@ -140,10 +140,10 @@ void PIProcess::run() {
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
} else
|
||||
cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
||||
piCout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl;
|
||||
#else
|
||||
if (execve(str.c_str(), a, e) < 0)
|
||||
cout << "[PIProcess] \"execve\" error, " << errorString() << endl;
|
||||
piCout << "[PIProcess] \"execve\" error, " << errorString() << endl;
|
||||
} else {
|
||||
msleep(1);
|
||||
//cout << "wait" << endl;
|
||||
|
||||
6
piprocess.h
Normal file → Executable file
6
piprocess.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;}
|
||||
#endif
|
||||
bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);}
|
||||
PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();}
|
||||
PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();}
|
||||
PIByteArray readOutput() {f_out.open(PIIODevice::ReadOnly); return f_out.readAll();}
|
||||
PIByteArray readError() {f_err.open(PIIODevice::ReadOnly); return f_err.readAll();}
|
||||
|
||||
PIStringList environment() {return env;}
|
||||
void clearEnvironment() {env.clear();}
|
||||
|
||||
225
piprotocol.cpp
Normal file → Executable file
225
piprotocol.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,14 +24,15 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
init();
|
||||
protName = name;
|
||||
PIObject::setName(name);
|
||||
PIConfig conf(config, PIFile::Read);
|
||||
PIConfig conf(config, PIIODevice::ReadOnly);
|
||||
if (!conf.isOpened()) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
devReceiverState = devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
int ps, gps;
|
||||
bool ok, gok, flag, gflag, has_dev = false;
|
||||
float freq, gfreq;
|
||||
PIFlags<PISerial::Parameters> pp;
|
||||
PIConfig::Entry & b(conf.getValue(name)),
|
||||
& rb(b.getValue("receiver")),
|
||||
@@ -40,7 +41,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
|
||||
/// receiver section
|
||||
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -49,7 +50,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -58,20 +59,44 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive port in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
eth = new PIEthernet();
|
||||
packet_ext.setDevice(eth);
|
||||
//setSenderAddress(dev, ps);
|
||||
setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
flag = rb.getValue("reconnectEnabled", true, &ok);
|
||||
gflag = b.getValue("reconnectEnabled", true, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenEnabled(flag);
|
||||
}
|
||||
freq = rb.getValue("reconnectTimeout", 1., &ok);
|
||||
gfreq = b.getValue("reconnectTimeout", 1., &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
if (recDataPtr == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
if (recDataSize == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
} else {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -81,7 +106,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -90,7 +115,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"speed\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -99,7 +124,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"parity\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -110,7 +135,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -118,19 +143,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
}
|
||||
type_rec = PIProtocol::Serial;
|
||||
type_send = PIProtocol::Serial;
|
||||
ser = new PISerial(dev, this, receiveEvent, headerValidateEvent);
|
||||
ser = new PISerial(dev);
|
||||
packet_ext.setDevice(ser);
|
||||
//setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
setReceiverDevice(dev, (PISerial::Speed)ps);
|
||||
setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
ser->setInSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
ps = rb.getValue("vtime", 1, &ok);
|
||||
gps = b.getValue("vtime", 1, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receive \"vtime\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
ser->setVTime(ps);
|
||||
}
|
||||
has_dev = true;
|
||||
if (recDataPtr == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
if (recDataSize == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
} else {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -140,7 +176,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) history_write_rec = ghist;
|
||||
if (gok && ok && (history_write_rec != ghist)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous receiver history in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -151,29 +187,30 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
history_id_rec = rb.getValue("historyID", 0, &ok);
|
||||
if (!ok) {
|
||||
history_id_rec = protName.toByteArray().checksumCRC16();
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver history ID defined, write with ID = " << history_id_rec << endl;
|
||||
}
|
||||
history_file_rec.open(history_path_rec, PIFile::Write | PIFile::New);
|
||||
history_file_rec.open(history_path_rec, PIIODevice::WriteOnly);
|
||||
}
|
||||
}
|
||||
float freq = rb.getValue("frequency", -1.f, &ok), gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
freq = rb.getValue("frequency", -1.f, &ok);
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous expected frequency in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (freq > 0.f && !has_dev)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl;
|
||||
float tm = b.getValue("disconnectTimeout", 3.f);
|
||||
if (tm <= 0.f)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl;
|
||||
timeout_ = (tm < 0.f) ? 0.f : tm;
|
||||
setExpectedFrequency(freq);
|
||||
|
||||
/// sender section
|
||||
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -183,7 +220,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -192,20 +229,43 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send port in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
setSenderAddress(dev, ps);
|
||||
//setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
flag = sb.getValue("reconnectEnabled", true, &ok);
|
||||
gflag = b.getValue("reconnectEnabled", true, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectEnabled\" flag in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenEnabled(flag);
|
||||
}
|
||||
freq = sb.getValue("reconnectTimeout", 1., &ok);
|
||||
gfreq = b.getValue("reconnectTimeout", 1., &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous \"reconnectTimeout\" value in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
eth->setReopenTimeout(freq * 1000);
|
||||
}
|
||||
if (sendDataPtr_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
if (sendDataSize_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
} else {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" or \"" << name << ".port\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -215,7 +275,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) dev = gdev;
|
||||
if (gok && ok && (dev != gdev)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -224,7 +284,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) ps = gps;
|
||||
if (gok && ok && (ps != gps)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"speed\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -233,7 +293,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"parity\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -244,35 +304,34 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) flag = gflag;
|
||||
if (gok && ok && (flag != gflag)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous send \"twoStopBits\" parity in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
pp |= PISerial::TwoStopBits;
|
||||
}
|
||||
} else {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_send = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial(dev, this, receiveEvent, headerValidateEvent);
|
||||
if (ser == 0) ser = new PISerial(dev);
|
||||
setSenderDevice(dev, (PISerial::Speed)ps);
|
||||
ser->setOutSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
has_dev = true;
|
||||
if (sendDataPtr_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
if (sendDataSize_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
}
|
||||
history_write_send = sb.getValue("writeHistory", false, &ok);
|
||||
ghist = b.getValue("writeHistory", false, &gok);
|
||||
if (ok || gok) {
|
||||
if (gok && !ok) history_write_send = ghist;
|
||||
if (gok && ok && (history_write_send != ghist)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender history in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
@@ -283,21 +342,21 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
history_id_send = sb.getValue("historyID", 0, &ok);
|
||||
if (!ok) {
|
||||
history_id_send = protName.toByteArray().checksumCRC16() + 1;
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender history ID defined, write with ID = " << history_id_send << endl;
|
||||
}
|
||||
history_file_send.open(history_path_send, PIFile::Write | PIFile::New);
|
||||
history_file_send.open(history_path_send, PIIODevice::WriteOnly);
|
||||
}
|
||||
}
|
||||
freq = sb.getValue("frequency", -1.f, &ok);
|
||||
gfreq = b.getValue("frequency", -1.f, &gok);
|
||||
if (gok && !ok) freq = gfreq;
|
||||
if (gok && ok && (freq != gfreq)) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Ambiguous sender frequency in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (freq > 0.f && !has_dev)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl;
|
||||
piCout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl;
|
||||
setSenderFrequency(freq);
|
||||
|
||||
headerPtr = (uchar * )recHeaderPtr;
|
||||
@@ -306,6 +365,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
dataSize = recDataSize;
|
||||
sendDataPtr = (uchar * )sendDataPtr_;
|
||||
sendDataSize = sendDataSize_;
|
||||
packet_ext.setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (recHeaderPtr != 0) {
|
||||
dataPtr = (uchar * )recHeaderPtr;
|
||||
@@ -341,6 +401,9 @@ PIProtocol::~PIProtocol() {
|
||||
|
||||
|
||||
void PIProtocol::init() {
|
||||
packet_ext.setThreadedReadData(this);
|
||||
packet_ext.setThreadedReadSlot(receiveEvent);
|
||||
packet_ext.setHeaderCheckSlot(headerValidateEvent);
|
||||
work = new_mp_prot = history_write_rec = history_write_send = false;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
@@ -379,7 +442,10 @@ void PIProtocol::init() {
|
||||
void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) {
|
||||
if (force) {
|
||||
type_send = type_rec = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent);
|
||||
if (ser == 0) {
|
||||
ser = new PISerial();
|
||||
packet_ext.setDevice(ser);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Serial && ser != 0) {
|
||||
ser->setDevice(device);
|
||||
@@ -393,7 +459,10 @@ void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed spee
|
||||
void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
|
||||
if (force) {
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent);
|
||||
if (eth == 0) {
|
||||
eth = new PIEthernet();
|
||||
packet_ext.setDevice(eth);
|
||||
}
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setReadAddress(ip, port);
|
||||
@@ -406,11 +475,12 @@ void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
|
||||
void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) {
|
||||
if (force) {
|
||||
type_send = type_rec = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent);
|
||||
if (ser == 0) ser = new PISerial();
|
||||
}
|
||||
if (type_send == PIProtocol::Serial && ser != 0) {
|
||||
ser->setDevice(device);
|
||||
ser->setSpeed(speed);
|
||||
ser->open();
|
||||
devSenderName = device;
|
||||
}
|
||||
}
|
||||
@@ -419,10 +489,11 @@ void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed,
|
||||
void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
|
||||
if (force) {
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent);
|
||||
if (eth == 0) eth = new PIEthernet();
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet && eth != 0) {
|
||||
eth->setSendAddress(ip, port);
|
||||
eth->open();
|
||||
if (ip.isEmpty()) devSenderName = "no ip";
|
||||
else devSenderName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
@@ -444,9 +515,10 @@ void PIProtocol::changeDisconnectTimeout() {
|
||||
|
||||
void PIProtocol::startReceive(float exp_frequency) {
|
||||
if (exp_frequency > 0.f) exp_freq = exp_frequency;
|
||||
if (type_rec == PIProtocol::Serial) ser->start();
|
||||
if (type_rec == PIProtocol::Ethernet) eth->start();
|
||||
//if (type_rec == PIProtocol::Serial) ser->start();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->start();
|
||||
if (exp_freq <= 0.f) return;
|
||||
packet_ext.startThreadedRead();
|
||||
setExpectedFrequency(exp_freq);
|
||||
diagTimer->start(1000. / exp_freq);
|
||||
diagTimer->reset();
|
||||
@@ -463,8 +535,9 @@ void PIProtocol::startSend(float frequency) {
|
||||
|
||||
|
||||
void PIProtocol::stopReceive() {
|
||||
if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
//if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
//if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
packet_ext.stop();
|
||||
diagTimer->stop();
|
||||
raiseEvent(this, "receiver stopped");
|
||||
}
|
||||
@@ -508,7 +581,7 @@ void PIProtocol::diagEvent(void * t, int) {
|
||||
p->calc_freq();
|
||||
p->calc_diag();
|
||||
p->check_state();
|
||||
if (p->ser != 0) p->missed_count = p->ser->missedPackets();
|
||||
if (p->ser != 0) p->missed_count = p->packet_ext.missedPackets();
|
||||
}
|
||||
|
||||
|
||||
@@ -558,47 +631,49 @@ void PIProtocol::calc_freq() {
|
||||
void PIProtocol::check_state() {
|
||||
if (type_rec == PIProtocol::Serial) {
|
||||
if (ser != 0) {
|
||||
if (ser->initialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
if (ser->isOpened()) devReceiverState = "Opened";
|
||||
else devReceiverState = "Not opened";
|
||||
}
|
||||
else devReceiverState = "Uninitialized";
|
||||
else devReceiverState = "Not exists";
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (eth != 0) {
|
||||
if (eth->receiverInitialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
if (eth->isOpened()) devReceiverState = "Opened";
|
||||
else devReceiverState = "Not opened";
|
||||
}
|
||||
else devReceiverState = "Uninitialized";
|
||||
else devReceiverState = "Not exists";
|
||||
}
|
||||
if (type_send == PIProtocol::Serial) {
|
||||
if (ser != 0) {
|
||||
if (ser->initialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
if (ser->isOpened()) devSenderState = "Opened";
|
||||
else devSenderState = "Not opened";
|
||||
}
|
||||
else devSenderState = "Uninitialized";
|
||||
else devSenderState = "Not exists";
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet) {
|
||||
if (eth != 0) {
|
||||
if (eth->senderInitialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
if (eth->isOpened()) devSenderState = "Opened";
|
||||
else devSenderState = "Not opened";
|
||||
}
|
||||
else devSenderState = "Uninitialized";
|
||||
else devSenderState = "Not exists";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::send(const void * data, int size) {
|
||||
void PIProtocol::send(const void * data, int size, bool direct) {
|
||||
if (!direct) {
|
||||
if (data == 0 || size == 0) return;
|
||||
if (!aboutSend()) return;
|
||||
}
|
||||
if (history_write_send) {
|
||||
history_file_send.writeToBinLog(history_id_send, data, size);
|
||||
history_rsize_send.setReadableSize(history_file_send.pos());
|
||||
}
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send((uchar * )data, size))
|
||||
if (ser->send(data, size))
|
||||
send_count++;
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send((uchar * )data, size))
|
||||
if (eth->send(data, size))
|
||||
send_count++;
|
||||
}
|
||||
|
||||
@@ -607,16 +682,16 @@ void PIProtocol::send() {
|
||||
//lock();
|
||||
//memcpy(packet, sendDataPtr, sendDataSize);
|
||||
//unlock();
|
||||
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||
if (!aboutSend()) return;
|
||||
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||
if (history_write_send) {
|
||||
history_file_send.writeToBinLog(history_id_send, sendDataPtr, sendDataSize);
|
||||
history_rsize_send.setReadableSize(history_file_send.pos());
|
||||
}
|
||||
if (type_send == PIProtocol::Serial)
|
||||
if (ser->send((uchar * )sendDataPtr, sendDataSize))
|
||||
if (ser->send(sendDataPtr, sendDataSize))
|
||||
send_count++;
|
||||
if (type_send == PIProtocol::Ethernet)
|
||||
if (eth->send((uchar * )sendDataPtr, sendDataSize))
|
||||
if (eth->send(sendDataPtr, sendDataSize))
|
||||
send_count++;
|
||||
}
|
||||
|
||||
14
piprotocol.h
Normal file → Executable file
14
piprotocol.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Protocol, input/output channel (COM, UDP)
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include "piserial.h"
|
||||
#include "piethernet.h"
|
||||
#include "pipacketextractor.h"
|
||||
#include "pitimer.h"
|
||||
#include "piconfig.h"
|
||||
#include "math.h"
|
||||
#include "piobject.h"
|
||||
|
||||
class PIProtocol;
|
||||
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
EVENT_HANDLER0(PIProtocol, void, stopReceive);
|
||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
|
||||
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||
@@ -87,7 +87,8 @@ public:
|
||||
EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();}
|
||||
EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();}
|
||||
EVENT_HANDLER0(PIProtocol, void, send);
|
||||
EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size);
|
||||
EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size) {send(data, size, false);}
|
||||
EVENT_HANDLER3(PIProtocol, void, send, const void *, data, int, size, bool, direct);
|
||||
|
||||
void setName(const PIString & name) {protName = name; PIObject::setName(name);}
|
||||
PIString name() const {return protName;}
|
||||
@@ -126,7 +127,7 @@ public:
|
||||
void * receiveData() {return dataPtr;}
|
||||
void * sendData() {return sendDataPtr;}
|
||||
|
||||
PIByteArray lastHeader() {if (ser != 0) return ser->lastHeader(); return PIByteArray();}
|
||||
PIByteArray lastHeader() {return packet_ext.lastHeader();}
|
||||
|
||||
protected:
|
||||
virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
|
||||
@@ -169,6 +170,7 @@ private:
|
||||
void changeDisconnectTimeout();
|
||||
|
||||
ReceiveFunc ret_func;
|
||||
PIPacketExtractor packet_ext;
|
||||
PITimer * diagTimer, * sendTimer;
|
||||
PIMultiProtocolBase * mp_owner;
|
||||
PIProtocol::Type type_send, type_rec;
|
||||
|
||||
177
piserial.cpp
Normal file → Executable file
177
piserial.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,32 +20,48 @@
|
||||
#include "piserial.h"
|
||||
|
||||
|
||||
PISerial::PISerial(PIString name, void * data_, SerialFunc slot, SerialHeaderFunc slot_header): PIThread() {
|
||||
PISerial::PISerial(const PIString & device, void * data_, ReadRetFunc slot): PIIODevice(device, ReadWrite) {
|
||||
piMonitor.serials++;
|
||||
setPriority(piHigh);
|
||||
path_ = device;
|
||||
data = data_;
|
||||
devName = name;
|
||||
fd = -1;
|
||||
missed = 0;
|
||||
dataSize = headerSize = 0;
|
||||
headerPtr = 0;
|
||||
ret_func = slot;
|
||||
ret_func_header = slot_header;
|
||||
params = 0;
|
||||
vtime = 1;
|
||||
ret_func_ = slot;
|
||||
#ifdef WINDOWS
|
||||
hCom = 0;
|
||||
#endif
|
||||
ispeed = ospeed = S115200;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PISerial::PISerial(void * data_, ReadRetFunc slot): PIIODevice("", ReadWrite) {
|
||||
piMonitor.serials++;
|
||||
setPriority(piHigh);
|
||||
data = data_;
|
||||
fd = -1;
|
||||
headerPtr = 0;
|
||||
params = 0;
|
||||
vtime = 1;
|
||||
ret_func_ = slot;
|
||||
#ifdef WINDOWS
|
||||
hCom = 0;
|
||||
#endif
|
||||
ispeed = ospeed = S115200;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PISerial::~PISerial() {
|
||||
piMonitor.serials--;
|
||||
terminate();
|
||||
}
|
||||
|
||||
|
||||
void PISerial::terminate() {
|
||||
if (!initialized()) return;
|
||||
bool PISerial::closeDevice() {
|
||||
if (!isInitialized()) return true;
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
PIThread::terminate();
|
||||
@@ -60,10 +76,11 @@ void PISerial::terminate() {
|
||||
#else
|
||||
if (fd != -1) {
|
||||
tcsetattr(fd, TCSANOW, &sdesc);
|
||||
close(fd);
|
||||
::close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,79 +102,51 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
}
|
||||
|
||||
|
||||
void PISerial::begin() {
|
||||
allReaded = addSize = curInd = 0;
|
||||
first = false;
|
||||
packetSize = headerSize + dataSize;
|
||||
if (headerSize > 0) mheader.resize(headerSize);
|
||||
if (!init()) stop();
|
||||
}
|
||||
|
||||
|
||||
void PISerial::run() {
|
||||
if (dataSize == 0) return;
|
||||
while (allReaded < packetSize + addSize) {
|
||||
#ifdef WINDOWS
|
||||
WaitCommEvent(hCom, 0, 0);
|
||||
ReadFile(hCom, &buffer[allReaded], SERIAL_BUFFER_SIZE, &readed, 0);
|
||||
#else
|
||||
readed = read(fd, &buffer[allReaded], SERIAL_BUFFER_SIZE);
|
||||
#endif
|
||||
allReaded += readed;
|
||||
bool PISerial::read(void * data, int size, double timeout_ms) {
|
||||
if (data == 0) return false;
|
||||
int ret, all = 0;
|
||||
if (timeout_ms > 0.) {
|
||||
setReadIsBlocking(false);
|
||||
all = ::read(fd, data, 1);
|
||||
timer.reset();
|
||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||
ret = ::read(fd, &((uchar * )data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
else msleep(1);
|
||||
}
|
||||
if (headerSize > 0) {
|
||||
if (allReaded + curInd >= SERIAL_BUFFER_SIZE) {
|
||||
memcpy(sbuffer, buffer, SERIAL_BUFFER_SIZE);
|
||||
memcpy(buffer, &sbuffer[SERIAL_BUFFER_SIZE - packetSize], allReaded);
|
||||
allReaded = packetSize;
|
||||
addSize = curInd = 0;
|
||||
}
|
||||
while (!ret_func_header(data, (uchar * )headerPtr, &buffer[curInd], headerSize)) {
|
||||
curInd++; missed++;
|
||||
if (curInd > addSize) {
|
||||
addSize += packetSize;
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(mheader.data(), &buffer[curInd + headerSize], headerSize);
|
||||
if (!ret_func(data, &buffer[curInd + headerSize], dataSize)) {
|
||||
curInd++; missed++;
|
||||
return;
|
||||
}
|
||||
memcpy(sbuffer, buffer, allReaded);
|
||||
memcpy(buffer, &sbuffer[packetSize + curInd], allReaded);
|
||||
allReaded -= packetSize + curInd;
|
||||
curInd = addSize = 0;
|
||||
return (all == size);
|
||||
} else {
|
||||
ret_func(data, buffer, dataSize);
|
||||
memcpy(sbuffer, buffer, allReaded);
|
||||
memcpy(buffer, &sbuffer[packetSize], allReaded);
|
||||
allReaded -= packetSize;
|
||||
setReadIsBlocking(true);
|
||||
all = ::read(fd, data, 1);
|
||||
while (all < size) {
|
||||
ret = ::read(fd, &((uchar * )data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
}
|
||||
return (all == size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PISerial::end() {
|
||||
terminate();
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::init() {
|
||||
bool PISerial::openDevice() {
|
||||
#ifdef WINDOWS
|
||||
hCom = CreateFileA(devName.stdString().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
DWORD da = 0, sm = 0;
|
||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if(hCom == INVALID_HANDLE_VALUE) {
|
||||
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
COMMTIMEOUTS times;
|
||||
times.ReadIntervalTimeout = 1;
|
||||
times.ReadIntervalTimeout = vtime;
|
||||
times.ReadTotalTimeoutConstant = 1;
|
||||
times.ReadTotalTimeoutMultiplier = 0;
|
||||
times.WriteTotalTimeoutConstant = 0;
|
||||
times.WriteTotalTimeoutMultiplier = 1;
|
||||
times.WriteTotalTimeoutConstant = 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||
cout << "[PISerial] Unable to set timeouts for \"" << devName << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to set timeouts for \"" << path_ << "\"" << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
@@ -175,15 +164,22 @@ bool PISerial::init() {
|
||||
}
|
||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
if (SetCommState(hCom, &desc) == -1) {
|
||||
cout << "[PISerial] Unable to set comm state for \"" << devName << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to set comm state for \"" << path_ << "\"" << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
fd = open(devName.data(), O_NOCTTY | O_RDWR);
|
||||
int om = 0;
|
||||
switch (mode_) {
|
||||
case PIIODevice::ReadOnly: om = O_RDONLY; break;
|
||||
case PIIODevice::WriteOnly: om = O_WRONLY; break;
|
||||
case PIIODevice::ReadWrite: om = O_RDWR; break;
|
||||
}
|
||||
//cout << "init ser " << path_ << " mode " << om << endl;
|
||||
fd = ::open(path_.data(), O_NOCTTY | om);
|
||||
if(fd == -1) {
|
||||
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||
piCout << "[PISerial] Unable to open \"" << path_ << "\"" << endl;
|
||||
return false;
|
||||
}
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
@@ -191,48 +187,47 @@ bool PISerial::init() {
|
||||
tcgetattr(fd, &desc);
|
||||
sdesc = desc;
|
||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
||||
desc.c_cflag = CLOCAL | CREAD | CSIZE;
|
||||
desc.c_cflag = CLOCAL | CSIZE | CS8;
|
||||
if (isReadable()) desc.c_cflag |= CREAD;
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
|
||||
if (params[PISerial::ParityControl]) {
|
||||
desc.c_iflag |= INPCK;
|
||||
desc.c_cflag |= PARENB;
|
||||
if (params[PISerial::ParityOdd]) desc.c_cflag |= PARODD;
|
||||
}
|
||||
desc.c_cc[VMIN] = 0;
|
||||
desc.c_cc[VTIME] = 1;
|
||||
desc.c_cc[VMIN] = 1;
|
||||
desc.c_cc[VTIME] = vtime;
|
||||
|
||||
cfsetispeed(&desc, convertSpeed(ispeed));
|
||||
cfsetospeed(&desc, convertSpeed(ospeed));
|
||||
|
||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||
cout << "[PISerial] Can`t set attributes for \"" << devName << "\"" << endl;
|
||||
close(fd);
|
||||
piCout << "[PISerial] Can`t set attributes for \"" << path_ << "\"" << endl;
|
||||
::close(fd);
|
||||
return false;
|
||||
}
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
//cout << "[PISerial] Initialized " << devName << endl;
|
||||
//piCout << "[PISerial] Initialized " << path_ << endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::send(uchar * data, int size) {
|
||||
//cout << "[PISerial] send size: " << sizeof(data) << endl;
|
||||
if (fd == -1) {
|
||||
//cout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
||||
return false;
|
||||
int PISerial::write(const void * data, int max_size, bool wait) {
|
||||
//piCout << "[PISerial] send size: " << sizeof(data) << endl;
|
||||
if (fd == -1 || !canWrite()) {
|
||||
//piCout << "[PISerial] Can`t write to uninitialized COM" << endl;
|
||||
return -1;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
DWORD wrote;
|
||||
WriteFile(hCom, data, size, &wrote, 0);
|
||||
WriteFile(hCom, data, max_size, &wrote, 0);
|
||||
#else
|
||||
int wrote;
|
||||
wrote = write(fd, data, size);
|
||||
wrote = ::write(fd, data, max_size);
|
||||
if (wait) tcdrain(fd);
|
||||
#endif
|
||||
if ((int)wrote != size) {
|
||||
//cout << "[PISerial] Error while sending" << endl;
|
||||
return false;
|
||||
}
|
||||
//cout << "[PISerial] Wrote " << wrote << " bytes in " << devName << endl;
|
||||
return true;
|
||||
return (int)wrote;
|
||||
//piCout << "[PISerial] Error while sending" << endl;
|
||||
//piCout << "[PISerial] Wrote " << wrote << " bytes in " << path_ << endl;
|
||||
}
|
||||
|
||||
85
piserial.h
Normal file → Executable file
85
piserial.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef PISERIAL_H
|
||||
#define PISERIAL_H
|
||||
|
||||
#include "pithread.h"
|
||||
#include "pistring.h"
|
||||
#include "pitimer.h"
|
||||
#include "piiodevice.h"
|
||||
#ifndef WINDOWS
|
||||
# include <termios.h>
|
||||
# include <fcntl.h>
|
||||
@@ -42,16 +42,12 @@
|
||||
# define B256000 256000
|
||||
#endif
|
||||
|
||||
#define SERIAL_BUFFER_SIZE 4096
|
||||
|
||||
typedef bool (*SerialFunc)(void * , uchar * , int );
|
||||
typedef bool (*SerialHeaderFunc)(void * , uchar * , uchar * , int );
|
||||
|
||||
class PISerial: public PIThread {
|
||||
class PISerial: public PIIODevice {
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, uchar*, int)"
|
||||
// slot_header is any function format "bool <func>(void*, uchar*, uchar*, int)"
|
||||
PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0, SerialHeaderFunc slot_header = headerValidate);
|
||||
PISerial(const PIString & device, void * data = 0, ReadRetFunc slot = 0);
|
||||
PISerial(void * data = 0, ReadRetFunc slot = 0);
|
||||
~PISerial();
|
||||
|
||||
enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04};
|
||||
@@ -69,31 +65,59 @@ public:
|
||||
S115200 = 115200
|
||||
};
|
||||
|
||||
void setSlot(SerialFunc func) {ret_func = func;}
|
||||
void setData(void * d) {data = d;}
|
||||
|
||||
//void setSlot(SerialFunc func) {ret_func = func;}
|
||||
void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;}
|
||||
void setOutSpeed(PISerial::Speed speed) {ospeed = speed;}
|
||||
void setInSpeed(PISerial::Speed speed) {ispeed = speed;}
|
||||
void setDevice(const PIString & dev) {devName = dev;}
|
||||
void setDevice(const PIString & dev) {path_ = dev;}
|
||||
void setParameters(PIFlags<PISerial::Parameters> parameters) {params = parameters;}
|
||||
void setData(void * d) {data = d;}
|
||||
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; this->headerSize = headerSize; this->dataSize = dataSize;}
|
||||
void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on);}
|
||||
void setVTime(int t) {vtime = t;}
|
||||
|
||||
bool send(uchar * data, int size);
|
||||
bool init();
|
||||
bool initialized() const {return fd != -1;}
|
||||
void terminate();
|
||||
#ifdef WINDOWS
|
||||
void setReadIsBlocking(bool yes) {
|
||||
COMMTIMEOUTS times;
|
||||
times.ReadIntervalTimeout = yes ? vtime : MAXDWORD;
|
||||
times.ReadTotalTimeoutConstant = yes ? 1 : 0;
|
||||
times.ReadTotalTimeoutMultiplier = 0;
|
||||
times.WriteTotalTimeoutConstant = 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (isOpened()) SetCommTimeouts(hCom, ×);
|
||||
}
|
||||
#else
|
||||
void setReadIsBlocking(bool yes) {if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);}
|
||||
#endif
|
||||
|
||||
PIByteArray lastHeader() {return mheader;}
|
||||
ullong missedBytes() const {return missed;}
|
||||
ullong missedPackets() const {return (packetSize == 0 ? 0 : missed / packetSize);}
|
||||
const PIString & device() const {return path_;}
|
||||
PISerial::Speed outSpeed() const {return ospeed;}
|
||||
PISerial::Speed inSpeed() const {return ispeed;}
|
||||
int VTime() const {return vtime;}
|
||||
|
||||
private:
|
||||
#ifdef WINDOWS
|
||||
int read(void * read_to, int max_size) {
|
||||
if (!canRead()) return -1;
|
||||
WaitCommEvent(hCom, 0, 0);
|
||||
ReadFile(hCom, read_to, max_size, &readed, 0);
|
||||
return readed;
|
||||
}
|
||||
#else
|
||||
int read(void * read_to, int max_size) {if (!canRead()) return -1; return ::read(fd, read_to, max_size);}
|
||||
#endif
|
||||
bool read(void * data, int size, double timeout_ms);
|
||||
|
||||
int write(const void * data, int max_size, bool wait);
|
||||
int write(const void * data, int max_size) {return write(data, max_size, false);}
|
||||
bool send(const void * data, int size, bool wait = false) {return (write(data, size, wait) == size);}
|
||||
|
||||
|
||||
protected:
|
||||
int convertSpeed(PISerial::Speed speed);
|
||||
static bool headerValidate(void * d, uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
||||
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
|
||||
#ifdef WINDOWS
|
||||
DCB desc, sdesc;
|
||||
@@ -103,18 +127,11 @@ private:
|
||||
termios desc, sdesc;
|
||||
uint readed;
|
||||
#endif
|
||||
int fd;
|
||||
int fd, vtime;
|
||||
PISerial::Speed ospeed, ispeed;
|
||||
PIString devName;
|
||||
SerialFunc ret_func;
|
||||
SerialHeaderFunc ret_func_header;
|
||||
uchar buffer[SERIAL_BUFFER_SIZE], sbuffer[SERIAL_BUFFER_SIZE];
|
||||
PIByteArray mheader;
|
||||
PITimer timer;
|
||||
void * headerPtr, * data;
|
||||
int dataSize, headerSize, packetSize, allReaded, addSize, curInd;
|
||||
ullong missed;
|
||||
PIFlags<PISerial::Parameters> params;
|
||||
bool first;
|
||||
|
||||
};
|
||||
|
||||
|
||||
2
pisignals.cpp
Normal file → Executable file
2
pisignals.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Signals
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pisignals.h
Normal file → Executable file
2
pisignals.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Signals
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
54
pistring.cpp
Normal file → Executable file
54
pistring.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -83,7 +83,7 @@ PIString & PIString::operator +=(const wchar_t * str) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete c;
|
||||
delete[] c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -313,6 +313,30 @@ PIString PIString::toLowerCase() const {
|
||||
}
|
||||
|
||||
|
||||
int PIString::lengthAscii() const {
|
||||
int j = 0;
|
||||
for (int i = 0; i < size_s(); ++i, ++j)
|
||||
if (!at(i).isAscii()) ++j;
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
const char * PIString::data() const {
|
||||
PIByteArray & d_(*(const_cast<PIByteArray * >(&data_)));
|
||||
d_.clear();
|
||||
for (int i = 0, j = 0; i < size_s(); ++i, ++j) {
|
||||
if (at(i).isAscii())
|
||||
d_.push_back(uchar(at(i).toAscii()));
|
||||
else {
|
||||
d_.push_back((at(i).toCharPtr()[0])); ++j;
|
||||
d_.push_back((at(i).toCharPtr()[1]));
|
||||
}
|
||||
}
|
||||
d_.push_back(uchar('\0'));
|
||||
return (const char * )d_.data();
|
||||
}
|
||||
|
||||
|
||||
string PIString::convertToStd() const {
|
||||
string s;
|
||||
if (size() > 0) {
|
||||
@@ -332,7 +356,7 @@ string PIString::convertToStd() const {
|
||||
char PIString::toChar() const {
|
||||
PIString s(toNativeDecimalPoints());
|
||||
char v;
|
||||
sscanf(s.stdString().c_str(), "%c", &v);
|
||||
sscanf(s.data(), "%c", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -340,9 +364,9 @@ char PIString::toChar() const {
|
||||
short PIString::toShort() const {
|
||||
PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
|
||||
short v;
|
||||
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%hx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%ho", &v); return v;}
|
||||
sscanf(s.stdString().c_str(), "%hd", &v);
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%hx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%ho", &v); return v;}
|
||||
sscanf(s.data(), "%hd", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -350,9 +374,9 @@ short PIString::toShort() const {
|
||||
int PIString::toInt() const {
|
||||
PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
|
||||
int v;
|
||||
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%x", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%o", &v); return v;}
|
||||
sscanf(s.stdString().c_str(), "%d", &v);
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%x", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%o", &v); return v;}
|
||||
sscanf(s.data(), "%d", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -360,9 +384,9 @@ int PIString::toInt() const {
|
||||
long PIString::toLong() const {
|
||||
PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
|
||||
long v;
|
||||
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%lx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%lo", &v); return v;}
|
||||
sscanf(s.stdString().c_str(), "%ld", &v);
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%lx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%lo", &v); return v;}
|
||||
sscanf(s.data(), "%ld", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -370,9 +394,9 @@ long PIString::toLong() const {
|
||||
llong PIString::toLLong() const {
|
||||
PIString s(trimmed().toLowerCase().toNativeDecimalPoints());
|
||||
llong v;
|
||||
if (s.left(2) == "0x") {sscanf(s.stdString().c_str(), "%llx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.stdString().c_str(), "%llo", &v); return v;}
|
||||
sscanf(s.stdString().c_str(), "%lld", &v);
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%llx", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%llo", &v); return v;}
|
||||
sscanf(s.data(), "%lld", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
19
pistring.h
Normal file → Executable file
19
pistring.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
String
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -126,8 +126,12 @@ public:
|
||||
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
|
||||
PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;}
|
||||
PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;}
|
||||
PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;}
|
||||
PIString reversed() const {PIString str(*this); str.reverse(); return str;}
|
||||
|
||||
const char * data() {return convertToStd().c_str();}
|
||||
//const char * data() {return convertToStd().c_str();}
|
||||
int lengthAscii() const;
|
||||
const char * data() const;
|
||||
const string stdString() const {return convertToStd();}
|
||||
wstring stdWString() const {return convertToWString();}
|
||||
PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());}
|
||||
@@ -153,15 +157,15 @@ public:
|
||||
int length() const {return size();}
|
||||
bool isEmpty() const {return (size() == 0 || *this == "");}
|
||||
|
||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().stdString().c_str()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;}
|
||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;}
|
||||
char toChar() const;
|
||||
short toShort() const;
|
||||
int toInt() const;
|
||||
long toLong() const;
|
||||
llong toLLong() const;
|
||||
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().stdString().c_str());}
|
||||
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().stdString().c_str());}
|
||||
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().stdString().c_str());}
|
||||
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());}
|
||||
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
|
||||
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
|
||||
@@ -188,11 +192,14 @@ private:
|
||||
string convertToStd() const;
|
||||
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
|
||||
|
||||
PIByteArray data_;
|
||||
//string std_string;
|
||||
//wstring std_wstring;
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||
inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;}
|
||||
|
||||
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
|
||||
|
||||
|
||||
8
pisystemmonitor.cpp
Normal file → Executable file
8
pisystemmonitor.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process resource monitor
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -39,10 +39,10 @@ bool PISystemMonitor::startOnProcess(int pID) {
|
||||
stop();
|
||||
pID_ = pID;
|
||||
#ifndef WINDOWS
|
||||
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIFile::Read);
|
||||
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIFile::Read);
|
||||
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
|
||||
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
|
||||
if (!file.isOpened()) {
|
||||
cout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl;
|
||||
piCout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl;
|
||||
return false;
|
||||
}
|
||||
cycle = -1;
|
||||
|
||||
2
pisystemmonitor.h
Normal file → Executable file
2
pisystemmonitor.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process resource monitor
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
45
pithread.cpp
Normal file → Executable file
45
pithread.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Thread
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,23 +20,26 @@
|
||||
#include "pithread.h"
|
||||
|
||||
|
||||
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
|
||||
piMonitor.threads++;
|
||||
data_ = data;
|
||||
ret_func = func;
|
||||
running = lockRun = false;
|
||||
priority_ = piNormal;
|
||||
timer = timer_delay;
|
||||
if (startNow) start(timer_delay);
|
||||
}
|
||||
|
||||
|
||||
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
|
||||
piMonitor.threads++;
|
||||
ret_func = 0;
|
||||
running = lockRun = false;
|
||||
priority_ = piNormal;
|
||||
timer = timer_delay;
|
||||
/*addEvent("started");
|
||||
addEvent("stopped");
|
||||
addEventHandler<int>(HANDLER(PIThread, start));
|
||||
addEventHandler(HANDLER(PIThread, startOnce));
|
||||
addEventHandler(HANDLER(PIThread, stop));
|
||||
addEventHandler<bool>(HANDLER(PIThread, terminate));*/
|
||||
if (startNow) start(timer_delay);
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
#else
|
||||
#endif
|
||||
|
||||
PIThread::~PIThread() {
|
||||
piMonitor.threads--;
|
||||
@@ -57,14 +60,17 @@ bool PIThread::start(int timer_delay) {
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedparam(&attr, &sparam);
|
||||
if (pthread_create(&thread, &attr, thread_function, this) == 0) {
|
||||
setPriority(priority_);
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0);
|
||||
if (thread == 0)
|
||||
return false;
|
||||
if (thread != 0) {
|
||||
setPriority(priority_);
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -76,13 +82,18 @@ bool PIThread::startOnce() {
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedparam(&attr, &sparam);
|
||||
if (pthread_create(&thread, &attr, thread_function_once, this) == 0)
|
||||
if (pthread_create(&thread, &attr, thread_function_once, this) == 0) {
|
||||
setPriority(priority_);
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0);
|
||||
if (thread == 0)
|
||||
return false;
|
||||
if (thread != 0) {
|
||||
setPriority(priority_);
|
||||
running = true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -110,6 +121,7 @@ void * PIThread::thread_function(void * t) {
|
||||
while (!ct->terminating) {
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data_);
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
if (ct->timer > 0) msleep(ct->timer);
|
||||
}
|
||||
@@ -133,6 +145,7 @@ void * PIThread::thread_function_once(void * t) {
|
||||
raiseEvent(ct, "started");
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data_);
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
raiseEvent(ct, "stopped");
|
||||
ct->end();
|
||||
|
||||
21
pithread.h
Normal file → Executable file
21
pithread.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Thread
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -30,8 +30,11 @@ inline void msleep(int msecs) {Sleep(msecs);}
|
||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||
#endif
|
||||
|
||||
typedef void (*ThreadFunc)(void * );
|
||||
|
||||
class PIThread: public PIObject {
|
||||
public:
|
||||
PIThread(void * data, ThreadFunc func, bool startNow = false, int timer_delay = -1);
|
||||
PIThread(bool startNow = false, int timer_delay = -1);
|
||||
~PIThread();
|
||||
|
||||
@@ -52,11 +55,16 @@ public:
|
||||
//bool start(int timer_delay = -1);
|
||||
EVENT_HANDLER0(PIThread, bool, start) {return start(-1);}
|
||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay);
|
||||
EVENT_HANDLER1(PIThread, bool, start, ThreadFunc, func) {ret_func = func; return start(-1);}
|
||||
EVENT_HANDLER2(PIThread, bool, start, ThreadFunc, func, int, timer_delay) {ret_func = func; return start(timer_delay);}
|
||||
EVENT_HANDLER0(PIThread, bool, startOnce);
|
||||
EVENT_HANDLER1(PIThread, bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
|
||||
EVENT_HANDLER0(PIThread, void, stop) {stop(false);}
|
||||
EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
|
||||
EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);}
|
||||
EVENT_HANDLER1(PIThread, void, terminate, bool, hard);
|
||||
void setData(void * d) {data_ = d;}
|
||||
void setSlot(ThreadFunc func) {ret_func = func;}
|
||||
void setPriority(PIThread::Priority prior);
|
||||
PIThread::Priority priority() const {return priority_;}
|
||||
bool isRunning() const {return running;}
|
||||
@@ -69,19 +77,20 @@ public:
|
||||
EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();}
|
||||
PIMutex & mutex() {return mutex_;}
|
||||
|
||||
private:
|
||||
virtual void begin() {;} // executed at start
|
||||
virtual void run() {;} // main loop
|
||||
virtual void end() {;} // executed at finish
|
||||
|
||||
protected:
|
||||
static void * thread_function(void * t);
|
||||
static void * thread_function_once(void * t);
|
||||
|
||||
virtual void begin() {;} // executed at start
|
||||
virtual void run() {;} // main loop executed with "timer_delay" timeout
|
||||
virtual void end() {;} // executed at finish
|
||||
|
||||
volatile bool terminating, running, lockRun;
|
||||
int timer, policy;
|
||||
void * data_;
|
||||
PIMutex mutex_;
|
||||
PIThread::Priority priority_;
|
||||
ThreadFunc ret_func;
|
||||
#ifndef WINDOWS
|
||||
pthread_t thread;
|
||||
sched_param sparam;
|
||||
|
||||
143
pitimer.cpp
143
pitimer.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -56,11 +56,15 @@ PITimer::~PITimer() {
|
||||
|
||||
#ifndef WINDOWS
|
||||
void PITimer::start(double msecs) {
|
||||
if (ti == 0) return;
|
||||
if (ti == 0 || msecs < 0) return;
|
||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(msecs / 1000);
|
||||
spec.it_value = spec.it_interval;
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
if (ti == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
timer_settime(timer, 0, &spec, 0);
|
||||
running = true;
|
||||
}
|
||||
@@ -119,11 +123,10 @@ void PITimer::run() {
|
||||
double PITimer::elapsed_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000000. - t_st * 1000000.);
|
||||
return (t_cur - t_st) * 1000000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec) -
|
||||
(t_st.tv_sec * 1.e+9 + t_st.tv_nsec);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -131,11 +134,10 @@ double PITimer::elapsed_n() {
|
||||
double PITimer::elapsed_u() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000. - t_st * 1000.);
|
||||
return (t_cur - t_st) * 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3)) -
|
||||
(t_st.tv_sec * 1.e+6 + (t_st.tv_nsec / 1.e+3));
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -146,8 +148,7 @@ double PITimer::elapsed_m() {
|
||||
return (double)(t_cur - t_st);
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6)) -
|
||||
(t_st.tv_sec * 1.e+3 + (t_st.tv_nsec / 1.e+6));
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -155,11 +156,102 @@ double PITimer::elapsed_m() {
|
||||
double PITimer::elapsed_s() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur / 1000. - t_st / 1000.);
|
||||
return (t_cur - t_st) / 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9)) -
|
||||
(t_st.tv_sec + (t_st.tv_nsec / 1.e+9));
|
||||
return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return t_st * 1000000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+9 + t_st.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_u() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+6 + t_st.tv_nsec / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_m() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+3 + t_st.tv_nsec / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_s() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) / 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec + t_st.tv_nsec / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_n() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000000.);
|
||||
#else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_u() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000.);
|
||||
#else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_m() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (double)t_cur;
|
||||
#else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_s() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur / 1000.);
|
||||
#else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -186,6 +278,31 @@ PIDate currentDate() {
|
||||
}
|
||||
|
||||
|
||||
PIString PITime::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(minutes));
|
||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(seconds));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDate::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(year));
|
||||
ts.replace("mm", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString time2string(const PITime & time, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||
|
||||
20
pitimer.h
20
pitimer.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -32,12 +32,14 @@ struct PITime {
|
||||
int seconds;
|
||||
int minutes;
|
||||
int hours;
|
||||
PIString toString(const PIString & format = "h:mm:ss");
|
||||
};
|
||||
|
||||
struct PIDate {
|
||||
int day;
|
||||
int month;
|
||||
int year; // since 1900
|
||||
PIString toString(const PIString & format = "d.mm.yyyy");
|
||||
};
|
||||
|
||||
class PITimer
|
||||
@@ -77,11 +79,21 @@ public:
|
||||
double elapsed_m(); // miliseconds
|
||||
double elapsed_s(); // seconds
|
||||
|
||||
double reset_time_n(); // nanoseconds
|
||||
double reset_time_u(); // microseconds
|
||||
double reset_time_m(); // miliseconds
|
||||
double reset_time_s(); // seconds
|
||||
|
||||
static double elapsed_system_n(); // nanoseconds
|
||||
static double elapsed_system_u(); // microseconds
|
||||
static double elapsed_system_m(); // miliseconds
|
||||
static double elapsed_system_s(); // seconds
|
||||
|
||||
private:
|
||||
#ifdef WINDOWS
|
||||
void run();
|
||||
|
||||
long int t_st, t_cur;
|
||||
long t_st, t_cur;
|
||||
#else
|
||||
static void timer_event(sigval e);
|
||||
|
||||
@@ -109,7 +121,7 @@ private:
|
||||
|
||||
PITime currentTime();
|
||||
PIDate currentDate();
|
||||
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss");
|
||||
PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy");
|
||||
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||
PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy"); // obsolete, use PITime.toString() instead
|
||||
|
||||
#endif // PITIMER_H
|
||||
|
||||
6
pivariable.cpp
Normal file → Executable file
6
pivariable.cpp
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variable, Struct (simple serialization)
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -40,6 +40,7 @@ bool PIVariant::operator ==(const PIVariant & v) const {
|
||||
case PIVariant::String: return vString == v.vString;
|
||||
case PIVariant::StringList: return vStringList == v.vStringList;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +85,7 @@ PIString PIVariant::stringValue() const {
|
||||
case PIVariant::String: return vString;
|
||||
case PIVariant::StringList: return vStringList.join("%|%");
|
||||
};
|
||||
return vString;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +216,7 @@ void PIVariable::writeVariable(char * dest) {
|
||||
|
||||
|
||||
void PIStruct::parseFile(const PIString & file) {
|
||||
PIConfig conf(file, PIFile::Read);
|
||||
PIConfig conf(file, PIIODevice::ReadOnly);
|
||||
PIVariable var;
|
||||
PIString ts;
|
||||
uint sz = 0;
|
||||
|
||||
2
pivariable.h
Normal file → Executable file
2
pivariable.h
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Variable, Struct (simple serialization)
|
||||
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
BIN
Описание.odt
Normal file → Executable file
BIN
Описание.odt
Normal file → Executable file
Binary file not shown.
BIN
Описание.pdf
Normal file → Executable file
BIN
Описание.pdf
Normal file → Executable file
Binary file not shown.
Reference in New Issue
Block a user