29.04.2014 - Version 0.4.0_prealpha. PICodeParser, namespace PICodeInfo, new tool "pip_cmg" in dir "code_model_generator". New feature in PIIODevice - "createFromFullPath", all parameters of all I/O devices now works with PIObjects`s properties.

This commit is contained in:
peri4
2014-04-29 11:50:13 +04:00
parent 77abb0bbea
commit 2e5e75c4c4
98 changed files with 2545 additions and 768 deletions

View File

@@ -101,6 +101,7 @@ target_link_libraries(pip_test pip)
add_subdirectory(system_test) add_subdirectory(system_test)
add_subdirectory(remote_console) add_subdirectory(remote_console)
add_subdirectory(code_model_generator)
if (DEFINED LIB) if (DEFINED LIB)
unset(LIB) unset(LIB)

4
clean
View File

@@ -10,3 +10,7 @@ cd remote_console
rm -rvf ./CMakeFiles rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd .. cd ..
cd code_model_generator
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd ..

View File

@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 2.6)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} . ../)
file(GLOB CPPS "*.cpp")
add_definitions(-Wall -O2)
add_executable(pip_cmg "main.cpp")
target_link_libraries(pip_cmg pip)
if (DEFINED LIB)
unset(LIB)
if (${WIN32})
get_filename_component(MGWDIR ${CMAKE_C_COMPILER} PATH)
set(CMAKE_INSTALL_PREFIX)
install(TARGETS pip_cmg DESTINATION ${MGWDIR}/../bin)
else ()
set(CMAKE_INSTALL_PREFIX /usr)
install(TARGETS pip_cmg DESTINATION bin)
endif ()
endif ()

View File

@@ -0,0 +1,225 @@
/*
PIP - Platform Independent Primitives
Code model generator
Copyright (C) 2014 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 "picli.h"
#include "picodeparser.h"
void usage() {
piCout << Bold << "PIP Code model generator";
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
piCout << Green << Bold << "Usage:" << Default << "\"pip_cmg [-h] -o <output_file> [-I<include_dir1>] [-I<include_dir1>] [...] [-D<define1>] [-D<define1>] [...] <file1> [<file2>] [<file3>] [...]\"" << NewLine;
piCout << Green << Bold << "Details:";
piCout << "-h " << Green << "- display this message and exit";
piCout << "-o <output_file> " << Green << "- output file for code model without extension (e.g. \"ccm\" - files \"ccm.h\" and \"ccm.cpp\" will be created)";
piCout << "-I<include_dir> " << Green << "- add include dir (e.g. -I.. -I../some_dir -I/usr/include)";
piCout << "-D<define> " << Green << "- add define to preprocessor, define PICODE is always defined (e.g. -DMY_DEFINE will add MY_DEFINE define)";
piCout << "<file> " << Green << "- add file to code model, all includes of this file will be proceed (e.g. \"main.cpp\")";
}
void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) {
f << "\n\tci = new ClassInfo();\n";
f << "\t(*classesInfo)[\"" << e->name << "\"] = ci;\n";
f << "\tci->name = \"" << e->name << "\";\n";
piForeachC (PICodeParser::Entity * p, e->parents)
f << "\tci->parents << \"" << p->name << "\";\n";
piForeachC (PICodeParser::Member & m, e->members) {
f << "\tci->variables << TypeInfo(\"" << m.name << "\", \"" << m.type << "\"";
if (m.attributes != 0) {
bool fir = true;
f << ", ";
if (m.attributes[PICodeParser::Const]) {if (fir) fir = false; else f << " | "; f << "Const";}
if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else f << " | "; f << "Static";}
if (m.attributes[PICodeParser::Mutable]) {if (fir) fir = false; else f << " | "; f << "Mutable";}
if (m.attributes[PICodeParser::Volatile]) {if (fir) fir = false; else f << " | "; f << "Volatile";}
if (m.attributes[PICodeParser::Inline]) {if (fir) fir = false; else f << " | "; f << "Inline";}
if (m.attributes[PICodeParser::Virtual]) {if (fir) fir = false; else f << " | "; f << "Virtual";}
}
f << ");\n";
}
PIString arg;
piForeachC (PICodeParser::Member & m, e->functions) {
if (e->name.findCWord(m.name) >= 0) continue;
f << "\tci->functions.push_back(FunctionInfo()); fi = &(ci->functions.back());\n";
f << "\tfi->name = \"" << m.name << "\";";
f << " fi->return_type = TypeInfo(\"\", \"" << m.type << "\"";
if (m.attributes[PICodeParser::Const] || m.attributes[PICodeParser::Static]) {
bool fir = true;
f << ", ";
if (m.attributes[PICodeParser::Const]) {if (fir) fir = false; else f << " | "; f << "Const";}
if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else f << " | "; f << "Static";}
}
f << ");\n";
//piCout << "write func" << m.name;
piForeachC (PIString & a, m.arguments_full) {
//piCout << "write arg" << a;
f << "\tfi->arguments << TypeInfo(";
arg = a;
bool con = false;
arg.prepend(" ");
if (arg.find(" const ") >= 0) {
arg.replaceAll(" const ", " ");
con = true;
}
arg.trim();
int ts = 0;
for (ts = arg.size_s() - 1; ts > 0; --ts)
if (!_isCChar(arg[ts]) && !(arg[ts].isDigit())) break;
f << "\"" << arg.takeRight(arg.size_s() - ts - 1).trim() << "\", ";
f << "\"" << arg.trim() << "\"";
if (con) f << ", Const";
f << ");\n";
}
}
}
void makeEnumInfo(PIFile & f, const PICodeParser::Enum * e) {
f << "\n\tei = new EnumInfo();\n";
f << "\t(*enumsInfo)[\"" << e->name << "\"] = ei;\n";
f << "\tei->name = \"" << e->name << "\";\n";
piForeachC (PICodeParser::Enumerator & m, e->members)
f << "\tei->members << PICodeInfo::EnumeratorInfo(\"" << m.first << "\", " << m.second << ");\n";
}
void writeModel(PICodeParser & parser, const PIString out) {
PIVector<const PICodeParser::Entity * > ventities;
PIString defname = out.replaceAll(".", "_").replaceAll("/", "_").toUpperCase() + "_H";
PISet<PIString> inc_files;
piForeachC (PICodeParser::Entity * e, parser.entities)
if (e->name.find("::") < 0 && !e->name.startsWith("_PI"))
inc_files << e->file;
PIFile f(out + ".cpp");
f.clear();
f.open(PIIODevice::WriteOnly);
f << "// Generated by \"PIP Code model generator\" " << currentDateTime().toString("dd.MM.yyyy hh:mm:ss\n\n");
f << "#include <string.h>\n#include \"" << out << ".h\"\n\nusing namespace PICodeInfo;\n\n";
piForeachC (PIString & i, inc_files)
f << "#include \"" << i << "\"\n";
f << "\n";
PIString entry, argtype, rettype, args;
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.find("::") >= 0 || e->name.startsWith("_PI")) continue;
entry.clear();
entry << "\nPIVariant execFunction(" << e->name << " * object, const char * function, const PIVariant & arg0, const PIVariant & arg1, const PIVariant & arg2, const PIVariant & arg3) {\n";
const PIVector<PICodeParser::Member> & fl(e->functions);
bool efunc = true;
piForeachC (PICodeParser::Member & m, fl) {
if (m.name.startsWith("__stat") || m.attributes[PICodeParser::Static]) continue;
//piCout << e->name << m.name << m.visibility;
args.clear();
rettype = m.type;
if (rettype.startsWith("const") && rettype.endsWith("&"))
rettype.cutLeft(5).cutRight(1).trim();
if (rettype.endsWith("&")) continue;
bool aok = true, ret = (m.type != "void");
if (m.arguments_full.size() > 4 || m.visibility != PICodeParser::Public) continue;
for (int i = 0; i < m.arguments_full.size_s(); ++i) {
if (i > 0) args << ", ";
argtype = m.arguments_type[i];
if (argtype.startsWith("const") && argtype.endsWith("&"))
argtype.cutLeft(5).cutRight(1).trim();
if (argtype.endsWith("&")) {
aok = false;
continue;
}
//entry << "(" << m.arguments_type[i] << ")";
//if (parser.isEnum(m.arguments_type[i])) entry << "(int)";
args << "arg" << i << ".toValue<" << argtype << " >()";
}
if (!aok) continue;
efunc = false;
entry << "\tif (strcmp(function, \"" << m.name << "\") == 0) {";
if (ret) entry << "return PIVariant::fromValue<" << rettype << " >(";
entry << "object->" << m.name << "(" << args << ")";
if (ret) entry << ");";
else entry << "; return PIVariant();";
entry << "}\n";
}
if (efunc) continue;
f << entry << "\tPICout(AddNewLine) << \"Can`t find function \\\"\" << function << \"\\\" in "
<< e->type << " \\\"" << e->name << "\\\"!\";\n\treturn PIVariant();\n}\n";
ventities << e;
}
f << "\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
f << "\tif (_inited_) return;\n\t_inited_ = true;\n\n";
f << "\tClassInfo * ci;\n\tTypeInfo * ni;\n\tFunctionInfo * fi;\n\tEnumInfo * ei;";
f << "\n\n// Classes\n";
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.startsWith("_PI")) continue;
makeClassInfo(f, e);
}
f << "\n// Enums\n";
piForeachC (PICodeParser::Enum & e, parser.enums)
makeEnumInfo(f, &e);
f << "}\n";
f << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n";
f.close();
f.setPath(out + ".h");
f.clear();
f.open(PIIODevice::WriteOnly);
f << "// Generated by \"PIP Code model generator\" " << currentDateTime().toString("dd.MM.yyyy hh:mm:ss\n\n");
f << "#ifndef " << defname << "\n#define " << defname << "\n\n";
f << "#include \"pivariant.h\"\n#include \"picodeinfo.h\"\n\n";
piForeachC (PICodeParser::Entity * e, ventities)
f << e->type << " " << e->name << ";\n";
f << "\n";
piForeachC (PICodeParser::Entity * e, ventities) {
f << "\nPIVariant execFunction(" << e->name << " * object, const char * function, const PIVariant & arg0 = PIVariant(), \
const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());";
}
f << "\n\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n";
f << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n";
f << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n";
f << "\n\n#endif // " << defname << "\n";
f.close();
}
int main(int argc, char * argv[]) {
PICLI cli(argc, argv);
cli.setOptionalArgumentsCount(-1);
cli.addArgument("output", true);
cli.addArgument("help");
if (cli.hasArgument("help") || cli.argumentValue("output").isEmpty() || cli.optionalArguments().isEmpty()) {
usage();
return 0;
}
PICodeParser parser;
piForeachC (PIString & a, cli.rawArguments()) {
if (a.startsWith("-I")) parser.includeDirectory(a.mid(2));
if (a.startsWith("-D")) parser.addDefine(a.mid(2), PIString());
}
PIStringList files;
piForeachC (PIString & a, cli.optionalArguments())
if (!a.startsWith("-")) files << a;
piCout << Cyan << Bold << "Parse files" << files << "...";
parser.parseFiles(files);
piCout << Cyan << Bold << "Parsing done";
piCout << Cyan << Bold << "Writing code model ...";
writeModel(parser, cli.argumentValue("output"));
piCout << Cyan << Bold << "Writing done";
return 0;
};

View File

@@ -0,0 +1,48 @@
/*
PIP - Platform Independent Primitives
Code model generator
Copyright (C) 2014 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 "pitimer.h"
#include "test.h"
void event(void * , int d) {
piCout << "tick" << d;
}
PITimer tm;
int main(int argc, char * argv[]) {
//tm.setSlot(event);
//tm.start(200);
/*execFunction(&tm, "setSlot", PIVariant::fromValue<TimerEvent>(event));
execFunction(&tm, "start", 200);
piMSleep(1000);
execFunction(&tm, "addDelimiter", 2);
piMSleep(1000);
execFunction(&tm, "stop");
execFunction(&tm, "stop_");
piMSleep(1000);*/
typedef std::pair<PIString, PICodeInfo::ClassInfo * > mpair;
piForeachC (mpair & i, *(PICodeInfo::classesInfo))
piCout << *i.second;
piCout << "\n\n";
typedef std::pair<PIString, PICodeInfo::EnumInfo * > epair;
piForeachC (epair & i, *(PICodeInfo::enumsInfo))
piCout << *i.second;
return 0;
};

140
main.cpp
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Test program Test program
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -55,23 +55,147 @@ Test::PIVariant<T> newVariant(const T & v) {return Test::PIVariant<T>(v);}
template <typename T> template <typename T>
Test::PIVariant<T> * castVariant(Test::__PIVariantBase * v, const T & t) {return static_cast<Test::PIVariant<T> * >(v);} Test::PIVariant<T> * castVariant(Test::__PIVariantBase * v, const T & t) {return static_cast<Test::PIVariant<T> * >(v);}
*/ */
#include "picode.h" #include "picodeparser.h"
#define S(a, b) a#b #define S(a, b) a#b
enum TypeFlag {NoFlag, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
typedef PIFlags<TypeFlag> TypeFlags;
struct TypeInfo {
TypeInfo() {flags = 0;}
PIString name;
PIString type;
TypeFlags flags;
};
struct FunctionInfo {
PIString name;
TypeInfo return_type;
PIVector<TypeInfo> arguments;
};
struct ClassInfo {
PIString name;
PIStringList parents;
PIVector<TypeInfo> variables;
PIVector<FunctionInfo> functions;
};
inline PICout operator <<(PICout s, const TypeInfo & v) {
if (v.flags[Inline]) s << "inline ";
if (v.flags[Virtual]) s << "virtual ";
if (v.flags[Static]) s << "static ";
if (v.flags[Const]) s << "const ";
if (v.flags[Mutable]) s << "mutable ";
if (v.flags[Volatile]) s << "volatile ";
s << v.type;
if (!v.name.isEmpty())
s << " " << v.name;
return s;
}
inline PICout operator <<(PICout s, const ClassInfo & v) {
s.setControl(0, true);
s << "class " << v.name;
if (!v.parents.isEmpty()) {
s << ": ";
bool first = true;
piForeachC (PIString & i, v.parents) {
if (first) first = false;
else s << ", ";
s << i;
}
s << " {\n";
piForeachC (FunctionInfo & i, v.functions) {
s << Tab << i.return_type << " " << i.name << "(";
bool fa = true;
piForeachC (TypeInfo & a, i.arguments) {
if (fa) fa = false;
else s << ", ";
s << a;
}
s << ");\n";
}
if (!v.functions.isEmpty() && !v.variables.isEmpty())
s << "\n";
piForeachC (TypeInfo & i, v.variables) {
s << Tab << i << ";\n";
}
s << "}\n";
}
s.restoreControl();
return s;
}
int main (int argc, char * argv[]) { int main (int argc, char * argv[]) {
//piCout << (S(1,2)); PIString s("this\t :is \n(SPARTA)!");
//(1,2)); piCout << s.findCWord("this");
//CodeParser cd; piCout << s.findCWord("is");
//cd.parseFile("test.cpp"); piCout << s.findCWord("SPARTA");
piCout << s.findCWord("SPARTA!");
if (argc < 2) return 0;
PICodeParser cd;
//cd.includeDirectory("../qpicalculator");
cd.parseFile(argv[1]);
piForeachC (PICodeParser::Enum & e, cd.enums)
piCout << e.name << e.members;
ClassInfo ci;
PICodeParser::Entity * e = cd.findEntityByName("PITimer");
if (!e) return 0;
ci.name = e->name;
piForeachC (PICodeParser::Entity * p, e->parents)
ci.parents << p->name;
piForeachC (PICodeParser::Member & m, e->members) {
TypeInfo ni;
ni.name = m.name;
ni.type = m.type;
if (m.attributes[PICodeParser::Const]) ni.flags |= Const;
if (m.attributes[PICodeParser::Static]) ni.flags |= Static;
if (m.attributes[PICodeParser::Mutable]) ni.flags |= Mutable;
if (m.attributes[PICodeParser::Volatile]) ni.flags |= Volatile;
if (m.attributes[PICodeParser::Inline]) ni.flags |= Inline;
if (m.attributes[PICodeParser::Virtual]) ni.flags |= Virtual;
ci.variables << ni;
}
piForeachC (PICodeParser::Member & m, e->functions) {
FunctionInfo fi;
fi.name = m.name;
fi.return_type.type = m.type;
if (m.attributes[PICodeParser::Const]) fi.return_type.flags |= Const;
if (m.attributes[PICodeParser::Static]) fi.return_type.flags |= Static;
piForeachC (PIString & a, m.arguments_full) {
TypeInfo ni;
PIString arg(a);
arg.prepend(" ");
if (arg.find(" const ") >= 0) {
ni.flags |= Const;
arg.replaceAll(" const ", " ");
}
int ts = 0;
for (ts = arg.size_s() - 1; ts >= 0; --ts)
if (!_isCChar(arg[ts]) && !(arg[ts].isDigit())) break;
ni.name = arg.takeRight(arg.size_s() - ts - 1).trim();
ni.type = arg.trim();
fi.arguments << ni;
}
ci.functions << fi;
}
piCout << NewLine << ci;
//piCout << v.toType<float>(); //piCout << v.toType<float>();
//piCout << v.toType<float>().toType<PIString>(); //piCout << v.toType<float>().toType<PIString>();
//PIFile::remove("ki"); //PIFile::remove("ki");
/*PIConfig conf("protocols_commod.conf"); /*PIConfig conf("protocols_commod.conf");
piCout << conf.allTree(); piCout << conf.allTree();
conf.setValue("rmd.123", 456);*/ conf.setValue("rmd.123", 456);*/
piCout << PIString("1.1").toFloat();
piCout << PIString("1,1").toFloat(); /*PITimer tm;
piCout << tm.debug() << tm.properties();
tm.setDebug(false);
piCout << tm.debug() << tm.properties();
tm.setDebug(true);
piCout << tm.debug() << tm.properties();*/
//PIObject * ser = (PIObject * )PIIODevice::createFromFullPath("file://OM2:38400:7");
//piCout << ser << NewLine << ser->properties();
} }

View File

@@ -42,6 +42,8 @@
* *
*/ */
REGISTER_DEVICE(PIBinaryLog);
PIBinaryLog::PIBinaryLog() { PIBinaryLog::PIBinaryLog() {
binlog_sig[0] = 'B'; binlog_sig[0] = 'B';
@@ -51,10 +53,13 @@ PIBinaryLog::PIBinaryLog() {
binlog_sig[4] = 'O'; binlog_sig[4] = 'O';
binlog_sig[5] = 'G'; binlog_sig[5] = 'G';
setThreadedReadBufferSize(65536); setThreadedReadBufferSize(65536);
is_started = rapid_start = false; is_started = false;
playspeed = 1.0f; setPlaySpeed(1.f);
default_id = 1; setDefaultID(1);
playmode = PlayVariableSpeed; setPlayMode(PlayVariableSpeed);
setLogDir(PIString());
setFilePrefix(PIString());
setRapidStart(false);
} }
@@ -64,23 +69,23 @@ bool PIBinaryLog::openDevice() {
is_started = false; is_started = false;
is_thread_ok = true; is_thread_ok = true;
if (mode_ == ReadWrite) { if (mode_ == ReadWrite) {
piCoutObj << "ReadWrite mode not supported, use WriteOnly or ReadOnly"; piCoutObj << "Error: ReadWrite mode not supported, use WriteOnly or ReadOnly";
return false; return false;
} }
if (!file.open(path_, mode_)) if (!file.open(path(), mode_))
return false; return false;
setName(path_); setName(path());
if (mode_ == WriteOnly) { if (mode_ == WriteOnly) {
file.resize(0); file.resize(0);
if (!writeFileHeader()) { if (!writeFileHeader()) {
piCoutObj << "Can't write binlog file header"; piCoutObj << "Error: Can't write binlog file header";
return false; return false;
} }
is_started = true; is_started = true;
} }
if (mode_ == ReadOnly) { if (mode_ == ReadOnly) {
if (file.isEmpty()) { if (file.isEmpty()) {
piCoutObj << "File is null"; piCoutObj << "Error: File is null";
fileError(); fileError();
return false; return false;
} }
@@ -88,11 +93,11 @@ bool PIBinaryLog::openDevice() {
fileError(); fileError();
return false; return false;
} }
if (isEmpty()) piCoutObj << "Empty BinLog file"; if (isEmpty()) piCoutObj << "Error: Empty BinLog file";
// startlogtime = currentSystemTime(); // startlogtime = currentSystemTime();
play_time = 0; play_time = 0;
// nextrecord = readsRecord(); // nextrecord = readsRecord();
if (!rapid_start) is_started = true; if (!rapidStart()) is_started = true;
} }
startlogtime = currentSystemTime(); startlogtime = currentSystemTime();
return true; return true;
@@ -112,7 +117,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
is_thread_ok = false; is_thread_ok = false;
PISystemTime pt; PISystemTime pt;
double delay; double delay;
switch (playmode) { switch (playMode()) {
case PlayRealTime: case PlayRealTime:
pt = currentSystemTime() - startlogtime; pt = currentSystemTime() - startlogtime;
// if (real_speedX > 0) // if (real_speedX > 0)
@@ -129,7 +134,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
break; break;
case PlayVariableSpeed: case PlayVariableSpeed:
delay = lastrecord.timestamp.toMilliseconds() - play_time; delay = lastrecord.timestamp.toMilliseconds() - play_time;
delay /= playspeed; delay /= playSpeed();
if (is_started) { if (is_started) {
if (delay > 0) if (delay > 0)
PISystemTime::fromMilliseconds(delay).sleep(); PISystemTime::fromMilliseconds(delay).sleep();
@@ -147,7 +152,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
PIString PIBinaryLog::createNewFile() { PIString PIBinaryLog::createNewFile() {
if (!file.close()) return PIString(); if (!file.close()) return PIString();
if (open(logdir + "/" + fileprefix + currentDateTime().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly)) if (open(logDir() + "/" + filePrefix() + currentDateTime().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly))
return file.path(); return file.path();
piCoutObj << "Can't create new file, maybe LogDir is invalid."; piCoutObj << "Can't create new file, maybe LogDir is invalid.";
return PIString(); return PIString();
@@ -225,15 +230,14 @@ int PIBinaryLog::read(void *read_to, int max_size) {
} }
void PIBinaryLog::restart() void PIBinaryLog::restart() {
{
bool th = isRunning(); bool th = isRunning();
if (th) stopThreadedRead(); if (th) stopThreadedRead();
if (!canRead()) return; if (!canRead()) return;
lastrecord.timestamp = PISystemTime(); lastrecord.timestamp = PISystemTime();
lastrecord.id = 0; lastrecord.id = 0;
is_thread_ok = true; is_thread_ok = true;
if (rapid_start) is_started = false; if (rapidStart()) is_started = false;
else is_started = true; else is_started = true;
play_time = 0; play_time = 0;
file.seekToBegin(); file.seekToBegin();
@@ -302,3 +306,15 @@ PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
} }
void PIBinaryLog::configureFromFullPath(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0: setLogDir(p); break;
case 1: setFilePrefix(p); break;
case 2: setDefaultID(p.toInt()); break;
}
}
}

View File

@@ -31,7 +31,7 @@
class PIBinaryLog: public PIIODevice class PIBinaryLog: public PIIODevice
{ {
PIOBJECT(PIBinaryLog) PIIODEVICE(PIBinaryLog)
public: public:
PIBinaryLog(); PIBinaryLog();
~PIBinaryLog() {closeDevice();} ~PIBinaryLog() {closeDevice();}
@@ -44,32 +44,38 @@ public:
//! Current \a PlayMode //! Current \a PlayMode
PlayMode playMode() const {return playmode;} PlayMode playMode() const {return (PlayMode)(property("playMode").toInt());}
//! Current directory where billogs wiil be saved //! Current directory where billogs wiil be saved
const PIString & logDir() const {return logdir;} PIString logDir() const {return property("logDir").toString();}
//! Returns current file prefix //! Returns current file prefix
const PIString & filePrefix() const {return fileprefix;} PIString filePrefix() const {return property("filePrefix").toString();}
//! Current LogDir, returns directory where billogs wiil be saved //! Current LogDir, returns directory where billogs wiil be saved
int dafaultID() const {return default_id;} int defaultID() const {return property("defaultID").toInt();}
//! Returns current play speed //! Returns current play speed
float speed() const {return playspeed;} float playSpeed() const {return property("playSpeed").toFloat();}
//! Returns if rapid start enabled
bool rapidStart() const {return property("rapidStart").toBool();}
//! Set \a PlayMode //! Set \a PlayMode
void setPlayMode(PlayMode mode) {playmode = mode;} void setPlayMode(PlayMode mode) {setProperty("playMode", (int)mode);}
//! Set path to directory where binlogs will be saved //! Set path to directory where binlogs will be saved
void setLogDir(const PIString & path) {logdir = path;} void setLogDir(const PIString & path) {setProperty("logDir", path);}
//! Set file prefix, used to //! Set file prefix, used to
void setFilePrefix(const PIString & prefix) {fileprefix = prefix;} void setFilePrefix(const PIString & prefix) {setProperty("filePrefix", prefix);}
//! Set defaultID, used in \a write function //! Set defaultID, used in \a write function
void setDefaultID(int id) {default_id = id;} void setDefaultID(int id) {setProperty("defaultID", id);}
//! If enabled BinLog \a ThreadedRead starts without delay for first record, e.g. first record will be readed immediately
void setRapidStart(bool enabled) {setProperty("rapidStart", enabled);}
// /** \brief Set play speed multiplyer, used only in \a PlayMode = \a PlayRealTime default value 1x. // /** \brief Set play speed multiplyer, used only in \a PlayMode = \a PlayRealTime default value 1x.
// * If "speedX" > 0 than it use as speed increase by X times, else as speed decrease by X times. // * If "speedX" > 0 than it use as speed increase by X times, else as speed decrease by X times.
@@ -77,8 +83,8 @@ public:
// bool setRealSpeedX(int speedX) {if (speedX == 0 || isRunning()) return false; real_speedX = speedX; return true;} // bool setRealSpeedX(int speedX) {if (speedX == 0 || isRunning()) return false; real_speedX = speedX; return true;}
// //! Returns current play speed multiplyer // //! Returns current play speed multiplyer
// float realSpeedX() const {return real_speedX;} // float realSpeedX() const {return real_speedX;}
//! Set play speed, used only in \a PlayMode = \a PlayVariableSpeed, default value 1.0 //! Set play speed, used only if \a playMode = \a PlayVariableSpeed, default value 1.0
void setSpeed(float speed) {playspeed = speed;} void setPlaySpeed(float speed) {setProperty("playSpeed", speed);}
//! Write one record to BinLog file, with ID = id, id must be greather than 0 //! Write one record to BinLog file, with ID = id, id must be greather than 0
@@ -89,7 +95,7 @@ public:
//! Read one record from BinLog file, with ID = id, if id = 0 than any id will be readed //! Read one record from BinLog file, with ID = id, if id = 0 than any id will be readed
PIByteArray readBinLog(int id = 0); PIByteArray readBinLog(int id = 0);
int readBinLog(int id, void *read_to, int max_size); int readBinLog(int id, void * read_to, int max_size);
//! Return true, if position at the end of BinLog file //! Return true, if position at the end of BinLog file
bool isEnd() {if (!opened_) return true; return file.isEnd();} bool isEnd() {if (!opened_) return true; return file.isEnd();}
@@ -103,14 +109,11 @@ public:
int read(void *read_to, int max_size); int read(void *read_to, int max_size);
//! Write one record to BinLog file, with ID = "defaultID" //! Write one record to BinLog file, with ID = "defaultID"
int write(const void * data, int size) {return writeBinLog(default_id, data, size);} int write(const void * data, int size) {return writeBinLog(defaultID(), data, size);}
//! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead //! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead
PIVector<int> filterID; PIVector<int> filterID;
//! If "RapidStart" enabled, than BinLog \a ThreadedRead starts without delay for first record, e.g. first record will be readed immediately
void setRapidStart(bool enabled = false) {rapid_start = enabled;}
//! Go to begin of BinLog file //! Go to begin of BinLog file
void restart(); void restart();
@@ -139,6 +142,8 @@ public:
EVENT(fileError) EVENT(fileError)
protected: protected:
PIString fullPathPrefix() const {return "binlog";}
void configureFromFullPath(const PIString & full_path);
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();
bool threadedRead(uchar *readed, int size); bool threadedRead(uchar *readed, int size);
@@ -156,16 +161,12 @@ private:
BinLogRecord readRecord(); BinLogRecord readRecord();
PIFile file; PIFile file;
PIString logdir, fileprefix;
BinLogRecord lastrecord; BinLogRecord lastrecord;
PISystemTime startlogtime; PISystemTime startlogtime;
//BinLogRecord nextrecord; //BinLogRecord nextrecord;
PlayMode playmode;
double play_time; //milliseconds double play_time; //milliseconds
float playspeed;
int default_id;
//int real_speedX; // in X //int real_speedX; // in X
bool is_started, rapid_start, is_thread_ok; bool is_started, is_thread_ok;
uchar binlog_sig[PIBINARYLOG_SIGNATURE_SIZE]; uchar binlog_sig[PIBINARYLOG_SIGNATURE_SIZE];
}; };

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Bit array Bit array
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array Byte array
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array Byte array
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ public:
friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v); friend PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v);
public: public:
//! Constructs data block //! Constructs data block
RawData(void * data, int size) {d = data; s = size;} RawData(void * data = 0, int size = 0) {d = data; s = size;}
//! Constructs data block //! Constructs data block
RawData(const void * data, const int size) {d = const_cast<void * >(data); s = size;} RawData(const void * data, const int size) {d = const_cast<void * >(data); s = size;}
RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;} RawData & operator =(const RawData & o) {d = o.d; s = o.s; return *this;}
@@ -153,6 +153,7 @@ private:
}; };
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {if (v0.size() == v1.size()) {for (uint i = 0; i < v0.size(); ++i) if (v0[i] != v1[i]) return v0[i] < v1[i]; return false;} return v0.size() < v1.size();}
//! \relatesalso PIByteArray \brief Output to std::ostream operator //! \relatesalso PIByteArray \brief Output to std::ostream operator
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; return s;} inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {s << "{"; for (uint i = 0; i < ba.size(); ++i) {s << ba[i]; if (i < ba.size() - 1) s << ", ";} s << "}"; return s;}

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Unicode char Unicode char
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser Command-Line Parser
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -63,13 +63,16 @@ void PICLI::parse() {
if (cra.left(1) == _prefix_short) { if (cra.left(1) == _prefix_short) {
last = 0; last = 0;
for (int j = 1; j < cra.length(); ++j) { for (int j = 1; j < cra.length(); ++j) {
bool found = false;
piForeach (Argument & a, _args) { piForeach (Argument & a, _args) {
if (a.short_key == cra[j]) { if (a.short_key == cra[j]) {
a.found = true; a.found = true;
last = &a; last = &a;
found = true;
break; break;
} }
} }
if (!found) break;
} }
} else { } else {
if (last == 0 ? true : !last->has_value) { if (last == 0 ? true : !last->has_value) {
@@ -77,7 +80,7 @@ void PICLI::parse() {
_args_mand << cra; _args_mand << cra;
continue; continue;
} }
if (_args_opt.size_s() < _count_opt) { if (_args_opt.size_s() < _count_opt || _count_opt < 0) {
_args_opt << cra; _args_opt << cra;
continue; continue;
} }

12
picli.h
View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser Command-Line Parser
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@ public:
const PIStringList & optionalArguments() {parse(); return _args_opt;} const PIStringList & optionalArguments() {parse(); return _args_opt;}
//! Returns program execute command without arguments //! Returns program execute command without arguments
const PIString programCommand() {parse(); return _args_raw.size() > 0 ? _args_raw.front() : PIString();} PIString programCommand() {parse(); return _args_raw.size() > 0 ? _args_raw.front() : PIString();}
bool hasArgument(const PIString & name) {parse(); piForeach (Argument & i, _args) if (i.name == name && i.found) return true; return false;} bool hasArgument(const PIString & name) {parse(); piForeach (Argument & i, _args) if (i.name == name && i.found) return true; return false;}
PIString argumentValue(const PIString & name) {parse(); piForeach (Argument &i, _args) if (i.name == name && i.found) return i.value; return PIString();} PIString argumentValue(const PIString & name) {parse(); piForeach (Argument &i, _args) if (i.name == name && i.found) return i.value; return PIString();}
PIString argumentShortKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.short_key; return PIString();} PIString argumentShortKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.short_key; return PIString();}
@@ -71,10 +71,10 @@ public:
const PIString & fullKeyPrefix() const {return _prefix_full;} const PIString & fullKeyPrefix() const {return _prefix_full;}
int mandatoryArgumentsCount() const {return _count_mand;} int mandatoryArgumentsCount() const {return _count_mand;}
int optionalArgumentsCount() const {return _count_opt;} int optionalArgumentsCount() const {return _count_opt;}
void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix;} void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix; needParse = true;}
void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix;} void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix; needParse = true;}
void setMandatoryArgumentsCount(const int count) {_count_mand = count;} void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
void setOptionalArgumentsCount(const int count) {_count_opt = count;} void setOptionalArgumentsCount(const int count) {_count_opt = count; needParse = true;}
private: private:
struct Argument { struct Argument {

View File

@@ -1,189 +0,0 @@
/*
PIP - Platform Independent Primitives
Packets extractor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picode.h"
PIString CodeParser::Macro::expand(const PIStringList & arg_vals, bool * ok) const {
if (args.size() != arg_vals.size()) {
piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect")
<< args.size() << "arguments but takes" << arg_vals.size() << "!";
if (ok != 0) *ok = false;
return PIString();
}
PIString ret = value;
for (int i = 0; i < args.size_s(); ++i) {
const PIString & an(args[i]), av(arg_vals[i]);
int ind(-1);
while ((ind = ret.find(an, ind + 1)) >= 0) {
PIChar ppc(0), pc(0), nc(0);
if (ind > 1) ppc = ret[ind - 2];
if (ind > 0) pc = ret[ind - 1];
if (ind + an.size_s() < ret.size_s()) nc = ret[ind + an.size_s()];
if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
ind--;
ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
ind -= an.size_s() - av.size_s() - 1;
continue;
}
if (_isCChar(pc) || _isCChar(nc)) continue;
ret.replace(ind, an.size_s(), av);
ind -= an.size_s() - av.size_s();
}
}
ret.replaceAll("##", "");
if (ok != 0) *ok = true;
return ret;
}
CodeParser::CodeParser() {
}
bool CodeParser::parseFile(const PIString & file) {
//piCout << "parse" << file << "...";
PIFile f(file, PIIODevice::ReadOnly);
if (!f.isOpened()) {
piCout << ("Error: can`t open file \"" + file + "\"!");
return false;
}
PIString fc = f.readAll();
return parseFileContent(fc);
}
void CodeParser::clear() {
defines.clear();
typedefs.clear();
tree.clear();
entities.clear();
}
bool CodeParser::parseFileContent(PIString & fc) {
bool mlc = false, cc = false;
int mls = 0, ole = -1, ccs = 0;
char c;
PIString pfc, line, ccmn;
PIMap<PIString, PIString> cchars;
/// Remove comments, join multiline "" and replace "" to $n (cchars)
fc.replaceAll("\r\n", "\n");
fc.replaceAll("\r", "\n");
for (int i = 0; i < fc.size_s() - 1; ++i) {
c = fc[i].toAscii();
if (c == '"') {
if (i > 0) if (fc[i - 1] == '\\') continue;
cc = !cc;
if (cc) ccs = i;
if (!cc) {
ccmn = "$" + PIString::fromNumber(cchars.size());
cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
fc.replace(ccs, i - ccs + 1, ccmn);
i = ccs - 1 + ccmn.size_s();
}
continue;
}
if (i > 0) {
if (c == '\\' && fc[i - 1] != '\\') {fc.cutMid(i, 2); --i;}
continue;
}
if (cc) continue;
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i + 1); --i; continue;}
}
while (!fc.isEmpty()) {
line = fc.takeLine().trimmed();
if (line.left(1) == "#") {
if (!parseDirective(line.cutLeft(1).trim()))
return false;
} else pfc << line << "\n";
}
bool replaced = true;
int replaced_cnt = 0;
while (replaced) {
if (replaced_cnt >= 64) {
piCout << "Error: recursive macros detected!";
return false;
}
replaced_cnt++;
replaced = false;
piForeachC (Define & d, defines) {
int ind(-1);
while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + d.first.size_s() < pfc.size_s()) nc = pfc[ind + d.first.size_s()];
if (_isCChar(pc) || _isCChar(nc)) continue;
pfc.replace(ind, d.first.size_s(), d.second);
ind -= d.first.size_s() - d.second.size_s();
replaced = true;
}
}
piForeachC (Macro & m, macros) {
int ind(-1);
while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc[ind + m.name.size_s()];
if (_isCChar(pc) || _isCChar(nc)) continue;
PIString ret, range; bool ok(false);
range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");
ret = m.expand(range.split(",").trim(), &ok);
//piCout << "range" << ret;
if (!ok) return false;
int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
pfc.replace(ind, rlen, ret);
ind -= rlen - ret.size_s();
replaced = true;
}
}
}
piCout << pfc;
return true;
}
bool CodeParser::parseDirective(PIString d) {
if (d.isEmpty()) return true;
PIString dname = d.takeCWord();
if (dname == "include") {
d.replaceAll("<", "\"").replaceAll(">", "\"");
return parseFile(d.takeRange("\"", "\""));
}
if (dname == "define") {
PIString mname = d.takeCWord();
if (d.left(1) == "(") { // macro
PIStringList args = d.takeRange("(", ")").split(",").trim();
macros << Macro(mname, d.trim(), args);
} else { // define
defines << Define(mname, d.trim());
}
return true;
}
return true;
}

View File

@@ -1,80 +0,0 @@
/*! \file pipacketextractor.h
* \brief Packets extractor
*/
/*
PIP - Platform Independent Primitives
Packets extractor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CODE_H
#define CODE_H
#include "pifile.h"
inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c == '_'));}
inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
class CodeParser {
public:
CodeParser();
bool parseFile(const PIString & file);
private:
void clear();
bool parseFileContent(PIString & fc);
bool parseDirective(PIString d);
enum Visibility {Global, Public, Protected, Private};
typedef PIPair<PIString, PIString> Define;
typedef PIPair<PIString, PIString> Typedef;
struct Macro {
Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
name = n;
value = v;
args = a;
}
PIString expand(const PIStringList & arg_vals, bool * ok = 0) const;
PIString name;
PIString value;
PIStringList args;
};
struct Entity {
Entity() {
visibility = Global;
size = 0;
parent = 0;
}
PIString type;
PIString name;
PIString file;
Visibility visibility;
int size;
Entity * parent;
PIVector<Entity * > children;
};
PIVector<Define> defines;
PIVector<Macro> macros;
PIVector<Typedef> typedefs;
PIVector<Entity> entities;
PIVector<Entity * > tree;
};
#endif // PIPACKETEXTRACTOR_H

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Text codings coder, based on "iconv" Text codings coder, based on "iconv"
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Text codings coder, based on "iconv" Text codings coder, based on "iconv"
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

26
picodeinfo.cpp Normal file
View File

@@ -0,0 +1,26 @@
/*
PIP - Platform Independent Primitives
C++ code info structs
Copyright (C) 2014 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 "picodeinfo.h"
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
bool __PICodeInfoInitializer__::_inited_ = false;

147
picodeinfo.h Normal file
View File

@@ -0,0 +1,147 @@
/*! \file picodeinfo.h
* \brief C++ code info structs
*/
/*
PIP - Platform Independent Primitives
C++ code info structs
Copyright (C) 2014 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 PICODEINFO_H
#define PICODEINFO_H
#include "pistring.h"
namespace PICodeInfo {
enum TypeFlag {NoFlag, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
typedef PIFlags<PICodeInfo::TypeFlag> TypeFlags;
struct TypeInfo {
TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0) {name = n; type = t; flags = f;}
PIString name;
PIString type;
PICodeInfo::TypeFlags flags;
};
struct FunctionInfo {
PIString name;
TypeInfo return_type;
PIVector<PICodeInfo::TypeInfo> arguments;
};
struct ClassInfo {
PIString name;
PIStringList parents;
PIVector<PICodeInfo::TypeInfo> variables;
PIVector<PICodeInfo::FunctionInfo> functions;
};
struct EnumeratorInfo {
EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
PIString name;
int value;
};
struct EnumInfo {
PIString name;
PIVector<PICodeInfo::EnumeratorInfo> members;
};
inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) {
if (v.flags[Inline]) s << "inline ";
if (v.flags[Virtual]) s << "virtual ";
if (v.flags[Mutable]) s << "mutable ";
if (v.flags[Volatile]) s << "volatile ";
if (v.flags[Static]) s << "static ";
if (v.flags[Const]) s << "const ";
s << v.type;
if (!v.name.isEmpty())
s << " " << v.name;
return s;
}
inline PICout operator <<(PICout s, const PICodeInfo::EnumeratorInfo & v) {s << v.name << " = " << v.value; return s;}
inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
s.setControl(0, true);
s << "class " << v.name;
if (!v.parents.isEmpty()) {
s << ": ";
bool first = true;
piForeachC (PIString & i, v.parents) {
if (first) first = false;
else s << ", ";
s << i;
}
}
s << " {\n";
piForeachC (FunctionInfo & i, v.functions) {
s << Tab << i.return_type << " " << i.name << "(";
bool fa = true;
piForeachC (TypeInfo & a, i.arguments) {
if (fa) fa = false;
else s << ", ";
s << a;
}
s << ");\n";
}
if (!v.functions.isEmpty() && !v.variables.isEmpty())
s << "\n";
piForeachC (TypeInfo & i, v.variables) {
s << Tab << i << ";\n";
}
s << "}\n";
s.restoreControl();
return s;
}
inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
s.setControl(0, true);
s << "enum " << v.name << " {\n";
piForeachC (EnumeratorInfo & i, v.members) {
bool f = true;
if (f) f = false;
else s << ", ";
s << Tab << i << "\n";
}
s << "}\n";
s.restoreControl();
return s;
}
extern PIMap<PIString, PICodeInfo::ClassInfo * > * classesInfo;
extern PIMap<PIString, PICodeInfo::EnumInfo * > * enumsInfo;
}
class __PICodeInfoInitializer__ {
public:
__PICodeInfoInitializer__() {
if (_inited_) return;
_inited_ = true;
PICodeInfo::classesInfo = new PIMap<PIString, PICodeInfo::ClassInfo * >;
PICodeInfo::enumsInfo = new PIMap<PIString, PICodeInfo::EnumInfo * >;
}
static bool _inited_;
};
static __PICodeInfoInitializer__ __picodeinfoinitializer__;
#endif // PICODEINFO_H

762
picodeparser.cpp Normal file
View File

@@ -0,0 +1,762 @@
/*
PIP - Platform Independent Primitives
C++ code parser
Copyright (C) 2014 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 "picodeparser.h"
PIString PICodeParser::Macro::expand(const PIStringList & arg_vals, bool * ok) const {
if (args.size() != arg_vals.size()) {
piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect")
<< args.size() << "arguments but takes" << arg_vals.size() << "!";
if (ok != 0) *ok = false;
return PIString();
}
PIString ret = value;
for (int i = 0; i < args.size_s(); ++i) {
const PIString & an(args[i]), av(arg_vals[i]);
int ind(-1);
while ((ind = ret.find(an, ind + 1)) >= 0) {
PIChar ppc(0), pc(0), nc(0);
if (ind > 1) ppc = ret[ind - 2];
if (ind > 0) pc = ret[ind - 1];
if (ind + an.size_s() < ret.size_s()) nc = ret[ind + an.size_s()];
if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
ind--;
ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
ind -= an.size_s() - av.size_s() - 1;
continue;
}
if (_isCChar(pc) || _isCChar(nc)) continue;
ret.replace(ind, an.size_s(), av);
ind -= an.size_s() - av.size_s();
}
}
ret.replaceAll("##", "");
if (ok != 0) *ok = true;
return ret;
}
PICodeParser::PICodeParser() {
macros_iter = 32;
clear();
includes << "";
}
void PICodeParser::parseFile(const PIString & file) {
clear();
parseFileInternal(file);
/*piCout << "\n\nDefines:";
piForeachC (Define & m, defines)
piCout << "define" << m.first << m.second;
piCout << "\n\nMacros:";
piForeachC (Macro & m, macros)
piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:";
piForeachC (Entity * c, entities)
piCout << "class" << c->name << c->parents;
piCout << "\n\nEnums:";
piForeachC (Enum & c, enums)
piCout << "enum" << c.name << c.members;
piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs)
piCout << "typedef" << c;*/
}
void PICodeParser::parseFiles(const PIStringList & files) {
clear();
piForeachC (PIString & f, files)
parseFileInternal(f);
/*piCout << "\n\nDefines:";
piForeachC (Define & m, defines)
piCout << "define" << m.first << m.second;
piCout << "\n\nMacros:";
piForeachC (Macro & m, macros)
piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:";
piForeachC (Entity * c, entities)
piCout << "class" << c->name << c->parents;
piCout << "\n\nEnums:";
piForeachC (Enum & c, enums)
piCout << "enum" << c.name << c.members;
piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs)
piCout << "typedef" << c;*/
}
bool PICodeParser::isEnum(const PIString & name) {
piForeachC (Enum & e, enums)
if (e.name == name)
return true;
return false;
}
bool PICodeParser::parseFileInternal(const PIString & file) {
if (proc_files[file]) return true;
proc_files << file;
cur_file = file;
PIFile f(file, PIIODevice::ReadOnly);
int ii = 0;
while (!f.isOpened() && ii < (includes.size_s() - 1)) {
f.setPath(includes[++ii] + "/" + file);
//piCout << "try" << f.path();
f.open(PIIODevice::ReadOnly);
}
if (!f.isOpened()) {
//piCout << ("Error: can`t open file \"" + file + "\"!");
return false;
}
PIString fc = f.readAll();
piCout << "parsing" << f.path() << "...";
bool ret = parseFileContent(fc);
piCout << "parsing" << f.path() << "done";
return ret;
}
void PICodeParser::clear() {
piForeach (Entity * i, entities) delete i;
defines.clear();
macros.clear();
enums.clear();
typedefs.clear();
entities.clear();
proc_files.clear();
cur_namespace.clear();
evaluator.clearCustomVariables();
defines << Define("PICODE", "") << custom_defines;
}
bool PICodeParser::parseFileContent(PIString & fc) {
bool mlc = false, cc = false;
int mls = 0, ole = -1, /*ccs = 0,*/ end = 0;
char c = 0, pc = 0;
PIString pfc, line, ccmn, tmp;
PIMap<PIString, PIString> cchars;
/// Remove comments, join multiline "*" and replace "*" to $n (cchars)
fc.replaceAll("\r\n", "\n");
fc.replaceAll("\r", "\n");
for (int i = 0; i < fc.size_s() - 1; ++i) {
if (i > 0) pc = c;
c = fc[i].toAscii();
if (c == '"' && !mlc && pc != '\'') {
if (i > 0) if (fc[i - 1] == '\\') continue;
cc = !cc;
/*if (cc) ccs = i;
if (!cc) {
ccmn = "$" + PIString::fromNumber(cchars.size());
cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
fc.replace(ccs, i - ccs + 1, ccmn);
i = ccs - 1 + ccmn.size_s();
}*/
continue;
}
if (i > 0)
if (c == '\\' && fc[i - 1].toAscii() != '\\') {
fc.cutMid(i, 2);
--i;
continue;
}
if (cc) continue;
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;}
}
//piCout << fc;
pfc = procMacros(fc);
bool replaced = true;
int replaced_cnt = 0;
while (replaced) {
//piCout << "MACRO iter" << replaced_cnt;
if (replaced_cnt >= macros_iter) {
piCout << "Error: recursive macros detected!";
break;//return false;
}
replaced_cnt++;
replaced = false;
piForeachC (Define & d, defines) {
int ind(-1);
while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + d.first.size_s() < pfc.size_s()) nc = pfc[ind + d.first.size_s()];
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
pfc.replace(ind, d.first.size_s(), d.second);
ind -= d.first.size_s() - d.second.size_s();
replaced = true;
}
}
piForeachC (Macro & m, macros) {
int ind(-1);
while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
PIChar pc(0), nc(0);
if (ind > 0) pc = pfc[ind - 1];
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc[ind + m.name.size_s()];
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
PIString ret, range; bool ok(false);
range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");
ret = m.expand(range.split(",").trim(), &ok);
if (!ok) return false;
int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
pfc.replace(ind, rlen, ret);
ind -= rlen - ret.size_s();
replaced = true;
}
}
}
//piCout << NewLine << "file" << cur_file << pfc;
for (int i = 0; i < pfc.size_s() - 5; ++i) {
if (pfc.mid(i, 8) == "template") {
pfc.cutLeft(i + 8);
pfc.takeRange("<", ">");
bool def = !isDeclaration(pfc, 0, &end);
pfc.cutLeft(end);
if (def) pfc.takeRange("{", "}");
else pfc.takeSymbol();
i = 0;
continue;
}
if (pfc.mid(i, 5) == "class" || pfc.mid(i, 6) == "struct") {
int dind = pfc.find("{", i), find = pfc.find(";", i);
if (dind < 0 && find < 0) {pfc.cutLeft(i + 6); i = 0; continue;}
if (dind < 0 || find < dind) {pfc.cutLeft(i + 6); i = 0; continue;}
ccmn = pfc.mid(i, dind - i) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n";
pfc.remove(i, ccmn.size());
parseClass(ccmn);
i = 0;
continue;
}
if (pfc.mid(i, 4) == "enum") {
pfc.cutLeft(i + 4);
tmp = pfc.takeCWord();
parseEnum(cur_namespace + tmp, pfc.takeRange("{", "}"));
pfc.takeSymbol();
i = 0;
continue;
}
if (pfc.mid(i, 7) == "typedef") {
pfc.cutLeft(i + 7);
typedefs << parseTypedef(pfc.takeLeft(pfc.find(";")));
if (typedefs.back().first.isEmpty()) typedefs.pop_back();
pfc.takeSymbol();
i = 0;
continue;
}
}
return true;
}
PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn;
//piCout << "found class <****\n" << cd << "\n****>";
int ind = cd.find(":");
PIVector<Entity * > parents;
if (ind > 0) {
PIStringList pl = cd.takeMid(ind + 1).trim().split(",");
cd.cutRight(1);
Entity * pe = 0;
piForeachC (PIString & p, pl) {
if (p.contains(" ")) pn = p.mid(p.find(" ") + 1);
else pn = p;
pe = findEntityByName(pn);
if (pe == 0) ;//{piCout << "Error: can`t find" << pn;}
else parents << pe;
}
}
bool is_class = cd.left(5) == "class";
cur_def_vis = (is_class ? Private : Public);
PIString cn = cd.mid(6).trim();
if (cn.isEmpty()) return 0;
Entity * e = new Entity();
e->name = cur_namespace + cn;
e->type = (is_class ? "class" : "struct");
e->parents = parents;
e->file = cur_file;
entities << e;
return e;
}
PIString PICodeParser::parseClass(PIString & fc) {
Visibility prev_vis = cur_def_vis;
int dind = fc.find("{"), find = fc.find(";"), end = 0;
if (dind < 0 && find < 0) return PIString();
if (dind < 0 || find < dind) return fc.left(find);
Entity * ce = parseClassDeclaration(fc.takeLeft(dind));
fc.trim().cutLeft(1).cutRight(1).trim();
//piCout << "found class <****\n" << fc << "\n****>";
if (!ce) return PIString();
int ps = -1;
bool def = false;
PIString prev_namespace = cur_namespace, stmp;
cur_namespace = ce->name + "::";
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
while (!fc.isEmpty()) {
PIString cw = fc.takeCWord(), tmp;
//piCout << "\ntaked word" << cw;
if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;}
if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;}
if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;}
if (cw == "class") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "class " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
if (cw == "struct") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "struct " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;}
if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;}
if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;}
if (cw == "template") {
fc.takeRange("<", ">");
def = !isDeclaration(fc, 0, &end);
fc.cutLeft(end);
if (def) fc.takeRange("{", "}");
else fc.takeSymbol();
continue;
}
def = !isDeclaration(fc, 0, &end);
tmp = (cw + fc.takeLeft(end)).trim();
if (!tmp.isEmpty())
parseMember(ce, tmp);
if (def) fc.takeRange("{", "}");
else fc.takeSymbol();
if (ps == fc.size_s()) {/*cur_namespace = prev_namespace;*/ fc.cutLeft(1);/*return false*/;}
ps = fc.size_s();
}
cur_def_vis = prev_vis;
cur_namespace = prev_namespace;
return ce->name;
}
bool PICodeParser::parseEnum(const PIString & name, PIString fc) {
//piCout << "enum" << name << fc;
Enum e(name);
PIStringList vl(fc.split(","));
PIString vn;
int cv = -1, ind = 0;
piForeachC (PIString & v, vl) {
vn = v; ind = v.find("=");
if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
if (ind < 0) ++cv;
e.members << Enumerator(vn.trim(), cv);
}
enums << e;
return true;
}
PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
//piCout << "parse typedef" << fc;
Typedef td;
fc.replaceAll("\t", " ");
if (fc.contains("(")) {
int start = fc.find("("), end = fc.find(")");
td.first = fc.takeMid(start + 1, end - start - 1).trim();
if (td.first.left(1) == "*") {td.first.cutLeft(1).trim(); fc.insert(start + 1, "*");}
td.second = fc.trim();
} else {
td.first = fc.takeMid(fc.findLast(" ")).trim();
td.second = fc.trim();
}
//piCout << "found typedef" << td;
return td;
}
bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
if (fc.trim().isEmpty()) return true;
if (fc.find("operator") >= 0) return true;
tmp_temp.clear();
//piCout << "parse member" << fc;
int ts = fc.find("<"), te = 0;
PIString ctemp, crepl;
while (ts >= 0) {
ctemp = fc.mid(ts).takeRange("<", ">");
if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;}
crepl = "$" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0");
fc.replace(ts, ctemp.size_s() + 2, crepl);
tmp_temp[crepl] = "<" + ctemp + ">";
ts = fc.find("<", te);
}
fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",");
PIStringList tl, al;
Member me;
//piCout << fc;
if (fc.contains("(")) {
fc.cutRight(fc.size_s() - fc.findLast(")") - 1);
te = fc.find("(");
//piCout << fc;
for (ts = te - 1; ts >= 0; --ts)
if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break;
//piCout << "takeMid" << ts + 1 << te - ts - 1;
me.name = fc.takeMid(ts + 1, te - ts - 1);
if (me.name == parent->name) return true;
me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(",");
me.type = fc.cutRight(1).trim();
me.visibility = cur_def_vis;
if (me.type.find("inline ") >= 0) {
me.attributes |= Inline;
me.type.removeAll("inline ");
}
if (me.type.find("static ") >= 0) {
me.attributes |= Static;
me.type.removeAll("static ");
}
if (me.type.find("virtual ") >= 0) {
me.attributes |= Virtual;
me.type.removeAll("virtual ");
}
normalizeEntityNamespace(me.type);
int i = 0;
piForeach (PIString & a, me.arguments_full)
if ((i = a.find("=")) > 0)
a.cutRight(a.size_s() - i).trim();
me.arguments_type = me.arguments_full;
piForeach (PIString & a, me.arguments_type) {
crepl.clear();
if (a.contains("["))
crepl = a.takeMid(a.find("["), a.findLast("]") - a.find("[") + 1);
for (ts = a.size_s() - 1; ts >= 0; --ts)
if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break;
a.cutRight(a.size_s() - ts - 1);
normalizeEntityNamespace(a);
a += crepl;
a.trim();
}
restoreTmpTemp(&me);
//piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type;
parent->functions << me;
} else {
tl = fc.split(",");
bool vn = true;
ctemp = tl.front();
for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
}
me.type = ctemp.takeLeft(ts + 1);
me.visibility = cur_def_vis;
restoreTmpTemp(&me);
PIString type = " " + me.type;
if (type.find(" const ") >= 0) {
me.attributes |= Const;
type.replaceAll(" const ", " ");
}
if (type.find(" static ") >= 0) {
me.attributes |= Static;
type.replaceAll(" static ", " ");
}
if (type.find(" mutable ") >= 0) {
me.attributes |= Mutable;
type.replaceAll(" mutable ", " ");
}
if (type.find(" volatile ") >= 0) {
me.attributes |= Volatile;
type.replaceAll(" volatile ", " ");
}
type.trim();
normalizeEntityNamespace(type);
tl[0] = ctemp.trim();
piForeachC (PIString & v, tl) {
crepl.clear();
me.name = v.trimmed();
me.type = type;
if (me.name.isEmpty()) continue;
if (me.name.contains("["))
crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1);
while (!me.name.isEmpty()) {
if (me.name.front() == "*" || me.name.front() == "&") {
me.type += me.name.takeLeft(1);
me.name.trim();
} else break;
}
me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*");
me.type += crepl;
//piCout << "var" << me.type << me.name << me.is_const << me.is_static;
parent->members << me;
}
}
//piCout << "parse member" << fc;
return true;
}
void PICodeParser::normalizeEntityNamespace(PIString & n) {
PIString suff, pref;
for (int i = n.size_s() - 1; i > 0; --i)
if (_isCChar(n[i]) || n[i].isDigit()) {
suff = n.right(n.size_s() - i - 1);
n.cutRight(suff.size_s());
break;
}
n.push_front(" ");
if (n.find(" static ") >= 0) {n.replaceAll(" static ", ""); pref += "static ";}
if (n.find(" const ") >= 0) {n.replaceAll(" const ", ""); pref += "const ";}
if (n.find(" mutable ") >= 0) {n.replaceAll(" mutable ", ""); pref += "mutable ";}
if (n.find(" volatile ") >= 0) {n.replaceAll(" volatile ", ""); pref += "volatile ";}
n.trim();
int f = 0;
piForeachC (Entity * e, entities) {
if (e->name == n) {
n = (pref + n + suff).trim();
return;
}
if ((f = e->name.find(n)) >= 0)
if (e->name.mid(f - 1, 1) == ":")
if (e->name.find(cur_namespace) >= 0) {
n = pref + e->name + suff;
return;
}
}
piForeachC (Enum & e, enums)
if ((f = e.name.find(n)) >= 0)
if (e.name.mid(f - 1, 1) == ":")
if (e.name.find(cur_namespace) >= 0) {
//piCout << "change" << n << "to" << e.name + suff;
n = pref + e.name + suff;
return;
}
piForeachC (Typedef & e, typedefs)
if ((f = e.first.find(n)) >= 0)
if (e.first.mid(f - 1, 1) == ":")
if (e.first.find(cur_namespace) >= 0) {
//piCout << "change" << n << "to" << e.name + suff;
n = pref + e.first + suff;
return;
}
n = (pref + n + suff).trim();
}
void PICodeParser::restoreTmpTemp(Member * e) {
int i = 0;
piForeach (PIString & a, e->arguments_full) {
while ((i = a.find("$")) >= 0)
a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
}
piForeach (PIString & a, e->arguments_type) {
while ((i = a.find("$")) >= 0)
a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
}
while ((i = e->type.find("$")) >= 0)
e->type.replace(i, 4, tmp_temp[e->type.mid(i, 4)]);
}
bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
//piCout << "macroCondition" << mif << mifcond;
if (mif == "ifdef") return isDefineExists(mifcond);
if (mif == "ifndef") return !isDefineExists(mifcond);
if (mif == "if" || mif == "elif") {
mifcond.removeAll(" ").removeAll("\t");
return procMacrosCond(mifcond) > 0.;
}
return false;
}
double PICodeParser::procMacrosCond(PIString fc) {
bool neg = false, first = true, br = false;
double ret = 0., brv = 0.;
int oper = 0, ps = -1;
char cc, nc;
PIString ce;
fc.removeAll("defined");
//piCout << "procMacrosCond" << fc;
while (!fc.isEmpty()) {
cc = fc[0].toAscii();
nc = (fc.size() > 1 ? fc[1].toAscii() : 0);
if (cc == '!') {neg = true; fc.pop_front(); continue;}
if (cc == '(') {br = true; brv = procMacrosCond(fc.takeRange('(', ')'));}
if (cc == '&' && nc == '&') {fc.remove(0, 2); oper = 1; continue;}
if (cc == '|' && nc == '|') {fc.remove(0, 2); oper = 2; continue;}
if (!br) {
ce = fc.takeCWord();
if (ce.isEmpty()) ce = fc.takeNumber();
}
if (first) {
first = false;
ret = br ? brv : defineValue(ce);
if (neg) ret = -ret;
} else {
//piCout << "oper" << oper << "with" << ce;
if (!br) brv = defineValue(ce);
switch (oper) {
case 1: ret = ret && (neg ? -brv : brv); break;
case 2: ret = ret || (neg ? -brv : brv); break;
}
}
if (ps == fc.size_s()) fc.cutLeft(1);
ps = fc.size_s();
br = neg = false;
}
//piCout << "return" << ret;
return ret;
}
bool PICodeParser::isDefineExists(const PIString & dn) {
piForeachC (Define & d, defines) {
if (d.first == dn)
return true;
}
return false;
}
double PICodeParser::defineValue(const PIString & dn) {
piForeachC (Define & d, defines) {
if (d.first == dn)
return d.second.isEmpty() ? 1. : d.second.toDouble();
}
return dn.toDouble();
}
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
piForeach (Entity * e, entities)
if (e->name == en)
return e;
return 0;
}
bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
int dind = fc.find("{", start), find = fc.find(";", start);
//piCout << "isDeclaration" << dind << find;
if (dind < 0 && find < 0) {if (end) *end = -1; return true;}
if (dind < 0 || find < dind) {if (end) *end = find; return true;}
if (end) *end = dind;
return false;
}
PIString PICodeParser::procMacros(PIString fc) {
if (fc.isEmpty()) return PIString();
int ifcnt = 0;
bool grab = false, skip = false, cond_ok = false;
PIString pfc, nfc, line, mif, mifcond;
//piCout << "procMacros\n<******" << fc << "\n******>";
fc += "\n";
while (!fc.isEmpty()) {
line = fc.takeLine().trimmed();
if (line.left(1) == "#") {
mifcond = line.mid(1);
mif = mifcond.takeCWord();
//piCout << "mif mifcond" << mif << mifcond << ifcnt;
if (skip || grab) {
if (mif.left(2) == "if") ifcnt++;
if (mif.left(5) == "endif") {
if (ifcnt > 0) ifcnt--;
else {
//piCout << "main endif" << skip << grab;
if (grab) pfc << procMacros(nfc);
skip = grab = false;
continue;
}
}
if (mif.left(4) == "elif" && ifcnt == 0) {
//piCout << "main elif" << skip << grab << cond_ok;
if (cond_ok) {
if (grab) {
pfc << procMacros(nfc);
skip = true; grab = false;
}
continue;
}
if (skip) {
//piCout << "check elif" << skip << grab << cond_ok;
if (!macroCondition(mif, mifcond.trimmed())) continue;
//piCout << "check elif ok";
skip = false; grab = cond_ok = true;
continue;
}
continue;
}
if (mif.left(4) == "else" && ifcnt == 0) {
//piCout << "main else" << skip << grab;
if (grab) pfc << procMacros(nfc);
if (skip && !cond_ok) {skip = false; grab = true;}
else {skip = true; grab = false;}
continue;
}
if (grab) nfc << line << "\n";
continue;
}
if (mif.left(2) == "if") {
//piCout << "main if";
skip = grab = cond_ok = false;
if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
else skip = true;
ifcnt = 0;
nfc.clear();
} else {
if (!parseDirective(line.cutLeft(1).trim()))
;//return false; /// WARNING
}
} else {
if (grab) nfc << line << "\n";
else if (!skip) pfc << line << "\n";
}
}
return pfc;
}
bool PICodeParser::parseDirective(PIString d) {
if (d.isEmpty()) return true;
PIString dname = d.takeCWord();
//piCout << "parseDirective" << d;
if (dname == "include") {
d.replaceAll("<", "\"").replaceAll(">", "\"");
PIString cf = cur_file;
bool ret = parseFileInternal(d.takeRange("\"", "\""));
cur_file = cf;
return ret;
}
if (dname == "define") {
PIString mname = d.takeCWord();
if (d.left(1) == "(") { // macro
PIStringList args = d.takeRange("(", ")").split(",").trim();
macros << Macro(mname, d.trim(), args);
} else { // define
defines << Define(mname, d.trim());
evaluator.setVariable(mname, complexd_1);
}
return true;
}
if (dname == "undef") {
PIString mname = d.takeCWord();
for (int i = 0; i < defines.size_s(); ++i)
if (defines[i].first == mname) {defines.remove(i); --i;}
return true;
}
return true;
}

148
picodeparser.h Normal file
View File

@@ -0,0 +1,148 @@
/*! \file picodeparser.h
* \brief C++ code parser
*/
/*
PIP - Platform Independent Primitives
C++ code parser
Copyright (C) 2014 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 PICODEPARSER_H
#define PICODEPARSER_H
#include "pifile.h"
#include "pievaluator.h"
inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c.toAscii() == '_'));}
inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
class PIP_EXPORT PICodeParser {
public:
PICodeParser();
enum PIP_EXPORT Visibility {Global, Public, Protected, Private};
enum PIP_EXPORT Attribute {NoAttributes = 0x0, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
typedef PIFlags<Attribute> Attributes;
typedef PIPair<PIString, PIString> Define;
typedef PIPair<PIString, PIString> Typedef;
typedef PIPair<PIString, int> Enumerator;
struct PIP_EXPORT Macro {
Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
name = n;
value = v;
args = a;
}
PIString expand(const PIStringList & arg_vals, bool * ok = 0) const;
PIString name;
PIString value;
PIStringList args;
};
struct PIP_EXPORT Member {
Member() {
visibility = Global;
size = 0;
is_type_ptr = false;
attributes = NoAttributes;
}
PIString type;
PIString name;
PIStringList arguments_full;
PIStringList arguments_type;
Visibility visibility;
Attributes attributes;
bool is_type_ptr;
int size;
};
struct PIP_EXPORT Entity {
Entity() {
visibility = Global;
size = 0;
}
PIString type;
PIString name;
PIString file;
Visibility visibility;
int size;
PIVector<Entity * > parents;
//PIVector<Entity * > children;
PIVector<Member> functions;
PIVector<Member> members;
PIVector<Typedef> typedefs;
};
struct PIP_EXPORT Enum {
Enum(const PIString & n = PIString()) {
name = n;
}
PIString name;
PIVector<Enumerator> members;
};
void parseFile(const PIString & file);
void parseFiles(const PIStringList & files);
void includeDirectory(const PIString & dir) {includes << dir;}
void addDefine(const PIString & def_name, const PIString & def_value) {custom_defines << Define(def_name, def_value);}
bool isEnum(const PIString & name);
Entity * findEntityByName(const PIString & en);
int macrosSubstitutionMaxIterations() const {return macros_iter;}
void setMacrosSubstitutionMaxIterations(int value) {macros_iter = value;}
PIVector<Define> defines, custom_defines;
PIVector<Macro> macros;
PIVector<Enum> enums;
PIVector<Typedef> typedefs;
PIVector<Entity * > entities;
private:
void clear();
bool parseFileInternal(const PIString & file);
bool parseFileContent(PIString & fc);
bool parseDirective(PIString d);
Entity * parseClassDeclaration(const PIString & fc);
PIString parseClass(PIString & fc);
bool parseEnum(const PIString & name, PIString fc);
Typedef parseTypedef(PIString fc);
bool parseMember(Entity * parent, PIString & fc);
void restoreTmpTemp(Member * e);
bool macroCondition(const PIString & mif, PIString mifcond);
bool isDefineExists(const PIString & dn);
double defineValue(const PIString & dn);
PIString procMacros(PIString fc);
double procMacrosCond(PIString fc);
bool isDeclaration(const PIString & fc, int start, int * end);
void normalizeEntityNamespace(PIString & n);
int macros_iter;
PIEvaluator evaluator;
//PIVector<Entity * > tree;
PISet<PIString> proc_files;
PIString cur_file;
PIStringList includes;
Entity root_;
Visibility cur_def_vis;
PIString cur_namespace;
PIMap<PIString, PIString> tmp_temp;
};
#endif // PICODEPARSER_H

View File

@@ -14,14 +14,14 @@
PIStringList PICollection::groups() { PIStringList PICollection::groups() {
PIStringList sl; PIStringList sl;
piForeachC (Group & g, _groups) piForeachC (Group & g, *_groups)
sl << g.name; sl << g.name;
return sl; return sl;
} }
PIVector<const PIObject * > PICollection::groupElements(const PIString & group) { PIVector<const PIObject * > PICollection::groupElements(const PIString & group) {
piForeachC (Group & g, _groups) piForeachC (Group & g, *_groups)
if (g.name == group) if (g.name == group)
return g.elements; return g.elements;
return PIVector<const PIObject * >(); return PIVector<const PIObject * >();
@@ -29,18 +29,21 @@ PIVector<const PIObject * > PICollection::groupElements(const PIString & group)
void PICollection::addToGroup(const PIString & group, const PIObject * element) { void PICollection::addToGroup(const PIString & group, const PIObject * element) {
//piCout << "add to" << group << element;
PIString n = element->className(); PIString n = element->className();
piForeach (Group & g, _groups) piForeach (Group & g, *_groups)
if (g.name == group) { if (g.name == group) {
for (int i = 0; i < g.elements.size_s(); ++i) for (int i = 0; i < g.elements.size_s(); ++i)
if (PIString(g.elements[i]->className()) == n) if (PIString(g.elements[i]->className()) == n)
return; return;
g.elements << element; g.elements << element;
//piCout << "new group" << group << ", ok";
return; return;
} }
_groups << Group(group); *_groups << Group(group);
_groups.back().elements << element; _groups->back().elements << element;
//piCout << "new group" << group << ", ok";
} }
bool __PICollectionInitializer::_inited_(false);
PIVector<PICollection::Group> PICollection::_groups; PIVector<PICollection::Group> * PICollection::_groups;

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Peer - named I/O ethernet node, forming self-organized peering network Peer - named I/O ethernet node, forming self-organized peering network
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -48,8 +48,9 @@
# define ADD_NEW_TO_COLLECTION(group, class) static PICollection::CollectionAdder __##group##_##class##_##adder##__(#group, new class()); # define ADD_NEW_TO_COLLECTION(group, class) static PICollection::CollectionAdder __##group##_##class##_##adder##__(#group, new class());
#endif #endif
class PICollection class PIP_EXPORT PICollection
{ {
friend class __PICollectionInitializer;
public: public:
PICollection() {;} PICollection() {;}
@@ -74,8 +75,20 @@ protected:
PIVector<const PIObject * > elements; PIVector<const PIObject * > elements;
}; };
static PIVector<Group> _groups; static PIVector<Group> * _groups;
}; };
class PIP_EXPORT __PICollectionInitializer {
public:
__PICollectionInitializer() {
if (_inited_) return;
_inited_ = true;
PICollection::_groups = new PIVector<PICollection::Group>();
}
static bool _inited_;
};
static __PICollectionInitializer __picollectioninitializer;
#endif // PICOLLECTION_H #endif // PICOLLECTION_H

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Config parser Config parser
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -83,6 +83,7 @@
* *
*/ */
PIConfig::Entry PIConfig::Branch::_empty; PIConfig::Entry PIConfig::Branch::_empty;
PIConfig::Entry PIConfig::Entry::_empty; PIConfig::Entry PIConfig::Entry::_empty;

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Config parser Config parser
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input Console output/input
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input Console output/input
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Generic containers Generic containers
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Generic containers Generic containers
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -39,6 +39,10 @@ public:
template<typename Type0, typename Type1> template<typename Type0, typename Type1>
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;} inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
template<typename Type0, typename Type1> template<typename Type0, typename Type1>
inline bool operator ==(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return (value0.first == value1.first) && (value0.second == value1.second);}
template<typename Type0, typename Type1>
inline bool operator !=(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return (value0.first != value1.first) || (value0.second != value1.second);}
template<typename Type0, typename Type1>
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;} inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
template<typename Type0, typename Type1> template<typename Type0, typename Type1>
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;} inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
@@ -284,7 +288,7 @@ public:
_CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;} _CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
//! Returns if element "t" exists in this set //! Returns if element "t" exists in this set
bool operator [](const Type & t) {return _stlc::find(t);} bool operator [](const Type & t) {return _stlc::find(t) != _stlc::end();}
//! Returns content of set as PIVector //! Returns content of set as PIVector
PIVector<Type> toVector() {PIVector<Type> 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;}

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Abstract input/output device Abstract input/output device
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

44
pidevicepool.cpp Normal file
View File

@@ -0,0 +1,44 @@
/*
PIP - Platform Independent Primitives
Single collection of devices
Copyright (C) 2014 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 "pidevicepool.h"
/*! \class PIDevicePool
* \brief Single collection of devices
*
* \section PIDevicePool_sec0 Synopsis
*
* \section PIDevicePool_ex0 Example
* \snippet pidevicepool.cpp 0
*/
PIDevicePool::PIDevicePool(): PIObject() {
}
PIDevicePool::~PIDevicePool() {
/*stop();
if (opened_) {
closeDevice();
if (!opened_)
closed();
}*/
}

65
pidevicepool.h Normal file
View File

@@ -0,0 +1,65 @@
/*! \file pidevicepool.h
* \brief Single collection of devices
*/
/*
PIP - Platform Independent Primitives
Single collection of devices
Copyright (C) 2014 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 PIDEVICEPOOL_H
#define PIDEVICEPOOL_H
#include "piiodevice.h"
class PIP_EXPORT PIDevicePool: public PIObject
{
PIOBJECT(PIDevicePool)
public:
PIDevicePool();
~PIDevicePool();
//! \handlers
//! \{
//! \fn bool initialize()
//! \brief Initialize device
//! \}
//! \vhandlers
//! \{
//! \fn void flush()
//! \brief Immediate write all buffers
//! \}
//! \events
//! \{
//! \fn void threadedWriteEvent(ullong id, int written_size)
//! \brief Raise if write thread succesfull write some data of task with ID "id"
//! \}
protected:
private:
};
#endif // PIDEVICEPOOL_H

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Speed and quality in/out diagnostics Speed and quality in/out diagnostics
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Speed and quality in/out diagnostics Speed and quality in/out diagnostics
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Directory Directory
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -165,7 +165,7 @@ PIVector<PIDir::DirEntry> PIDir::entries() {
struct stat fs; struct stat fs;
PIVector<DirEntry> l; PIVector<DirEntry> l;
for (int i = 0; i < cnt; ++i) { for (int i = 0; i < cnt; ++i) {
stat((p + separator + list[i]->d_name).data(), &fs); stat((p + separator + PIString(list[i]->d_name)).data(), &fs);
l.push_back(DirEntry(list[i]->d_name, fs.st_mode, fs.st_size)); l.push_back(DirEntry(list[i]->d_name, fs.st_mode, fs.st_size));
delete list[i]; delete list[i];
} }

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Directory Directory
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ethernet, UDP/TCP Broadcast/Multicast Ethernet, UDP/TCP Broadcast/Multicast
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -45,51 +45,53 @@
* *
* */ * */
REGISTER_DEVICE(PIEthernet);
PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) { PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
piMonitor.ethernets++; piMonitor.ethernets++;
setPriority(piHigh);
type_ = UDP;
ip_ = ip_s = ""; ip_ = ip_s = "";
port_ = port_s = 0; port_ = port_s = 0;
sock = sock_s = -1; sock = sock_s = -1;
connected_ = connecting_ = false; connected_ = connecting_ = false;
params = PIEthernet::ReuseAddress;
server_thread_.setData(this); server_thread_.setData(this);
setThreadedReadBufferSize(65536); setThreadedReadBufferSize(65536);
if (type_ != UDP) init(); setPriority(piHigh);
setType(UDP);
setParameters(PIEthernet::ReuseAddress);
//if (type_ != UDP) init();
} }
PIEthernet::PIEthernet(PIEthernet::Type type, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) { PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) {
piMonitor.ethernets++; piMonitor.ethernets++;
setPriority(piHigh);
type_ = type;
parseAddress(ip_port, &ip_, &port_); parseAddress(ip_port, &ip_, &port_);
ip_s = ""; ip_s = "";
port_s = 0; port_s = 0;
sock = sock_s = -1; sock = sock_s = -1;
connected_ = connecting_ = false; connected_ = connecting_ = false;
params = params_;
server_thread_.setData(this); server_thread_.setData(this);
setThreadedReadBufferSize(65536); setThreadedReadBufferSize(65536);
setPriority(piHigh);
setType(type_);
setParameters(params_);
if (type_ != UDP) init(); if (type_ != UDP) init();
} }
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) { PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
piMonitor.ethernets++; piMonitor.ethernets++;
setPriority(piHigh);
type_ = TCP_Client;
path_ = ip_port;
parseAddress(ip_port, &ip_s, &port_s); parseAddress(ip_port, &ip_s, &port_s);
sock = sock_; sock = sock_;
sock_s = -1; sock_s = -1;
server_thread_.setData(this);
params = PIEthernet::ReuseAddress;
init_ = opened_ = connected_ = true; init_ = opened_ = connected_ = true;
connecting_ = false; connecting_ = false;
server_thread_.setData(this);
setParameters(PIEthernet::ReuseAddress);
setThreadedReadBufferSize(65536); setThreadedReadBufferSize(65536);
setPriority(piHigh);
setType(TCP_Client);
setPath(ip_port);
} }
@@ -114,7 +116,7 @@ bool PIEthernet::init() {
#else #else
int so = 1; int so = 1;
#endif #endif
if (type_ == UDP) { if (type() == UDP) {
st = SOCK_DGRAM; st = SOCK_DGRAM;
pr = IPPROTO_UDP; pr = IPPROTO_UDP;
} else { } else {
@@ -122,7 +124,7 @@ bool PIEthernet::init() {
pr = IPPROTO_TCP; pr = IPPROTO_TCP;
} }
#ifdef WINDOWS #ifdef WINDOWS
if (type_ == UDP) flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF; if (type() == UDP) flags = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF;
sock = WSASocket(AF_INET, st, pr, NULL, 0, flags); sock = WSASocket(AF_INET, st, pr, NULL, 0, flags);
sock_s = WSASocket(AF_INET, st, pr, NULL, 0, WSA_FLAG_OVERLAPPED); sock_s = WSASocket(AF_INET, st, pr, NULL, 0, WSA_FLAG_OVERLAPPED);
#else #else
@@ -133,6 +135,7 @@ bool PIEthernet::init() {
piCoutObj << "Can`t create socket, " << ethErrorString(); piCoutObj << "Can`t create socket, " << ethErrorString();
return false; return false;
} }
PIFlags<Parameters> params = parameters();
#ifndef WINDOWS #ifndef WINDOWS
timeval to; timeval to;
to.tv_sec = 10; to.tv_sec = 10;
@@ -160,14 +163,15 @@ void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
bool PIEthernet::openDevice() { bool PIEthernet::openDevice() {
if (connected_) return true; if (connected_) return true;
init(); init();
if (sock == -1 || path_.isEmpty()) return false; if (sock == -1 || path().isEmpty()) return false;
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
if (type_ != UDP) if (type() != UDP)
return true; return true;
//piCout << "bind to" << (params[PIEthernet::Broadcast] ? "bc" : ip_) << ":" << port_ << " ..."; //piCout << "bind to" << (params[PIEthernet::Broadcast] ? "bc" : ip_) << ":" << port_ << " ...";
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
addr_.sin_family = AF_INET; addr_.sin_family = AF_INET;
addr_.sin_port = htons(port_); addr_.sin_port = htons(port_);
PIFlags<Parameters> params = parameters();
if (params[PIEthernet::Broadcast]) addr_.sin_addr.s_addr = INADDR_ANY; if (params[PIEthernet::Broadcast]) addr_.sin_addr.s_addr = INADDR_ANY;
else addr_.sin_addr.s_addr = inet_addr(ip_.data()); else addr_.sin_addr.s_addr = inet_addr(ip_.data());
#ifdef QNX #ifdef QNX
@@ -218,10 +222,17 @@ void PIEthernet::closeSocket(int & sd) {
} }
void PIEthernet::setParameter(PIEthernet::Parameters parameter, bool on) {
PIFlags<Parameters> cp = (PIFlags<Parameters>)(property("parameters").toInt());
cp.setFlag(parameter, on);
setParameters(cp);
}
bool PIEthernet::joinMulticastGroup(const PIString & group) { bool PIEthernet::joinMulticastGroup(const PIString & group) {
if (sock == -1) init(); if (sock == -1) init();
if (sock == -1) return false; if (sock == -1) return false;
if (type_ != UDP) { if (type() != UDP) {
piCoutObj << "Only UDP sockets can join multicast groups"; piCoutObj << "Only UDP sockets can join multicast groups";
return false; return false;
} }
@@ -229,10 +240,12 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
if (mcast_queue.contains(group)) if (mcast_queue.contains(group))
return false; return false;
mcast_queue.enqueue(group); mcast_queue.enqueue(group);
if (!mcast_groups.contains(group)) mcast_groups << group;
return true; return true;
} }
PIFlags<Parameters> params = parameters();
#ifdef WINDOWS #ifdef WINDOWS
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
addr_.sin_family = AF_INET; addr_.sin_family = AF_INET;
addr_.sin_addr.s_addr = inet_addr(group.data()); addr_.sin_addr.s_addr = inet_addr(group.data());
@@ -243,12 +256,15 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
piCoutObj << "Can`t join multicast group " << group << ", " << ethErrorString(); piCoutObj << "Can`t join multicast group " << group << ", " << ethErrorString();
return false; return false;
} }
if (ret != sock) leafs.insert(group, ret); if (ret != sock) {
leafs.insert(group, ret);
if (!mcast_groups.contains(group)) mcast_groups << group;
}
#else #else
# ifndef QNX # ifndef QNX
if (!params[Broadcast]) if (!params[Broadcast])
piCoutObj << "Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!"; piCoutObj << "Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!";
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
struct ip_mreqn mreq; struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(mreq)); memset(&mreq, 0, sizeof(mreq));
mreq.imr_ifindex = 0; mreq.imr_ifindex = 0;
@@ -267,6 +283,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
piCoutObj << "Can`t join multicast group " << group << ", " << ethErrorString(); piCoutObj << "Can`t join multicast group " << group << ", " << ethErrorString();
return false; return false;
} }
if (!mcast_groups.contains(group)) mcast_groups << group;
# endif # endif
#endif #endif
return true; return true;
@@ -276,19 +293,21 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
bool PIEthernet::leaveMulticastGroup(const PIString & group) { bool PIEthernet::leaveMulticastGroup(const PIString & group) {
if (sock == -1) init(); if (sock == -1) init();
if (sock == -1) return false; if (sock == -1) return false;
if (type_ != UDP) { if (type() != UDP) {
piCoutObj << "Only UDP sockets can leave multicast groups"; piCoutObj << "Only UDP sockets can leave multicast groups";
return false; return false;
} }
PIFlags<Parameters> params = parameters();
#ifdef WINDOWS #ifdef WINDOWS
SOCKET s = leafs[group]; SOCKET s = leafs[group];
if (s != SOCKET()) { if (s != SOCKET()) {
leafs.erase(group); leafs.erase(group);
closesocket(s); closesocket(s);
mcast_groups.removeAll(group);
} }
#else #else
# ifndef QNX # ifndef QNX
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
struct ip_mreqn mreq; struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(mreq)); memset(&mreq, 0, sizeof(mreq));
if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY; if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
@@ -299,6 +318,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
piCoutObj << "Can`t leave multicast group " << group << ", " << ethErrorString(); piCoutObj << "Can`t leave multicast group " << group << ", " << ethErrorString();
return false; return false;
} }
mcast_groups.removeAll(group);
#endif #endif
#endif #endif
return true; return true;
@@ -330,7 +350,7 @@ bool PIEthernet::connect() {
bool PIEthernet::listen() { bool PIEthernet::listen() {
if (sock == -1) init(); if (sock == -1) init();
if (sock == -1) return false; if (sock == -1) return false;
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
addr_.sin_port = htons(port_); addr_.sin_port = htons(port_);
addr_.sin_addr.s_addr = inet_addr(ip_.data()); addr_.sin_addr.s_addr = inet_addr(ip_.data());
@@ -367,7 +387,7 @@ int PIEthernet::read(void * read_to, int max_size) {
sockaddr_in client_addr; sockaddr_in client_addr;
socklen_t slen = sizeof(client_addr); socklen_t slen = sizeof(client_addr);
//piCoutObj << "read from " << ip_ << ":" << port_ << endl; //piCoutObj << "read from " << ip_ << ":" << port_ << endl;
switch (type_) { switch (type()) {
case TCP_SingleTCP: case TCP_SingleTCP:
::listen(sock, 64); ::listen(sock, 64);
s = accept(sock, (sockaddr * )&client_addr, &slen); s = accept(sock, (sockaddr * )&client_addr, &slen);
@@ -382,7 +402,7 @@ int PIEthernet::read(void * read_to, int max_size) {
case TCP_Client: case TCP_Client:
if (connecting_) { if (connecting_) {
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
addr_.sin_port = htons(port_); addr_.sin_port = htons(port_);
addr_.sin_addr.s_addr = inet_addr(ip_.data()); addr_.sin_addr.s_addr = inet_addr(ip_.data());
addr_.sin_family = AF_INET; addr_.sin_family = AF_INET;
@@ -450,7 +470,7 @@ int PIEthernet::write(const void * data, int max_size) {
} }
//piCoutObj << "sending to " << ip_s << ":" << port_s << " " << max_size << " bytes"; //piCoutObj << "sending to " << ip_s << ":" << port_s << " " << max_size << " bytes";
int ret = 0; int ret = 0;
switch (type_) { switch (type()) {
case TCP_SingleTCP: case TCP_SingleTCP:
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
addr_.sin_port = htons(port_s); addr_.sin_port = htons(port_s);
@@ -486,7 +506,7 @@ int PIEthernet::write(const void * data, int max_size) {
case TCP_Client: case TCP_Client:
if (connecting_) { if (connecting_) {
memset(&addr_, 0, sizeof(addr_)); memset(&addr_, 0, sizeof(addr_));
parseAddress(path_, &ip_, &port_); parseAddress(path(), &ip_, &port_);
addr_.sin_port = htons(port_); addr_.sin_port = htons(port_);
addr_.sin_addr.s_addr = inet_addr(ip_.data()); addr_.sin_addr.s_addr = inet_addr(ip_.data());
addr_.sin_family = AF_INET; addr_.sin_family = AF_INET;
@@ -517,7 +537,7 @@ void PIEthernet::server_func(void * eth) {
socklen_t slen = sizeof(client_addr); socklen_t slen = sizeof(client_addr);
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen); int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
if (s == -1) { if (s == -1) {
if (ce->debug_) piCout << "[PIEthernet] Can`t accept new connection, " << ethErrorString(); if (ce->debug()) piCout << "[PIEthernet] Can`t accept new connection, " << ethErrorString();
return; return;
} }
PIString ip(inet_ntoa(client_addr.sin_addr)); PIString ip(inet_ntoa(client_addr.sin_addr));
@@ -543,6 +563,27 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
} }
void PIEthernet::configureFromFullPath(const PIString & full_path) {
PIStringList pl = full_path.split(":");
bool mcast = false;
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0:
p = p.toLowerCase();
if (p == "udp") setType(UDP);
if (p == "tcp") setType(TCP_Client);
break;
case 1: setReadIP(p); break;
case 2: setReadPort(p.toInt()); break;
}
if (i <= 2) continue;
if (i % 2 == 1) {if (p.toLowerCase() == "mcast") mcast = true;}
else {if (mcast) {joinMulticastGroup(p); mcast = false;}}
}
}
PIEthernet::InterfaceList PIEthernet::interfaces() { PIEthernet::InterfaceList PIEthernet::interfaces() {
PIEthernet::InterfaceList il; PIEthernet::InterfaceList il;
Interface ci; Interface ci;

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ethernet, UDP/TCP Broadcast/Multicast Ethernet, UDP/TCP Broadcast/Multicast
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
class PIP_EXPORT PIEthernet: public PIIODevice class PIP_EXPORT PIEthernet: public PIIODevice
{ {
PIOBJECT(PIEthernet) PIIODEVICE(PIEthernet)
friend class PIPeer; friend class PIPeer;
public: public:
@@ -57,16 +57,16 @@ public:
//! Set read address //! Set read address
void setReadAddress(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);} void setReadAddress(const PIString & ip, int port) {setPath(ip + ":" + PIString::fromNumber(port));}
//! Set read address in format "i.i.i.i:p" //! Set read address in format "i.i.i.i:p"
void setReadAddress(const PIString & ip_port) {path_ = ip_port;} void setReadAddress(const PIString & ip_port) {setPath(ip_port);}
//! Set read IP //! Set read IP
void setReadIP(const PIString & ip) {parseAddress(path_, &ip_, &port_); path_ = ip + ":" + PIString::fromNumber(port_);} void setReadIP(const PIString & ip) {parseAddress(path(), &ip_, &port_); setPath(ip + ":" + PIString::fromNumber(port_));}
//! Set read port //! Set read port
void setReadPort(int port) {parseAddress(path_, &ip_, &port_); path_ = ip_ + ":" + PIString::fromNumber(port);} void setReadPort(int port) {parseAddress(path(), &ip_, &port_); setPath(ip_ + ":" + PIString::fromNumber(port));}
//! Set send address //! Set send address
@@ -83,13 +83,13 @@ public:
//! Returns read address in format "i.i.i.i:p" //! Returns read address in format "i.i.i.i:p"
PIString readAddress() {return path_;} PIString readAddress() {return path();}
//! Returns read IP //! Returns read IP
PIString readIP() {parseAddress(path_, &ip_, &port_); return ip_;} PIString readIP() {parseAddress(path(), &ip_, &port_); return ip_;}
//! Returns read port //! Returns read port
int readPort() {parseAddress(path_, &ip_, &port_); return port_;} int readPort() {parseAddress(path(), &ip_, &port_); return port_;}
//! Returns send address in format "i.i.i.i:p" //! Returns send address in format "i.i.i.i:p"
@@ -103,21 +103,21 @@ public:
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them //! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {params = parameters_;} void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {setProperty("parameters", (int)parameters_);}
//! Set parameter "parameter" to state "on". You should to reopen %PIEthernet to apply this //! Set parameter "parameter" to state "on". You should to reopen %PIEthernet to apply this
void setParameter(PIEthernet::Parameters parameter, bool on = true) {params.setFlag(parameter, on);} void setParameter(PIEthernet::Parameters parameter, bool on = true);
//! Returns if parameter "parameter" is set //! Returns if parameter "parameter" is set
bool isParameterSet(PIEthernet::Parameters parameter) const {return params[parameter];} bool isParameterSet(PIEthernet::Parameters parameter) const {return ((PIFlags<PIEthernet::Parameters>)(property("parameters").toInt()))[parameter];}
//! Returns parameters //! Returns parameters
PIFlags<PIEthernet::Parameters> parameters() const {return params;} PIFlags<PIEthernet::Parameters> parameters() const {return (PIFlags<PIEthernet::Parameters>)(property("parameters").toInt());}
//PIByteArray macAddress() {if (!init_) init(); struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); memcpy(ifr.ifr_name, "eth0", 5); ioctl(sock, SIOCSIFHWADDR, &ifr); return PIByteArray(&ifr.ifr_hwaddr.sa_data, 6);} //PIByteArray macAddress() {if (!init_) init(); struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); memcpy(ifr.ifr_name, "eth0", 5); ioctl(sock, SIOCSIFHWADDR, &ifr); return PIByteArray(&ifr.ifr_hwaddr.sa_data, 6);}
//! Returns %PIEthernet type //! Returns %PIEthernet type
Type type() const {return type_;} Type type() const {return (Type)(property("type").toInt());}
//! Join to multicast group with address "group". Use only for UDP //! Join to multicast group with address "group". Use only for UDP
@@ -126,15 +126,18 @@ public:
//! Leave multicast group with address "group". Use only for UDP //! Leave multicast group with address "group". Use only for UDP
bool leaveMulticastGroup(const PIString & group); bool leaveMulticastGroup(const PIString & group);
//! Returns joined multicast groups. Use only for UDP
const PIStringList & multicastGroups() const {return mcast_groups;}
//! Connect to TCP server with address \a readAddress(). Use only for TCP_Client //! Connect to TCP server with address \a readAddress(). Use only for TCP_Client
bool connect(); bool connect();
//! Connect to TCP server with address "ip":"port". Use only for TCP_Client //! Connect to TCP server with address "ip":"port". Use only for TCP_Client
bool connect(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port); return connect();} bool connect(const PIString & ip, int port) {setPath(ip + ":" + PIString::fromNumber(port)); return connect();}
//! Connect to TCP server with address "ip_port". Use only for TCP_Client //! Connect to TCP server with address "ip_port". Use only for TCP_Client
bool connect(const PIString & ip_port) {path_ = ip_port; return connect();} bool connect(const PIString & ip_port) {setPath(ip_port); return connect();}
//! Returns if %PIEthernet connected to TCP server. Use only for TCP_Client //! Returns if %PIEthernet connected to TCP server. Use only for TCP_Client
bool isConnected() const {return connected_;} bool isConnected() const {return connected_;}
@@ -308,6 +311,8 @@ public:
protected: protected:
PIEthernet(int sock, PIString ip_port); PIEthernet(int sock, PIString ip_port);
PIString fullPathPrefix() const {return "eth";}
void configureFromFullPath(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0); bool configureDevice(const void * e_main, const void * e_parent = 0);
//! Executes when any read function was successful. Default implementation does nothing //! Executes when any read function was successful. Default implementation does nothing
@@ -329,14 +334,14 @@ protected:
PIThread server_thread_; PIThread server_thread_;
PIVector<PIEthernet * > clients_; PIVector<PIEthernet * > clients_;
PIQueue<PIString> mcast_queue; PIQueue<PIString> mcast_queue;
PIStringList mcast_groups;
#ifdef WINDOWS #ifdef WINDOWS
PIMap<PIString, SOCKET> leafs; PIMap<PIString, SOCKET> leafs;
#endif #endif
PIFlags<PIEthernet::Parameters> params;
Type type_;
private: private:
static void server_func(void * eth); static void server_func(void * eth);
void setType(Type t) {setProperty("type", (int)t); if (isOpened()) {closeDevice(); init(); openDevice();}}
static std::string ethErrorString() { static std::string ethErrorString() {
#ifdef WINDOWS #ifdef WINDOWS
@@ -351,4 +356,6 @@ private:
}; };
inline bool operator <(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name < v1.name);}
#endif // PIETHERNET_H #endif // PIETHERNET_H

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Evaluator designed for stream computing Evaluator designed for stream computing
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -158,6 +158,7 @@ PIEvaluatorContent::PIEvaluatorContent() {
addFunction("clamp", 3); // (x,a,b) = x < a ? a : (x > b ? b : x) addFunction("clamp", 3); // (x,a,b) = x < a ? a : (x > b ? b : x)
addFunction("step", 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0) addFunction("step", 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0)
addFunction("mix", 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x') addFunction("mix", 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x')
addFunction("defined", 1);
clearCustomVariables(); clearCustomVariables();
//addVariable("n", 0.); //addVariable("n", 0.);
//addVariable("x1", 123); //addVariable("x1", 123);
@@ -245,6 +246,7 @@ PIEvaluatorTypes::BaseFunctions PIEvaluatorContent::getBaseFunction(const PIStri
if (name == "clamp") return PIEvaluatorTypes::bfClamp; if (name == "clamp") return PIEvaluatorTypes::bfClamp;
if (name == "step") return PIEvaluatorTypes::bfStep; if (name == "step") return PIEvaluatorTypes::bfStep;
if (name == "mix") return PIEvaluatorTypes::bfMix; if (name == "mix") return PIEvaluatorTypes::bfMix;
if (name == "defined") return PIEvaluatorTypes::bfDefined;
return PIEvaluatorTypes::bfUnknown; return PIEvaluatorTypes::bfUnknown;
} }
@@ -1148,6 +1150,9 @@ inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci)
ttmp = value(ci.operators[2]); ttmp = value(ci.operators[2]);
tmpvars[oi].value = stmp.real() * (1. - tmp.real()) + ttmp.real() * tmp.real(); tmpvars[oi].value = stmp.real() * (1. - tmp.real()) + ttmp.real() * tmp.real();
break; break;
case PIEvaluatorTypes::bfDefined:
tmpvars[oi].value = value(ci.operators[0]).real() > 0. ? complexd_1 : complexd_0;
break;
case PIEvaluatorTypes::bfRandom: case PIEvaluatorTypes::bfRandom:
tmp = static_cast<ldouble>(rand()) / RAND_MAX; tmp = static_cast<ldouble>(rand()) / RAND_MAX;
stmp = value(ci.operators[1]) - value(ci.operators[0]); stmp = value(ci.operators[1]) - value(ci.operators[0]);

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Evaluator designed for stream computing Evaluator designed for stream computing
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -26,6 +26,8 @@
#include "pistring.h" #include "pistring.h"
#include "pimath.h" #include "pimath.h"
typedef complexd (*FuncFunc)(void * , int, complexd * );
namespace PIEvaluatorTypes { namespace PIEvaluatorTypes {
static const int operationCount = 14; static const int operationCount = 14;
@@ -42,7 +44,8 @@ namespace PIEvaluatorTypes {
bfIm, bfRe, bfArg, bfLen, bfConj, bfIm, bfRe, bfArg, bfLen, bfConj,
bfRad, bfDeg, bfJ0, bfJ1, bfJN, bfRad, bfDeg, bfJ0, bfJ1, bfJN,
bfY0, bfY1, bfYN, bfMin, bfMax, bfY0, bfY1, bfYN, bfMin, bfMax,
bfClamp, bfStep, bfMix bfClamp, bfStep, bfMix, bfDefined,
bfCustom = 0xFFFF
}; };
struct Instruction { struct Instruction {
@@ -63,10 +66,12 @@ namespace PIEvaluatorTypes {
int var_num; int var_num;
}; };
struct Function { struct Function {
Function() {arguments = 0; type = bfUnknown;} Function() {arguments = 0; type = bfUnknown; handler = 0;}
Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype;} Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype; handler = 0;}
Function(const PIString & name, int args, FuncFunc h) {identifier = name; arguments = args; type = bfCustom; handler = h;}
PIString identifier; PIString identifier;
BaseFunctions type; BaseFunctions type;
FuncFunc handler;
int arguments; int arguments;
}; };
struct Variable { struct Variable {
@@ -83,6 +88,7 @@ namespace PIEvaluatorTypes {
⋀ & ⋀ &
| |
*/ */
class PIP_EXPORT PIEvaluatorContent class PIP_EXPORT PIEvaluatorContent
{ {
friend class PIEvaluator; friend class PIEvaluator;
@@ -92,6 +98,7 @@ public:
void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));} void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));}
void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();} void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();}
void addCustomFunction(const PIString & name, int args_count, FuncFunc func) {functions << PIEvaluatorTypes::Function(name, args_count, func);}
int functionsCount() const {return functions.size();} int functionsCount() const {return functions.size();}
int variablesCount() const {return variables.size();} int variablesCount() const {return variables.size();}
int customVariablesCount() const {return variables.size() - cv_count;} int customVariablesCount() const {return variables.size() - cv_count;}
@@ -119,16 +126,24 @@ private:
}; };
class PIP_EXPORT PIEvaluator class PIP_EXPORT PIEvaluator
{ {
public: public:
//! Constructs an empty evaluator //! Constructs an empty evaluator
PIEvaluator() {correct = false;} PIEvaluator() {correct = false; data_ = 0;}
~PIEvaluator() {;} ~PIEvaluator() {;}
//! Returns custom data
void * data() {return data_;}
//! Set custom data to "_data"
void setData(void * _data) {data_ = _data;}
//! Check mathematical expression and parse it to list of instructions //! Check mathematical expression and parse it to list of instructions
bool check(const PIString & string); bool check(const PIString & string);
@@ -142,7 +157,10 @@ public:
void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);} void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);}
void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;} void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;}
/*
//! Add function "name" with arguments count "args_count" and handler "func". Three arguments will be passed to handler: \a data(), "args_count" and array of input values.
void addFunction(const PIString & name, int args_count, FuncFunc func) {content.addCustomFunction(name, args_count, func);}
*/
//! Evaluate last successfully checked with function \a check() expression and returns result //! Evaluate last successfully checked with function \a check() expression and returns result
complexd evaluate(); complexd evaluate();
@@ -200,6 +218,7 @@ private:
PIString currentString, lastError; PIString currentString, lastError;
complexd out; complexd out;
bool correct; bool correct;
void * data_;
}; };
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);} inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
File File
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -40,12 +40,14 @@
* *
*/ */
REGISTER_DEVICE(PIFile);
bool PIFile::openDevice() { bool PIFile::openDevice() {
close(); close();
if (path_.isEmpty()) return false; if (path().isEmpty()) return false;
//piCout << "fopen " << path_.data() << ": " << strType(mode_).data() << fd; //piCout << "fopen " << path_.data() << ": " << strType(mode_).data() << fd;
fd = fopen(path_.data(), strType(mode_).data()); fd = fopen(path().data(), strType(mode_).data());
opened_ = (fd != 0); opened_ = (fd != 0);
#ifndef WINDOWS #ifndef WINDOWS
if (opened_) fcntl(fileno(fd), F_SETFL, O_NONBLOCK); if (opened_) fcntl(fileno(fd), F_SETFL, O_NONBLOCK);
@@ -144,3 +146,8 @@ bool PIFile::isExists(const PIString & path) {
if (ok) fclose(f); if (ok) fclose(f);
return ok; return ok;
} }
void PIFile::configureFromFullPath(const PIString & full_path) {
setPath(full_path);
}

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
File File
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -28,11 +28,11 @@
class PIP_EXPORT PIFile: public PIIODevice class PIP_EXPORT PIFile: public PIIODevice
{ {
PIOBJECT(PIFile) PIIODEVICE(PIFile)
public: public:
//! Constructs a file with path "path" nad open mode "type" //! Constructs a file with path "path" nad open mode "type"
PIFile(const PIString & path = PIString(), DeviceMode type = ReadWrite): PIIODevice(path, type) {setPrecision(5); openDevice();} PIFile(const PIString & path = PIString(), DeviceMode mode = ReadWrite): PIIODevice(path, mode) {setPrecision(5); if (!path.isEmpty()) openDevice();}
~PIFile() {close();} ~PIFile() {close();}
@@ -69,7 +69,7 @@ public:
//! Set file path to "path" and reopen file if need //! Set file path to "path" and reopen file if need
void setPath(const PIString & path) {path_ = path; if (opened_) openDevice();} void setPath(const PIString & path) {PIIODevice::setPath(path); if (opened_) openDevice();}
//! Returns file size //! Returns file size
llong size(); llong size();
@@ -125,7 +125,7 @@ public:
//! Write to file binary content of "v" //! Write to file binary content of "v"
PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;} PIFile & writeBinary(const double v) {write(&v, sizeof(v)); return *this;}
PIFile & operator =(const PIFile & f) {path_ = f.path_; mode_ = f.mode_; return *this;} PIFile & operator =(const PIFile & f) {PIIODevice::setPath(f.path()); mode_ = f.mode_; return *this;}
//! Write to file text representation of "v" //! Write to file text representation of "v"
PIFile & operator <<(const char v) {if (canWrite() && fd != 0) write(&v, 1); return *this;} PIFile & operator <<(const char v) {if (canWrite() && fd != 0) write(&v, 1); return *this;}
@@ -184,8 +184,8 @@ public:
PIFile & operator >>(double & v) {if (canRead() && fd != 0) ret = fscanf(fd, "%lf", &v); return *this;} PIFile & operator >>(double & v) {if (canRead() && fd != 0) ret = fscanf(fd, "%lf", &v); return *this;}
EVENT_HANDLER(void, clear) {close(); fd = fopen(path_.data(), "w"); if (fd != 0) fclose(fd); fd = 0; opened_ = false; open();} EVENT_HANDLER(void, clear) {close(); fd = fopen(path().data(), "w"); if (fd != 0) fclose(fd); fd = 0; opened_ = false; open();}
EVENT_HANDLER0(void, remove) {close(); std::remove(path_.data());} EVENT_HANDLER0(void, remove) {close(); std::remove(path().data());}
EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);} EVENT_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill); EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill);
@@ -222,6 +222,8 @@ public:
//! \} //! \}
protected: protected:
PIString fullPathPrefix() const {return "file";}
void configureFromFullPath(const PIString & full_path);
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Geometry Geometry
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Global includes Global includes
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -235,7 +235,7 @@ PICout PICout::operator <<(const double v) {space(); std::cout << v; return *thi
PICout PICout::operator <<(const void * v) {space(); std::cout << "0x" << PIString::fromNumber(ullong(v), 16); return *this;} PICout PICout::operator <<(const void * v) {space(); std::cout << "0x" << PIString::fromNumber(ullong(v), 16); return *this;}
PICout PICout::operator <<(const PIObject * v) {space(); std::cout << v->className() << "*(" << "0x" << PIString::fromNumber(ullong(v), 16) << ", \"" << v->name() << "\")"; return *this;} PICout PICout::operator <<(const PIObject * v) {space(); if (v == 0) std::cout << "PIObject*(0x0)"; else std::cout << v->className() << "*(" << "0x" << PIString::fromNumber(ullong(v), 16) << ", \"" << v->name() << "\")"; return *this;}
#undef PINUMERICCOUT #undef PINUMERICCOUT

View File

@@ -7,7 +7,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Global includes Global includes
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
#define PIINCLUDES_H #define PIINCLUDES_H
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision) //! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
#define PIP_VERSION 0x000308 #define PIP_VERSION 0x000400
//! Major value of PIP version //! Major value of PIP version
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16 #define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
@@ -39,7 +39,7 @@
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF #define PIP_VERSION_REVISION PIP_VERSION & 0xFF
//! Suffix of PIP version //! Suffix of PIP version
#define PIP_VERSION_SUFFIX "_beta" #define PIP_VERSION_SUFFIX "_prealpha"
#ifdef DOXYGEN #ifdef DOXYGEN
@@ -84,8 +84,13 @@
#endif #endif
#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__WIN64__) #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# define WINDOWS # define WINDOWS
# define ARCH_BITS_32
#endif
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
# define WINDOWS
# define ARCH_BITS_64
#endif #endif
#if defined(__QNX__) || defined(__QNXNTO__) #if defined(__QNX__) || defined(__QNXNTO__)
# define QNX # define QNX
@@ -112,6 +117,15 @@
# endif # endif
# endif # endif
#endif #endif
#ifndef WINDOWS
# if defined(__LP64__) || defined(_LP64_) || defined(LP64)
# define ARCH_BITS_64
# else
# define ARCH_BITS_32
# endif
#endif
#ifdef __GNUC__ #ifdef __GNUC__
# define CC_GCC # define CC_GCC
# define CC_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__) # define CC_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
@@ -128,8 +142,10 @@
# pragma GCC diagnostic ignored "-Wextra" # pragma GCC diagnostic ignored "-Wextra"
# pragma GCC diagnostic ignored "-Wliteral-suffix" # pragma GCC diagnostic ignored "-Wliteral-suffix"
# endif # endif
# define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define CC_VC # define CC_VC
# pragma warning(disable: 4018)
# pragma warning(disable: 4061) # pragma warning(disable: 4061)
# pragma warning(disable: 4100) # pragma warning(disable: 4100)
# pragma warning(disable: 4239) # pragma warning(disable: 4239)
@@ -144,15 +160,15 @@
# pragma warning(disable: 4820) # pragma warning(disable: 4820)
# pragma warning(disable: 4986) # pragma warning(disable: 4986)
# pragma warning(disable: 4996) # pragma warning(disable: 4996)
# define DEPRECATED
# ifdef ARCH_BITS_32
typedef long ssize_t;
# else
typedef long long ssize_t;
# endif
#else #else
# define CC_OTHER # define CC_OTHER
#endif # define DEPRECATED
#ifdef PIP_DEBUG
# undef NDEBUG
#else
# ifndef NDEBUG
# define NDEBUG
# endif
#endif #endif
#ifdef WINDOWS #ifdef WINDOWS
@@ -164,7 +180,7 @@
#endif #endif
#include "pip_export.h" #include "pip_export.h"
#if defined(DOXYGEN) || defined(CC_GCC) #if defined(DOXYGEN) || defined(CC_GCC) || defined(PICODE)
# undef PIP_EXPORT # undef PIP_EXPORT
# define PIP_EXPORT # define PIP_EXPORT
#endif #endif
@@ -190,6 +206,7 @@
#include <ctime> #include <ctime>
#include <csignal> #include <csignal>
#include <cassert> #include <cassert>
#include <cmath>
//#include <signal.h> //#include <signal.h>
#include <typeinfo> #include <typeinfo>
#include <algorithm> #include <algorithm>
@@ -236,7 +253,7 @@
# endif # endif
#endif #endif
#ifdef ANDROID #ifdef ANDROID
# include "ifaddrs_3rd.h" //# include "ifaddrs_3rd.h"
# define tcdrain(fd) ioctl(fd, TCSBRK, 1) # define tcdrain(fd) ioctl(fd, TCSBRK, 1)
inline int wctomb(char * c, wchar_t w) {*c = ((char * )&w)[0]; return 1;} inline int wctomb(char * c, wchar_t w) {*c = ((char * )&w)[0]; return 1;}
inline int mbtowc(wchar_t * w, const char * c, size_t) {*w = ((wchar_t * )&c)[0]; return 1;} inline int mbtowc(wchar_t * w, const char * c, size_t) {*w = ((wchar_t * )&c)[0]; return 1;}
@@ -259,6 +276,13 @@
#ifdef FREE_BSD #ifdef FREE_BSD
extern char ** environ; extern char ** environ;
#endif #endif
#if defined(DOXYGEN) || defined(PICODE)
# undef PIP_EXPORT
# define PIP_EXPORT
# undef DEPRECATED
# define DEPRECATED
#endif
#include "pimonitor.h" #include "pimonitor.h"
extern PIMonitor piMonitor; extern PIMonitor piMonitor;
@@ -294,12 +318,9 @@ using std::map;
using std::multimap; using std::multimap;
using std::string; using std::string;
#ifndef QNX #ifndef QNX
using std::wstring; using std::wstring;
//# ifndef WINDOWS
//static locale_t currentLocale_t = 0;
//# endif
#else #else
typedef std::basic_string<wchar_t> wstring; typedef std::basic_string<wchar_t> wstring;
#endif #endif
/*! \brief Templated function for swap two values /*! \brief Templated function for swap two values
@@ -458,8 +479,8 @@ template<typename T> inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, size
template<> inline ushort piLetobe(const ushort & v) {return (v << 8) | (v >> 8);} template<> inline ushort piLetobe(const ushort & v) {return (v << 8) | (v >> 8);}
template<> inline uint piLetobe(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} template<> inline uint piLetobe(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
__attribute__((deprecated)) inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);} DEPRECATED inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);}
__attribute__((deprecated)) inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} DEPRECATED inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
#ifdef DOXYGEN #ifdef DOXYGEN
@@ -721,7 +742,7 @@ private:
#else #else
# define piCout if (piDebug) PICout() # define piCout if (piDebug) PICout()
# define piCoutObj if (piDebug && debug_) PICout() << "" << (PIString("[") + className() + " \"" + name() + "\"]") # define piCoutObj if (piDebug && debug()) PICout() << "" << (PIString("[") + className() + " \"" + name() + "\"]")
#endif #endif
class PIObject; class PIObject;
@@ -787,7 +808,7 @@ namespace PICoutManipulators {
BackMagenta /*! Magenta background */ = 0x800000, BackMagenta /*! Magenta background */ = 0x800000,
BackCyan /*! Cyan background */ = 0x1000000, BackCyan /*! Cyan background */ = 0x1000000,
BackWhite /*! White background */ = 0x2000000, BackWhite /*! White background */ = 0x2000000,
Default /*! Default format */ = 0x4000000, Default /*! Default format */ = 0x4000000
}; };
}; };

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Abstract input/output device Abstract input/output device
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@
* PIIODevice have internal buffer for threaded read, and \a threadedRead() function * PIIODevice have internal buffer for threaded read, and \a threadedRead() function
* receive pointer to this buffer in first argument. You can adjust size of this buffer * receive pointer to this buffer in first argument. You can adjust size of this buffer
* by function \a setThreadedReadBufferSize() \n * by function \a setThreadedReadBufferSize() \n
* Default size of this buffer is 4096 bytes * Default size of this buffer is 4096 bytes.
* *
* \section PIIODevice_sec5 Reopen * \section PIIODevice_sec5 Reopen
* When threaded read is begin its call \a open() if device is closed. While threaded * When threaded read is begin its call \a open() if device is closed. While threaded
@@ -70,11 +70,42 @@
* function \a configureDevice(). * function \a configureDevice().
* \n Each ancestor of %PIIODevice reimlements \a configureDevice() function to be able * \n Each ancestor of %PIIODevice reimlements \a configureDevice() function to be able
* to be confured from configuration file. This parameters described at section * to be confured from configuration file. This parameters described at section
* "Configurable parameters" in the class reference. Usage example: * "Configurable parameters" in the class reference. \n Usage example:
* \snippet piiodevice.cpp configure * \snippet piiodevice.cpp configure
* Implement example: * Implementation example:
* \snippet piiodevice.cpp configureDevice * \snippet piiodevice.cpp configureDevice
* *
* \section PIIODevice_sec7 Creating devices by unambiguous string
* There are some virtual functions to describe child class without its declaration.
* \n \a fullPathPrefix() should returns unique prefix of device
* \n \a constructFullPath() should returns full unambiguous string, contains prefix and all device parameters
* \n \a configureFromFullPath() provide configuring device from full unambiguous string without prefix and "://"
* \n Macro PIIODEVICE should be used instead of PIOBJECT
* \n Macro REGISTER_DEVICE should be used after definition of class, i.e. at the last line of *.cpp file
* \n \n If custom I/O device corresponds there rules, it can be returned by function \a createFromFullPath().
* \n Each PIP I/O device has custom unambiguous string description:
* * PIFile: "file://<path>"
* * PIBinaryLog: "binlog://<logDir>[:<filePrefix>][:<defaultID>]"
* * PISerial: "ser://<device>:<speed(50|...|115200)>[:<dataBitsCount(6|7|8)>][:<parity(N|E|O)>][:<stopBits(1|2)>]"
* * PIEthernet: "eth://<type(UDP|TCP)>:<readIP>:<readPort>[:<multicast(mcast:<ip>)>]"
* * PIUSB: "usb://<vid>:<pid>[:<deviceNumber>][:<readEndpointNumber>][:<writeEndpointNumber>]"
* \n \n Examples:
* * PIFile: "file://../text.txt"
* * PIBinaryLog: "binlog://../logs/:mylog_:1"
* * PISerial: "ser:///dev/ttyUSB0:9600:8:N:1", equivalent "ser:///dev/ttyUSB0:9600"
* * PIEthernet: "eth://TCP:127.0.0.1:16666", "eth://UDP:192.168.0.5:16666:mcast:234.0.2.1:mcast:234.0.2.2"
* * PIUSB: "usb://0bb4:0c86:1:1:2"
* \n \n
* So, custom I/O device can be created with next call:
* \code{cpp}
* // creatring devices
* PISerial * ser = (PISerial * )PIIODevice::createFromFullPath("ser://COM1:115200");
* PIEthernet * eth = (PIEthernet * )PIIODevice::createFromFullPath("eth://UDP:127.0.0.1:4001");
* // examine devices
* piCout << ser << ser->properties();
* piCout << eth << eth->properties();
* \endcode
*
* \section PIIODevice_ex0 Example * \section PIIODevice_ex0 Example
* \snippet piiodevice.cpp 0 * \snippet piiodevice.cpp 0
*/ */
@@ -82,38 +113,18 @@
PIIODevice::PIIODevice(): PIThread() { PIIODevice::PIIODevice(): PIThread() {
mode_ = ReadOnly; mode_ = ReadOnly;
opened_ = init_ = thread_started_ = false; _init();
reopen_enabled_ = raise_threaded_read_ = true; setPath(PIString());
reopen_timeout_ = 1000;
ret_func_ = 0;
ret_data_ = 0;
tri = 0;
buffer_tr.resize(4096);
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
CONNECT(void, &write_thread, started, this, write_func);
created();
init();
} }
/*! \brief Constructs a PIIODevice with path and mode /*! \brief Constructs a PIIODevice with path and mode
* \param path path to device * \param path path to device
* \param type mode for open * \param type mode for open */
* \param initNow init or not in constructor */ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIThread() {
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() { mode_ = mode;
path_ = path; _init();
mode_ = type; setPath(path);
opened_ = init_ = thread_started_ = false;
reopen_enabled_ = raise_threaded_read_ = true;
reopen_timeout_ = 1000;
ret_func_ = 0;
ret_data_ = 0;
tri = 0;
buffer_tr.resize(4096);
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
CONNECT(void, &write_thread, started, this, write_func);
created();
if (initNow) init();
} }
@@ -127,6 +138,20 @@ PIIODevice::~PIIODevice() {
} }
void PIIODevice::_init() {
opened_ = init_ = thread_started_ = false;
raise_threaded_read_ = true;
ret_func_ = 0;
ret_data_ = 0;
tri = 0;
setReopenEnabled(true);
setReopenTimeout(1000);
setThreadedReadBufferSize(4096);
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
CONNECT(void, &write_thread, started, this, write_func);
}
void PIIODevice::check_start(void * data, int delim) { void PIIODevice::check_start(void * data, int delim) {
//cout << "check " << tread_started_ << endl; //cout << "check " << tread_started_ << endl;
if (open()) { if (open()) {
@@ -176,7 +201,7 @@ void PIIODevice::begin() {
return; return;
} }
//init(); //init();
if (!timer.isRunning() && reopen_enabled_) timer.start(reopen_timeout_); if (!timer.isRunning() && isReopenEnabled()) timer.start(reopenTimeout());
} }
@@ -206,13 +231,14 @@ PIByteArray PIIODevice::readForTime(double timeout_ms) {
PIByteArray str; PIByteArray str;
if (timeout_ms <= 0.) return str; if (timeout_ms <= 0.) return str;
int ret; int ret;
uchar td[threadedReadBufferSize()]; uchar * td = new uchar[threadedReadBufferSize()];
timer.reset(); timer.reset();
while (timer.elapsed_m() < timeout_ms) { while (timer.elapsed_m() < timeout_ms) {
ret = read(td, threadedReadBufferSize()); ret = read(td, threadedReadBufferSize());
if (ret <= 0) msleep(1); if (ret <= 0) msleep(1);
else str.append(td, ret); else str.append(td, ret);
} }
delete td;
return str; return str;
} }
@@ -237,16 +263,30 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
PIConfig::Entry * ep = 0; PIConfig::Entry * ep = 0;
if (parent_section) ep = em.parent(); if (parent_section) ep = em.parent();
if (ep != 0) { if (ep != 0) {
setReopenEnabled(ep->getValue("reopenEnabled", reopen_enabled_, &ex)); setReopenEnabled(ep->getValue("reopenEnabled", isReopenEnabled(), &ex));
if (!ex) setReopenEnabled(em.getValue("reopenEnabled", reopen_enabled_)); if (!ex) setReopenEnabled(em.getValue("reopenEnabled", isReopenEnabled()));
setReopenTimeout(ep->getValue("reopenTimeout", reopen_timeout_, &ex)); setReopenTimeout(ep->getValue("reopenTimeout", reopenTimeout(), &ex));
if (!ex) setReopenTimeout(em.getValue("reopenTimeout", reopen_timeout_)); if (!ex) setReopenTimeout(em.getValue("reopenTimeout", reopenTimeout()));
setThreadedReadBufferSize(ep->getValue("threadedReadBufferSize", buffer_tr.size_s(), &ex)); setThreadedReadBufferSize(ep->getValue("threadedReadBufferSize", buffer_tr.size_s(), &ex));
if (!ex) setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s())); if (!ex) setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s()));
} else { } else {
setReopenEnabled(em.getValue("reopenEnabled", reopen_enabled_)); setReopenEnabled(em.getValue("reopenEnabled", isReopenEnabled()));
setReopenTimeout(em.getValue("reopenTimeout", reopen_timeout_)); setReopenTimeout(em.getValue("reopenTimeout", reopenTimeout()));
setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s())); setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s()));
} }
return configureDevice(&em, ep); return configureDevice(&em, ep);
} }
PIIODevice * PIIODevice::createFromFullPath(const PIString & full_path) {
PIString prefix = full_path.left(full_path.find(":"));
if (prefix.isEmpty()) return 0;
PIVector<const PIObject * > rd(PICollection::groupElements("__PIIODevices__"));
piForeachC (PIObject * d, rd)
if (prefix == ((const PIIODevice * )d)->fullPathPrefix()) {
PIIODevice * nd = ((const PIIODevice * )d)->copy();
if (nd) nd->configureFromFullPath(full_path.mid(prefix.length() + 3));
return nd;
}
return 0;
}

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Abstract input/output device Abstract input/output device
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -23,12 +23,27 @@
#ifndef PIIODEVICE_H #ifndef PIIODEVICE_H
#define PIIODEVICE_H #define PIIODEVICE_H
#include "picollection.h"
#include "pivariant.h" #include "pivariant.h"
#include "pitimer.h" #include "pitimer.h"
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData // function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
typedef bool (*ReadRetFunc)(void * , uchar * , int ); typedef bool (*ReadRetFunc)(void * , uchar * , int );
#ifdef DOXYGEN
//! \relatesalso PIIODevice \brief Use this macro to enable automatic creation instances of your class with \a createFromFullPath() function
# define REGISTER_DEVICE(class)
//! \relatesalso PIIODevice \brief Use this macro instead of PIOBJECT when describe your own PIIODevice
# define PIIODEVICE(class)
#else
# define REGISTER_DEVICE(class) ADD_NEW_TO_COLLECTION(__PIIODevices__, class)
# define PIIODEVICE(class) PIOBJECT(class) PIIODevice * copy() const {return new class();}
#endif
class PIP_EXPORT PIIODevice: public PIThread class PIP_EXPORT PIIODevice: public PIThread
{ {
@@ -45,17 +60,17 @@ public:
ReadWrite /*! Device can both read and write */ = 0x03 ReadWrite /*! Device can both read and write */ = 0x03
}; };
PIIODevice(const PIString & path, DeviceMode type = ReadWrite, bool initNow = true); PIIODevice(const PIString & path, DeviceMode mode = ReadWrite);
virtual ~PIIODevice(); virtual ~PIIODevice();
//! Current open mode of device //! Current open mode of device
DeviceMode mode() const {return mode_;} DeviceMode mode() const {return mode_;}
//! Current path of device //! Current path of device
PIString path() const {return path_;} PIString path() const {return property("path").toString();}
//! Set path of device //! Set path of device
void setPath(const PIString & path) {path_ = path;} void setPath(const PIString & path) {setProperty("path", path);}
//! Return \b true if mode is ReadOnly or ReadWrite //! Return \b true if mode is ReadOnly or ReadWrite
bool isReadable() const {return (mode_ & ReadOnly);} bool isReadable() const {return (mode_ & ReadOnly);}
@@ -79,17 +94,17 @@ public:
//! Set execution of \a open enabled while threaded read on closed device //! Set execution of \a open enabled while threaded read on closed device
void setReopenEnabled(bool yes = true) {reopen_enabled_ = yes;} void setReopenEnabled(bool yes = true) {setProperty("reopenEnabled", yes);}
//! Set timeout in milliseconds between \a open tryings if reopen is enabled //! Set timeout in milliseconds between \a open tryings if reopen is enabled
void setReopenTimeout(int msecs = 1000) {reopen_timeout_ = msecs;} void setReopenTimeout(int msecs) {setProperty("reopenTimeout", msecs);}
//! Return reopen enable //! Return reopen enable
bool isReopenEnabled() const {return reopen_enabled_;} bool isReopenEnabled() const {return property("reopenEnabled").toBool();}
//! Return reopen timeout //! Return reopen timeout
int reopenTimeout() {return reopen_timeout_;} int reopenTimeout() {return property("reopenTimeout").toInt();}
/** \brief Set "threaded read slot" /** \brief Set "threaded read slot"
@@ -174,10 +189,16 @@ public:
bool configure(const PIString & config_file, const PIString & section, bool parent_section = false); bool configure(const PIString & config_file, const PIString & section, bool parent_section = false);
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromFullPath() and returns it.
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://".
//! See \ref PIIODevice_sec7
static PIIODevice * createFromFullPath(const PIString & full_path);
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(bool, open, const PIString &, _path) {path_ = _path; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER1(bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _type) {path_ = _path; mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _mode) {setPath(_path); mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;} EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;} EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;}
@@ -249,9 +270,6 @@ public:
protected: protected:
//! Function executed from the end of constructor
virtual void created() {;}
//! Function executed before first \a openDevice() or from constructor //! Function executed before first \a openDevice() or from constructor
virtual bool init() {return true;} virtual bool init() {return true;}
@@ -267,20 +285,31 @@ protected:
//! Function executed when thread read some data, default implementation execute external slot "ret_func_" //! 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;} virtual bool threadedRead(uchar * readed, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, readed, size); return true;}
//! Reimplement to construct full unambiguous string prefix. \ref PIIODevice_sec7
virtual PIString fullPathPrefix() const {return PIString();}
//! Reimplement to construct full unambiguous string, describes this device, default returns \a path()
virtual PIString constructFullPath() const {return path();}
//! Reimplement to configure your device with parameters of full unambiguous string. Default implementation does nothing
virtual void configureFromFullPath(const PIString & full_path) {;}
void terminate(); void terminate();
PIString path_;
DeviceMode mode_; DeviceMode mode_;
ReadRetFunc ret_func_; ReadRetFunc ret_func_;
bool init_, opened_, thread_started_, reopen_enabled_, raise_threaded_read_; bool init_, opened_, thread_started_, raise_threaded_read_;
int reopen_timeout_;
void * ret_data_; void * ret_data_;
private: private:
EVENT_HANDLER2(void, check_start, void * , data, int, delim); EVENT_HANDLER2(void, check_start, void * , data, int, delim);
EVENT_HANDLER(void, write_func); EVENT_HANDLER(void, write_func);
virtual PIIODevice * copy() const {return 0;}
void _init();
void begin(); void begin();
void run(); void run();
void end() {terminate();} void end() {terminate();}

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console Keyboard grabber for console
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
* \brief Keyboard console input listener * \brief Keyboard console input listener
* \details This class provide listening of console keyboard input. * \details This class provide listening of console keyboard input.
* There is two ways to receive pressed key: * There is two ways to receive pressed key:
* * external static functionwith format "void func(char key, void * data)" * * external static functionwith format "void func(char key, void * data_)"
* * event \a keyPressed() * * event \a keyPressed()
* *
* Also there is static variable \a exiting which by default is set to * Also there is static variable \a exiting which by default is set to
@@ -38,7 +38,7 @@
bool PIKbdListener::exiting; bool PIKbdListener::exiting;
PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() { PIKbdListener::PIKbdListener(KBFunc slot, void * _data): PIThread() {
#ifdef WINDOWS #ifdef WINDOWS
hIn = GetStdHandle(STD_INPUT_HANDLE); hIn = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hIn, &smode); GetConsoleMode(hIn, &smode);
@@ -49,7 +49,7 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
#endif #endif
is_active = true; is_active = true;
ret_func = slot; ret_func = slot;
data = data_; data_ = _data;
PIKbdListener::exiting = exit_enabled = false; PIKbdListener::exiting = exit_enabled = false;
start(); start();
} }
@@ -134,8 +134,8 @@ void PIKbdListener::run() {
return; return;
} }
if (ret > 0) { if (ret > 0) {
keyPressed(lc, data); keyPressed(lc, data_);
if (ret_func != 0) ret_func(lc, data); if (ret_func != 0) ret_func(lc, data_);
} }
} }

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console Keyboard grabber for console
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -56,8 +56,11 @@ public:
~PIKbdListener() {terminate(); end();} ~PIKbdListener() {terminate(); end();}
//! Set custom data to "data" //! Returns custom data
void setData(void * data_) {data = data_;} void * data() {return data_;}
//! Set custom data to "_data"
void setData(void * _data) {data_ = _data;}
//! Set external function to "slot" //! Set external function to "slot"
void setSlot(KBFunc slot) {ret_func = slot;} void setSlot(KBFunc slot) {ret_func = slot;}
@@ -111,7 +114,7 @@ private:
KBFunc ret_func; KBFunc ret_func;
char exit_key; char exit_key;
bool exit_enabled, is_active; bool exit_enabled, is_active;
void * data; void * data_;
#ifdef WINDOWS #ifdef WINDOWS
DWORD ret, rc; DWORD ret, rc;
void * hIn; void * hIn;

13
pimap.h
View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Dynamic array of any type Dynamic array of any type
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -302,9 +302,14 @@ public:
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;} _CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;} _CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();} Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;} PIVector<Key> keys() const {
Type & at(const Key & key_) {return value(key_);} PIVector<Key> ret;
Type value(const Key & key_) const {return _stlc::find(key_)->second;} for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
ret << i->first;
return ret;
}
Type & at(const Key & key_) {return _stlc::find(key_)->second;}
Type value(const Key & key_) const {typename _stlc::const_iterator it = _stlc::find(key_); if (it != _stlc::end()) return it->second; return Type();}
}; };

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Math Math
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Math Math
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Counter of some PIP types Counter of some PIP types
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Counter of some PIP types Counter of some PIP types
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Multiprotocol Multiprotocol
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Mutex Mutex
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Mutex Mutex
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -55,6 +55,14 @@ handler A: event to event
*/ */
PIObject::PIObject(const PIString & name) {
piMonitor.objects++;
setName(name);
setDebug(true);
objects << this;
}
void PIObject::piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h) { void PIObject::piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h) {
PIObject * o = findByName(src); PIObject * o = findByName(src);
if (o == 0) { if (o == 0) {

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -227,26 +227,26 @@ class PIP_EXPORT PIObject
public: public:
//! Contructs PIObject with name "name" //! Contructs PIObject with name "name"
PIObject(const PIString & name = PIString()) {piMonitor.objects++; setName(name); objects << this; debug_ = true;} PIObject(const PIString & name = PIString());
virtual ~PIObject() {piMonitor.objects--; objects.removeAll(this);} virtual ~PIObject() {piMonitor.objects--; objects.removeAll(this);}
//! Returns object name //! Returns object name
const PIString & name() const {return name_;} PIString name() const {return property("name").toString();}
//! Returns object class name //! Returns object class name
virtual const char * className() const {return "PIObject";} virtual const char * className() const {return "PIObject";}
//! Return if debug of this object is active //! Return if debug of this object is active
bool debug() const {return debug_;} bool debug() const {return property("debug").toBool();}
//! Set object name //! Set object name
void setName(const PIString & name) {name_ = name;} void setName(const PIString & name) {setProperty("name", name);}
//! Set object debug active //! Set object debug active
void setDebug(bool debug) {debug_ = debug;} void setDebug(bool debug) {setProperty("debug", debug);}
//! Returns properties of the object //! Returns properties of the object
const PIMap<PIString, PIVariant> & properties() const {return properties_;} const PIMap<PIString, PIVariant> & properties() const {return properties_;}
@@ -255,13 +255,13 @@ public:
int propertiesCount() const {return properties_.size_s();} int propertiesCount() const {return properties_.size_s();}
//! Returns property with name "name" //! Returns property with name "name"
PIVariant property(const PIString & name) {if (!properties_.contains(name)) return PIVariant(); return properties_.value(name);} PIVariant property(const PIString & name) const {if (!properties_.contains(name)) return PIVariant(); return properties_.value(name);}
//! Set property with name "name" to "value". If there is no such property in object it will be added //! Set property with name "name" to "value". If there is no such property in object it will be added
void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value;} void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value;}
//! Returns if property with name "name" exists //! Returns if property with name "name" exists
bool isPropertyExists(const PIString & name) {return properties_.contains(name);} bool isPropertyExists(const PIString & name) const {return properties_.contains(name);}
/* /*
PIStringList events(); PIStringList events();
@@ -476,9 +476,16 @@ public:
raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3); raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3);
} }
//! Returns PIObject* with name "name" or 0, if there is no objects found
static PIObject * findByName(const PIString & name) {
piForeach (PIObject * i, PIObject::objects) {
if (i->name() != name) continue;
return i;
}
return 0;
};
protected: protected:
PIString name_;
bool debug_;
private: private:
struct Connection { struct Connection {
@@ -493,13 +500,6 @@ private:
PIMap<PIString, PIVariant> properties_; PIMap<PIString, PIVariant> properties_;
static PIVector<PIObject * > objects; static PIVector<PIObject * > objects;
static PIObject * findByName(const PIString & name) {
piForeach (PIObject * i, PIObject::objects) {
if (i->name_ != name) continue;
return i;
}
return 0;
};
}; };

4
pip.h
View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
All includes All includes
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -31,4 +31,6 @@
#include "picrc.h" #include "picrc.h"
#include "pistatemachine.h" #include "pistatemachine.h"
#include "picollection.h" #include "picollection.h"
#include "piserial.h"
#include "pibinarylog.h"
#include "piusb.h" #include "piusb.h"

18
pip.pro
View File

@@ -9,11 +9,11 @@ INCLUDEPATH += .
QT -= core gui QT -= core gui
CONFIG -= qt CONFIG -= qt
CONFIG += dll CONFIG += dll
VERSION = 0.3.8 VERSION = 0.4.0
# Input # Input
HEADERS += \ HEADERS += \
pivariable.h \ pivariant.h \
pitimer.h \ pitimer.h \
pithread.h \ pithread.h \
pisystemtests.h \ pisystemtests.h \
@@ -49,10 +49,12 @@ HEADERS += \
pibytearray.h \ pibytearray.h \
pibitarray.h \ pibitarray.h \
picollection.h \ picollection.h \
ifaddrs_3rd.h \ pidiagnostics.h \
pidiagnostics.h pibinarylog.h \
picodeparser.h \
piusb.h
SOURCES += main.cpp \ SOURCES += main.cpp \
pivariable.cpp \ pivariant.cpp \
pitimer.cpp \ pitimer.cpp \
pithread.cpp \ pithread.cpp \
pisystemtests.cpp \ pisystemtests.cpp \
@@ -80,8 +82,10 @@ SOURCES += main.cpp \
picli.cpp \ picli.cpp \
pibytearray.cpp \ pibytearray.cpp \
picollection.cpp \ picollection.cpp \
ifaddrs_3rd.c \ pidiagnostics.cpp \
pidiagnostics.cpp pibinarylog.cpp \
picodeparser.cpp \
piusb.cpp
win32 { win32 {
LIBS += -lws2_32 -lIphlpapi LIBS += -lws2_32 -lIphlpapi
} else { } else {

View File

@@ -1,38 +0,0 @@
# if defined(UNDER_CE)
# include <winbase.h>
# else
# include <winver.h>
# endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,8,0
PRODUCTVERSION 0,3,8,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "\0"
VALUE "FileVersion", "0.3.8.0\0"
VALUE "LegalCopyright", "\0"
VALUE "OriginalFilename", "pip0.dll\0"
VALUE "ProductName", "pip\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/* End of Version info */

View File

@@ -5,8 +5,8 @@
# endif # endif
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,8,0 FILEVERSION 0,4,0,0
PRODUCTVERSION 0,3,8,0 PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L FILEFLAGS 0x0L
FILEOS VOS__WINDOWS32 FILEOS VOS__WINDOWS32
@@ -19,7 +19,7 @@ VS_VERSION_INFO VERSIONINFO
BEGIN BEGIN
VALUE "CompanyName", "Peri4\0" VALUE "CompanyName", "Peri4\0"
VALUE "FileDescription", "Platform-Independent Primitives\0" VALUE "FileDescription", "Platform-Independent Primitives\0"
VALUE "FileVersion", "0.3.8_alpha\0" VALUE "FileVersion", "0.4.0_prealpha\0"
VALUE "LegalCopyright", "\0" VALUE "LegalCopyright", "\0"
VALUE "OriginalFilename", "libpip.dll\0" VALUE "OriginalFilename", "libpip.dll\0"
VALUE "ProductName", "PIP\0" VALUE "ProductName", "PIP\0"

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Packets extractor Packets extractor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -57,6 +57,8 @@
* *
* */ * */
REGISTER_DEVICE(PIPacketExtractor);
PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) { PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) {
ret_func_header = 0; ret_func_header = 0;

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Packets extractor Packets extractor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
class PIP_EXPORT PIPacketExtractor: public PIIODevice class PIP_EXPORT PIPacketExtractor: public PIIODevice
{ {
PIOBJECT(PIPacketExtractor) PIIODEVICE(PIPacketExtractor)
public: public:
//! Contructs extractor with child device "device_", header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize" //! Contructs extractor with child device "device_", header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize"
@@ -106,6 +106,7 @@ protected:
private: private:
bool threadedRead(uchar * readed, int size); bool threadedRead(uchar * readed, int size);
PIString fullPathPrefix() const {return "pckext";}
bool openDevice() {if (dev == 0) return false; return dev->open();} bool openDevice() {if (dev == 0) return false; return dev->open();}
PIIODevice * dev; PIIODevice * dev;

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Peer - named I/O ethernet node Peer - named I/O ethernet node
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -24,9 +24,9 @@
#define _PIPEER_IP_MULTICAST "230.13.3.12" #define _PIPEER_IP_MULTICAST "230.13.3.12"
#define _PIPEER_MSG_SIZE 8192 #define _PIPEER_MSG_SIZE 8192
PIPeer::PIPeer(const PIString & name): PIObject() { PIPeer::PIPeer(const PIString & name_): PIObject() {
rec_mc = rec_bc = false; rec_mc = rec_bc = false;
setName(name); setName(name_);
self_info.name = name_; self_info.name = name_;
self_info.dist = 0; self_info.dist = 0;
eth_send = 0; eth_send = 0;
@@ -272,7 +272,7 @@ bool PIPeer::multicastRead(uchar * data, int size) {
PIVector<PeerInfo> rpeers; PIVector<PeerInfo> rpeers;
ba >> pi.name; ba >> pi.name;
//piCout << "read type" << type << "from" << pi.name; //piCout << "read type" << type << "from" << pi.name;
if (pi.name == name_) return true; if (pi.name == name()) return true;
PIMutexLocker locker(mc_mutex); PIMutexLocker locker(mc_mutex);
diag_s.received(size); diag_s.received(size);
//piCout << "analyz ..."; //piCout << "analyz ...";
@@ -319,7 +319,7 @@ bool PIPeer::multicastRead(uchar * data, int size) {
for (uint i = 0; i < rpeers.size(); ++i) { for (uint i = 0; i < rpeers.size(); ++i) {
PeerInfo & rpeer(rpeers[i]); PeerInfo & rpeer(rpeers[i]);
//piCout << " to sync " << rpeer.name; //piCout << " to sync " << rpeer.name;
if (rpeer.name == name_) continue; if (rpeer.name == name()) continue;
bool exist = false; bool exist = false;
for (uint j = 0; j < peers.size(); ++j) { for (uint j = 0; j < peers.size(); ++j) {
PeerInfo & peer(peers[j]); PeerInfo & peer(peers[j]);

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Peer - named I/O ethernet node, forming self-organized peering network Peer - named I/O ethernet node, forming self-organized peering network
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -99,7 +99,7 @@ public:
PIDiagnostics & diagnosticService() {return diag_s;} PIDiagnostics & diagnosticService() {return diag_s;}
PIDiagnostics & diagnosticData() {return diag_d;} PIDiagnostics & diagnosticData() {return diag_d;}
const PIVector<PeerInfo> & allPeers() const {return peers;} const PIVector<PIPeer::PeerInfo> & allPeers() const {return peers;}
bool isPeerExists(const PIString & name) const {return getPeerByName(name) != 0;} bool isPeerExists(const PIString & name) const {return getPeerByName(name) != 0;}
const PeerInfo * getPeerByName(const PIString & name) const {piForeachC (PeerInfo & i, peers) if (i.name == name) return &i; return 0;} const PeerInfo * getPeerByName(const PIString & name) const {piForeachC (PeerInfo & i, peers) if (i.name == name) return &i; return 0;}
@@ -128,7 +128,7 @@ private:
void sendPeerInfo(const PeerInfo & info); void sendPeerInfo(const PeerInfo & info);
void sendPeerRemove(const PIString & peer); void sendPeerRemove(const PIString & peer);
void sendSelfInfo() {sendPeerInfo(self_info);} void sendSelfInfo() {sendPeerInfo(self_info);}
void sendSelfRemove() {sendPeerRemove(name_);} void sendSelfRemove() {sendPeerRemove(name());}
void syncPeers(); void syncPeers();
void findNearestAddresses(); void findNearestAddresses();
void initEths(const PIStringList & al); void initEths(const PIStringList & al);

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process Process
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process Process
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP) Protocol, input/output channel (COM, UDP)
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -187,7 +187,7 @@ void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PI
if (sendDataSize_ == 0) if (sendDataSize_ == 0)
piCoutObj << "Warning: null send data size!";*/ piCoutObj << "Warning: null send data size!";*/
} else { } else {
piCoutObj << "Can`t find \"" << name_ << ".sender.port\" or \"" << name_ << ".port\" in \"" << config << "\"!"; piCoutObj << "Can`t find \"" << name() << ".sender.port\" or \"" << name() << ".port\" in \"" << config << "\"!";
devSenderState = "Config error"; devSenderState = "Config error";
return; return;
} }
@@ -233,7 +233,7 @@ void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PI
pp.setFlag(PISerial::TwoStopBits, flag); pp.setFlag(PISerial::TwoStopBits, flag);
} }
} else { } else {
piCoutObj << "Can`t find \"" << name_ << ".sender.speed\" or \"" << name_ << ".speed\" in \"" << config << "\"!"; piCoutObj << "Can`t find \"" << name() << ".sender.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!";
devSenderState = "Config error"; devSenderState = "Config error";
return; return;
} }
@@ -346,7 +346,7 @@ void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const
if (recDataSize == 0) if (recDataSize == 0)
piCoutObj << "Warning: null receive data size!";*/ piCoutObj << "Warning: null receive data size!";*/
} else { } else {
piCoutObj << "Can`t find \"" << name_ << ".receiver.port\" or \"" << name_ << ".port\" in \"" << config << "\"!"; piCoutObj << "Can`t find \"" << name() << ".receiver.port\" or \"" << name() << ".port\" in \"" << config << "\"!";
devReceiverState = "Config error"; devReceiverState = "Config error";
return; return;
} }
@@ -416,7 +416,7 @@ void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const
if (recDataSize == 0) if (recDataSize == 0)
piCoutObj << "Warning: null receive data size!";*/ piCoutObj << "Warning: null receive data size!";*/
} else { } else {
piCoutObj << "Can`t find \"" << name_ << ".receiver.speed\" or \"" << name_ << ".speed\" in \"" << config << "\"!"; piCoutObj << "Can`t find \"" << name() << ".receiver.speed\" or \"" << name() << ".speed\" in \"" << config << "\"!";
devReceiverState = "Config error"; devReceiverState = "Config error";
return; return;
} }

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP) Protocol, input/output channel (COM, UDP)
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Queue container Queue container
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
COM COM
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -32,39 +32,19 @@
* *
*/ */
REGISTER_DEVICE(PISerial);
PISerial::PISerial(): PIIODevice("", ReadWrite) { PISerial::PISerial(): PIIODevice("", ReadWrite) {
piMonitor.serials++; _init();
setPriority(piHigh);
fd = -1;
block_read = true;
params = 0;
ispeed = ospeed = S115200;
vtime = 1;
#ifdef WINDOWS
block_write = true;
hCom = 0;
#endif
dbits = 8;
init();
} }
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_): PIIODevice(device_, ReadWrite) { PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_): PIIODevice(device_, ReadWrite) {
piMonitor.serials++; _init();
setPriority(piHigh); setPath(device_);
path_ = device_; setSpeed(speed_);
fd = -1; setParameters(params_);
block_read = true;
params = params_;
ispeed = ospeed = speed_;
vtime = 1;
#ifdef WINDOWS
block_write = true;
hCom = 0;
#endif
dbits = 8;
init();
} }
@@ -73,6 +53,36 @@ PISerial::~PISerial() {
} }
void PISerial::_init() {
fd = -1;
piMonitor.serials++;
setPriority(piHigh);
block_read = true;
vtime = 1;
#ifdef WINDOWS
block_write = true;
hCom = 0;
#endif
setParameters(0);
setSpeed(S115200);
setDataBitsCount(8);
//init();
}
void PISerial::setParameter(PISerial::Parameters parameter, bool on) {
PIFlags<Parameters> cp = (PIFlags<Parameters>)(property("parameters").toInt());
cp.setFlag(parameter, on);
setParameters(cp);
}
bool PISerial::isParameterSet(PISerial::Parameters parameter) const {
PIFlags<Parameters> cp = (PIFlags<Parameters>)(property("parameters").toInt());
return cp[parameter];
}
bool PISerial::setPin(int number, bool on) { bool PISerial::setPin(int number, bool on) {
switch (number) { switch (number) {
case 1: return setCAR(on); break; case 1: return setCAR(on); break;
@@ -116,7 +126,7 @@ bool PISerial::isPin(int number) const {
bool PISerial::setBit(int bit, bool on, const PIString & bname) { bool PISerial::setBit(int bit, bool on, const PIString & bname) {
#ifndef WINDOWS #ifndef WINDOWS
if (fd < 0) { if (fd < 0) {
piCoutObj << "setBit" << bname << " error: \"" << path_ << "\" is not opened!"; piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!";
return false; return false;
} }
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) { if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
@@ -134,7 +144,7 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
bool PISerial::isBit(int bit, const PIString & bname) const { bool PISerial::isBit(int bit, const PIString & bname) const {
#ifndef WINDOWS #ifndef WINDOWS
if (fd < 0) { if (fd < 0) {
piCoutObj << "isBit" << bname << " error: \"" << path_ << "\" is not opened!"; piCoutObj << "isBit" << bname << " error: \"" << path() << "\" is not opened!";
return false; return false;
} }
int ret = 0; int ret = 0;
@@ -334,29 +344,31 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
bool PISerial::openDevice() { bool PISerial::openDevice() {
piCout << "ser open" << path();
if (path().isEmpty()) return false;
#ifdef WINDOWS #ifdef WINDOWS
DWORD ds = 0, sm = 0; DWORD ds = 0, sm = 0;
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;} if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;} if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
PIString wp = "//./" + path_; PIString wp = "//./" + path();
hCom = CreateFileA(wp.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); hCom = CreateFileA(wp.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if (hCom == INVALID_HANDLE_VALUE) { if (hCom == INVALID_HANDLE_VALUE) {
piCoutObj << "Unable to open \"" << path_ << "\""; piCoutObj << "Unable to open \"" << path() << "\"";
fd = -1; fd = -1;
return false; return false;
} }
fd = 0; fd = 0;
#else #else
int om = 0; int om = 0;
switch (mode_) { switch (mode()) {
case PIIODevice::ReadOnly: om = O_RDONLY; break; case PIIODevice::ReadOnly: om = O_RDONLY; break;
case PIIODevice::WriteOnly: om = O_WRONLY; break; case PIIODevice::WriteOnly: om = O_WRONLY; break;
case PIIODevice::ReadWrite: om = O_RDWR; break; case PIIODevice::ReadWrite: om = O_RDWR; break;
} }
//cout << "init ser " << path_ << " mode " << om << " param " << params << endl; //cout << "init ser " << path_ << " mode " << om << " param " << params << endl;
fd = ::open(path_.data(), O_NOCTTY | om); fd = ::open(path().data(), O_NOCTTY | om);
if (fd == -1) { if (fd == -1) {
piCoutObj << "Unable to open \"" << path_ << "\""; piCoutObj << "Unable to open \"" << path() << "\"";
return false; return false;
} }
tcgetattr(fd, &desc); tcgetattr(fd, &desc);
@@ -378,24 +390,25 @@ void PISerial::applySettings() {
times.WriteTotalTimeoutConstant = 0; times.WriteTotalTimeoutConstant = 0;
times.WriteTotalTimeoutMultiplier = block_write ? 0 : 1; times.WriteTotalTimeoutMultiplier = block_write ? 0 : 1;
if (SetCommTimeouts(hCom, &times) == -1) if (SetCommTimeouts(hCom, &times) == -1)
piCoutObj << "Unable to set timeouts for \"" << path_ << "\""; piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
GetCommMask(hCom, &mask); GetCommMask(hCom, &mask);
SetCommMask(hCom, EV_RXCHAR); SetCommMask(hCom, EV_RXCHAR);
GetCommState(hCom, &sdesc); GetCommState(hCom, &sdesc);
desc = sdesc; desc = sdesc;
desc.DCBlength = sizeof(desc); desc.DCBlength = sizeof(desc);
desc.BaudRate = convertSpeed(ispeed); desc.BaudRate = convertSpeed(outSpeed());
if (dbits >= 5 && dbits <= 8) if (dataBitsCount() >= 5 && dataBitsCount() <= 8)
desc.ByteSize = dbits; desc.ByteSize = dataBitsCount();
else else
desc.ByteSize = 8; desc.ByteSize = 8;
PIFlags<Parameters> params = parameters();
if (params[PISerial::ParityControl]) { if (params[PISerial::ParityControl]) {
desc.fParity = 1; desc.fParity = 1;
desc.Parity = params[PISerial::ParityOdd] ? 1 : 2; desc.Parity = params[PISerial::ParityOdd] ? 1 : 2;
} }
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT; desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
if (SetCommState(hCom, &desc) == -1) { if (SetCommState(hCom, &desc) == -1) {
piCoutObj << "Unable to set comm state for \"" << path_ << "\""; piCoutObj << "Unable to set comm state for \"" << path() << "\"";
return; return;
} }
#else #else
@@ -404,13 +417,14 @@ void PISerial::applySettings() {
desc.c_oflag = desc.c_lflag = desc.c_cflag = 0; desc.c_oflag = desc.c_lflag = desc.c_cflag = 0;
desc.c_iflag = IGNBRK; desc.c_iflag = IGNBRK;
desc.c_cflag = CLOCAL | HUPCL; desc.c_cflag = CLOCAL | HUPCL;
switch (dbits) { switch (dataBitsCount()) {
case 5: desc.c_cflag |= (CSIZE & CS5); break; case 5: desc.c_cflag |= (CSIZE & CS5); break;
case 6: desc.c_cflag |= (CSIZE & CS6); break; case 6: desc.c_cflag |= (CSIZE & CS6); break;
case 7: desc.c_cflag |= (CSIZE & CS7); break; case 7: desc.c_cflag |= (CSIZE & CS7); break;
case 8: default: desc.c_cflag |= (CSIZE & CS8); break; case 8: default: desc.c_cflag |= (CSIZE & CS8); break;
}; };
if (isReadable()) desc.c_cflag |= CREAD; if (isReadable()) desc.c_cflag |= CREAD;
PIFlags<Parameters> params = parameters();
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB; if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
if (params[PISerial::ParityControl]) { if (params[PISerial::ParityControl]) {
desc.c_iflag |= INPCK; desc.c_iflag |= INPCK;
@@ -420,14 +434,14 @@ void PISerial::applySettings() {
desc.c_cc[VMIN] = 1; desc.c_cc[VMIN] = 1;
desc.c_cc[VTIME] = vtime; desc.c_cc[VTIME] = vtime;
cfsetispeed(&desc, convertSpeed(ispeed)); cfsetispeed(&desc, convertSpeed(inSpeed()));
cfsetospeed(&desc, convertSpeed(ospeed)); cfsetospeed(&desc, convertSpeed(outSpeed()));
tcflush(fd, TCIOFLUSH); tcflush(fd, TCIOFLUSH);
fcntl(fd, F_SETFL, block_read ? 0 : O_NONBLOCK); fcntl(fd, F_SETFL, block_read ? 0 : O_NONBLOCK);
if(tcsetattr(fd, TCSANOW, &desc) < 0) { if(tcsetattr(fd, TCSANOW, &desc) < 0) {
piCoutObj << "Can`t set attributes for \"" << path_ << "\""; piCoutObj << "Can`t set attributes for \"" << path() << "\"";
return; return;
} }
#endif #endif
@@ -496,7 +510,7 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
PIConfig::Entry * em = (PIConfig::Entry * )e_main; PIConfig::Entry * em = (PIConfig::Entry * )e_main;
PIConfig::Entry * ep = (PIConfig::Entry * )e_parent; PIConfig::Entry * ep = (PIConfig::Entry * )e_parent;
setDevice(readDeviceSetting<PIString>("device", device(), em, ep)); setDevice(readDeviceSetting<PIString>("device", device(), em, ep));
setSpeed((PISerial::Speed)(readDeviceSetting<int>("speed", (int)ospeed, em, ep))); setSpeed((PISerial::Speed)(readDeviceSetting<int>("speed", (int)outSpeed(), em, ep)));
setDataBitsCount(readDeviceSetting<int>("dataBitsCount", dataBitsCount(), em, ep)); setDataBitsCount(readDeviceSetting<int>("dataBitsCount", dataBitsCount(), em, ep));
setParameter(PISerial::ParityControl, readDeviceSetting<bool>("parityControl", isParameterSet(PISerial::ParityControl), em, ep)); setParameter(PISerial::ParityControl, readDeviceSetting<bool>("parityControl", isParameterSet(PISerial::ParityControl), em, ep));
setParameter(PISerial::ParityOdd, readDeviceSetting<bool>("parityOdd", isParameterSet(PISerial::ParityOdd), em, ep)); setParameter(PISerial::ParityOdd, readDeviceSetting<bool>("parityOdd", isParameterSet(PISerial::ParityOdd), em, ep));
@@ -505,6 +519,25 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
} }
void PISerial::configureFromFullPath(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0: setPath(p); break;
case 1: setSpeed((Speed)(p.toInt())); break;
case 2: setDataBitsCount(p.toInt()); break;
case 3:
p = p.toLowerCase();
if (p != "n") setParameter(ParityControl);
if (p == "o") setParameter(ParityOdd);
break;
case 4: if (p.toInt() == 2) setParameter(TwoStopBits); break;
}
}
}
PIVector<int> PISerial::availableSpeeds() { PIVector<int> PISerial::availableSpeeds() {
PIVector<int> spds; PIVector<int> spds;
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 << spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
@@ -518,11 +551,11 @@ PIStringList PISerial::availableDevices(bool test) {
PIStringList dl; PIStringList dl;
#ifdef WINDOWS #ifdef WINDOWS
HKEY key = 0; HKEY key = 0;
RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", &key); RegOpenKey(HKEY_LOCAL_MACHINE, (LPCTSTR)"HARDWARE\\DEVICEMAP\\SERIALCOMM", &key);
if (key != 0) { if (key != 0) {
char name[256], data[1024]; char name[256], data[1024];
DWORD name_len = 256, data_len = 1024, type = 0, index = 0; DWORD name_len = 256, data_len = 1024, type = 0, index = 0;
while (RegEnumValue(key, index, name, &name_len, NULL, &type, (uchar * )data, &data_len) == ERROR_SUCCESS) { while (RegEnumValue(key, index, (LPTSTR)name, &name_len, NULL, &type, (uchar * )data, &data_len) == ERROR_SUCCESS) {
dl << PIString(data); dl << PIString(data);
index++; index++;
} }

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
COM COM
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -91,7 +91,9 @@
#endif #endif
class PIP_EXPORT PISerial: public PIIODevice { class PIP_EXPORT PISerial: public PIIODevice
{
PIIODEVICE(PISerial)
public: public:
//! Contructs an empty %PISerial //! Contructs an empty %PISerial
@@ -134,36 +136,36 @@ public:
//! Set both input and output speed to "speed" //! Set both input and output speed to "speed"
void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed; applySettings();} void setSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); setProperty("inSpeed", (int)speed); applySettings();}
//! Set output speed to "speed" //! Set output speed to "speed"
void setOutSpeed(PISerial::Speed speed) {ospeed = speed; applySettings();} void setOutSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); applySettings();}
//! Set input speed to "speed" //! Set input speed to "speed"
void setInSpeed(PISerial::Speed speed) {ispeed = speed; applySettings();} void setInSpeed(PISerial::Speed speed) {setProperty("inSpeed", (int)speed); applySettings();}
//! Set device name to "dev" //! Set device name to "dev"
void setDevice(const PIString & dev) {path_ = dev; if (isOpened()) {close(); open();};} void setDevice(const PIString & dev) {setPath(dev); if (isOpened()) {close(); open();};}
//! Set parameters to "parameters_" //! Set parameters to "parameters_"
void setParameters(PIFlags<PISerial::Parameters> parameters_) {params = parameters_; applySettings();} void setParameters(PIFlags<PISerial::Parameters> parameters_) {setProperty("parameters", (int)parameters_); applySettings();}
//! Set parameter "parameter" to "on" state //! Set parameter "parameter" to "on" state
void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on); applySettings();} void setParameter(PISerial::Parameters parameter, bool on = true);
//! Returns if parameter "parameter" is set //! Returns if parameter "parameter" is set
bool isParameterSet(PISerial::Parameters parameter) const {return params[parameter];} bool isParameterSet(PISerial::Parameters parameter) const;
//! Returns parameters //! Returns parameters
PIFlags<PISerial::Parameters> parameters() const {return params;} PIFlags<PISerial::Parameters> parameters() const {return (PIFlags<Parameters>)(property("parameters").toInt());}
//! Set data bits count. Valid range is from 5 to 8, befault is 8 //! Set data bits count. Valid range is from 5 to 8, befault is 8
void setDataBitsCount(int bits) {dbits = bits; applySettings();} void setDataBitsCount(int bits) {setProperty("dataBitsCount", bits); applySettings();}
//! Returns data bits count //! Returns data bits count
int dataBitsCount() const {return dbits;} int dataBitsCount() const {return property("dataBitsCount").toInt();}
//! Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS) //! Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS)
@@ -200,13 +202,13 @@ public:
//! Returns device name //! Returns device name
const PIString & device() const {return path_;} PIString device() const {return path();}
//! Returns output speed //! Returns output speed
PISerial::Speed outSpeed() const {return ospeed;} PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());}
//! Returns input speed //! Returns input speed
PISerial::Speed inSpeed() const {return ispeed;} PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());}
int VTime() const {return vtime;} int VTime() const {return vtime;}
@@ -271,17 +273,19 @@ public:
//! \} //! \}
protected: protected:
PIString fullPathPrefix() const {return "ser";}
void configureFromFullPath(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0); bool configureDevice(const void * e_main, const void * e_parent = 0);
int write(const void * data, int max_size) {return write(data, max_size, true);} int write(const void * data, int max_size) {return write(data, max_size, true);}
//! Executes when any read function was successful. Default implementation does nothing //! Executes when any read function was successful. Default implementation does nothing
virtual void received(const void * data, int size) {;} virtual void received(const void * data, int size) {;}
void _init();
void applySettings(); void applySettings();
int convertSpeed(PISerial::Speed speed); int convertSpeed(PISerial::Speed speed);
bool setBit(int bit, bool on, const PIString & bname); bool setBit(int bit, bool on, const PIString & bname);
bool isBit(int bit, const PIString & bname) const; bool isBit(int bit, const PIString & bname) const;
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;}
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();
@@ -295,11 +299,9 @@ protected:
termios desc, sdesc; termios desc, sdesc;
uint readed; uint readed;
#endif #endif
int fd, vtime, dbits; int fd, vtime;
bool block_read; bool block_read;
PISerial::Speed ospeed, ispeed;
PITimer timer; PITimer timer;
PIFlags<PISerial::Parameters> params;
}; };

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Signals Signals
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Signals Signals
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Stack container Stack container
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
State machine State machine
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
String String
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -356,6 +356,44 @@ int PIString::findLast(const PIString str, const int start) const {
} }
int PIString::findWord(const PIString & word, const int start) const {
int f = start - 1, tl = length(), wl = word.length();
while ((f = find(word, f + 1)) >= 0) {
bool ok = true;
PIChar c;
if (f > 0) {c = (*this)[f - 1]; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {ok = false; continue;}}
if (f + wl < tl) {c = (*this)[f + wl]; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {ok = false; continue;}}
if (ok) return f;
}
return -1;
}
int PIString::findCWord(const PIString & word, const int start) const {
int f = start - 1, tl = length(), wl = word.length();
while ((f = find(word, f + 1)) >= 0) {
bool ok = true;
PIChar c;
if (f > 0) {c = (*this)[f - 1]; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {ok = false; continue;}}
if (f + wl < tl) {c = (*this)[f + wl]; if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || (c != '_' && !c.isAlpha() && !c.isDigit()))) {ok = false; continue;}}
if (ok) return f;
}
return -1;
}
bool PIString::startsWith(const PIString & str) const {
if (size() < str.size()) return false;
return str == left(str.size());
}
bool PIString::endsWith(const PIString & str) const {
if (size() < str.size()) return false;
return str == right(str.size());
}
PIString PIString::takeSymbol() { PIString PIString::takeSymbol() {
PIString ret; PIString ret;
int sz = size_s(), ss = -1; int sz = size_s(), ss = -1;

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
String String
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ class PIP_EXPORT PIString: public PIVector<PIChar>
{ {
public: public:
//! Contructs an empty string //! Contructs an empty string
PIString(): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--;} PIString(): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--;}
//inline PIString & operator +=(const char c) {push_back(c); return *this;} //inline PIString & operator +=(const char c) {push_back(c); return *this;}
PIString & operator +=(const PIChar & c) {push_back(c); return *this;} PIString & operator +=(const PIChar & c) {push_back(c); return *this;}
@@ -49,63 +49,63 @@ public:
#endif #endif
//PIString(const char c) {*this += c;} //PIString(const char c) {*this += c;}
PIString(const PIString & o): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += o;}
//! Contructs string with single symbol "c" //! Contructs string with single symbol "c"
PIString(const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;} PIString(const PIChar & c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += c;}
PIString(const char c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += PIChar(c);} PIString(const char c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += PIChar(c);}
/*! \brief Contructs string from c-string "str" /*! \brief Contructs string from c-string "str"
* \details "str" should be null-terminated\n * \details "str" should be null-terminated\n
* Example: \snippet pistring.cpp PIString(char * ) */ * Example: \snippet pistring.cpp PIString(char * ) */
PIString(const char * str): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const char * str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
/*! \brief Contructs string from \c wchar_t c-string "str" /*! \brief Contructs string from \c wchar_t c-string "str"
* \details "str" should be null-terminated\n * \details "str" should be null-terminated\n
* Example: \snippet pistring.cpp PIString(wchar_t * ) */ * Example: \snippet pistring.cpp PIString(wchar_t * ) */
PIString(const wchar_t * str): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const wchar_t * str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
//! Contructs string from std::string "str" //! Contructs string from std::string "str"
PIString(const string & str): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const string & str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
#ifdef HAS_LOCALE #ifdef HAS_LOCALE
PIString(const wstring & str): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const wstring & str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
#endif #endif
//! Contructs string from byte array "ba" //! Contructs string from byte array "ba"
PIString(const PIByteArray & ba): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += ba;} PIString(const PIByteArray & ba): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += ba;}
/*! \brief Contructs string from "len" characters of buffer "str" /*! \brief Contructs string from "len" characters of buffer "str"
* \details Example: \snippet pistring.cpp PIString(char * , int) */ * \details Example: \snippet pistring.cpp PIString(char * , int) */
PIString(const char * str, const int len): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += string(str, len);} PIString(const char * str, const int len): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
/*! \brief Contructs string as sequence of characters "c" of buffer with length "len" /*! \brief Contructs string as sequence of characters "c" of buffer with length "len"
* \details Example: \snippet pistring.cpp PIString(int, char) */ * \details Example: \snippet pistring.cpp PIString(int, char) */
PIString(const int len, const char c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);} PIString(const int len, const char c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len" /*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */ * \details Example: \snippet pistring.cpp PIString(int, PIChar) */
PIString(const int len, const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);} PIString(const int len, const PIChar & c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
PIString(const short & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const short & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const ushort & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const ushort & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const int & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const int & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const uint & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const uint & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const long & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const long & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const ulong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const ulong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const llong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const llong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const ullong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const ullong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const float & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const float & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
PIString(const double & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);} PIString(const double & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
/* //~PIString() {piMonitor.strings--; piMonitor.containers++;}
//! Contructs string from other string "str"
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; uint len = str.size(); for (uint i = 0; i < len; ++i) push_back(str[i]);}
*/
~PIString() {piMonitor.strings--; piMonitor.containers++;}
PIString & operator =(const PIString & o) {clear(); *this += o; return *this;}
/*! \brief Return c-string representation of string /*! \brief Return c-string representation of string
* \details Converts content of string to c-string and return * \details Converts content of string to c-string and return
* pointer to first char. This buffer is valid until new convertion * pointer to first char. This buffer is valid until new convertion
@@ -369,6 +369,21 @@ public:
PIString reversed() const {PIString str(*this); str.reverse(); return str;} PIString reversed() const {PIString str(*this); str.reverse(); return str;}
/*! \brief Take a part of string from symbol at index "start" and maximum length "len" and return it
* \details Example: \snippet pistring.cpp PIString::takeMid
* \sa \a takeLeft, \a takeRight() */
PIString takeMid(const int start, const int len = -1) {PIString ret(mid(start, len)); cutMid(start, len); return ret;}
/*! \brief Take a part from the begin of string with maximum length "len" and return it
* \details Example: \snippet pistring.cpp PIString::takeLeft
* \sa \a takeMid(), \a takeRight() */
PIString takeLeft(const int len) {PIString ret(left(len)); cutLeft(len); return ret;}
/*! \brief Take a part from the end of string with maximum length "len" and return it
* \details Example: \snippet pistring.cpp PIString::takeRight
* \sa \a takeMid(), \a takeLeft() */
PIString takeRight(const int len) {PIString ret(right(len)); cutRight(len); return ret;}
/*! \brief Take a symbol from the begin of this string and return it /*! \brief Take a symbol from the begin of this string and return it
* \details Example: \snippet pistring.cpp PIString::takeSymbol * \details Example: \snippet pistring.cpp PIString::takeSymbol
* \sa \a takeWord(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange() */ * \sa \a takeWord(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange() */
@@ -422,7 +437,7 @@ public:
const char * data() const; const char * data() const;
//! \brief Return \c std::string representation of this string //! \brief Return \c std::string representation of this string
const string stdString() const {return convertToStd();} std::string stdString() const {return convertToStd();}
#ifdef HAS_LOCALE #ifdef HAS_LOCALE
wstring stdWString() const {return convertToWString();} wstring stdWString() const {return convertToWString();}
#endif #endif
@@ -479,6 +494,19 @@ public:
//! \details Example: \snippet pistring.cpp PIString::findLast //! \details Example: \snippet pistring.cpp PIString::findLast
int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);} int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);}
//! \brief Search word "word" from symbol at index "start" and return last occur position.
//! \details Example: \snippet pistring.cpp PIString::findWord
int findWord(const PIString & word, const int start = 0) const;
//! \brief Search C-style word "word" from symbol at index "start" and return last occur position.
//! \details Example: \snippet pistring.cpp PIString::findCWord
int findCWord(const PIString & word, const int start = 0) const;
//! \brief Return if string starts with "str"
bool startsWith(const PIString & str) const;
//! \brief Return if string ends with "str"
bool endsWith(const PIString & str) const;
//! \brief Return symbols length of string //! \brief Return symbols length of string
int length() const {return size();} int length() const {return size();}
@@ -640,6 +668,9 @@ public:
//! \details Example: \snippet pistring.cpp PIString::readableSize //! \details Example: \snippet pistring.cpp PIString::readableSize
static PIString readableSize(llong bytes) {PIString s; s.setReadableSize(bytes); return s;} static PIString readableSize(llong bytes) {PIString s; s.setReadableSize(bytes); return s;}
PIString & removeAll(char v) {replaceAll(v, ""); return *this;}
PIString & removeAll(const PIString & v) {replaceAll(v, ""); return *this;}
private: private:
static const char toBaseN[]; static const char toBaseN[];
static const int fromBaseN[]; static const int fromBaseN[];
@@ -699,8 +730,8 @@ private:
if (cs < 0 || cs >= base) break; if (cs < 0 || cs >= base) break;
digits << cs; digits << cs;
} }
piForeachRC (int & i, digits) { for (int i = digits.size_s() - 1; i >= 0; --i) {
ret += i * m; ret += digits[i] * m;
m *= base; m *= base;
} }
if (neg) ret = -ret; if (neg) ret = -ret;
@@ -789,6 +820,8 @@ public:
//! Contructs empty strings list with strings "s0", "s1", "s2" and "s3" //! Contructs empty strings list with strings "s0", "s1", "s2" and "s3"
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);} PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
PIStringList(const PIStringList & o): PIVector<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
//! \brief Join all strings in one with delimiter "delim" and return it //! \brief Join all strings in one with delimiter "delim" and return it
//! \details Example: \snippet pistring.cpp PIStringList::join //! \details Example: \snippet pistring.cpp PIStringList::join
@@ -812,6 +845,8 @@ public:
//! Return sum of lengths of all strings //! Return sum of lengths of all strings
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;} uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
PIStringList & operator =(const PIStringList & o) {clear(); for (uint i = 0; i < o.size(); ++i) *this << o[i]; return *this;}
PIStringList & operator <<(const PIString & str) {push_back(str); return *this;} PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
PIStringList & operator <<(const PIStringList & sl) {piForeachC (PIString & i, sl) push_back(i); return *this;} PIStringList & operator <<(const PIStringList & sl) {piForeachC (PIString & i, sl) push_back(i); return *this;}
//inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;} //inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;}

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process resource monitor Process resource monitor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Process resource monitor Process resource monitor
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
System tests results (see system_test folder) System tests results (see system_test folder)
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
System tests results (see system_test folder) System tests results (see system_test folder)
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Thread Thread
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Thread Thread
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Timer Timer
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Time structs Time structs
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Timer Timer
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Timer Timer
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -9,16 +9,19 @@
# endif # endif
#endif #endif
REGISTER_DEVICE(PIUSB);
PIUSB::PIUSB(ushort vid, ushort pid): PIIODevice("", ReadWrite, false) {
PIUSB::PIUSB(ushort vid, ushort pid): PIIODevice("", ReadWrite) {
vid_ = vid; vid_ = vid;
pid_ = pid; pid_ = pid;
path_ = PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0");
dev_num = 1;
intefrace_ = 0; intefrace_ = 0;
hdev = 0; hdev = 0;
interface_claimed = -1; interface_claimed = -1;
timeout_r = timeout_w = 1000; setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));
setDeviceNumber(1);
setTimeoutRead(1000);
setTimeoutWrite(1000);
} }
@@ -145,9 +148,9 @@ bool PIUSB::configureDevice(const void * e_main, const void * e_parent) {
bool PIUSB::openDevice() { bool PIUSB::openDevice() {
#ifdef PIP_USB #ifdef PIP_USB
if (path_.size_s() >= 8) { if (path().size_s() >= 8) {
vid_ = path_.left(4).toInt(16); vid_ = path().left(4).toInt(16);
pid_ = path_.right(4).toInt(16); pid_ = path().right(4).toInt(16);
} }
if (hdev != 0) closeDevice(); if (hdev != 0) closeDevice();
hdev = 0; hdev = 0;
@@ -172,7 +175,7 @@ bool PIUSB::openDevice() {
for (bus = usb_get_busses(); bus; bus = bus->next) { for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) { for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == vid_ && dev->descriptor.idProduct == pid_) { if (dev->descriptor.idVendor == vid_ && dev->descriptor.idProduct == pid_) {
if (cur_num == dev_num) { if (cur_num == deviceNumber()) {
struct usb_device_descriptor & dd(dev->descriptor); struct usb_device_descriptor & dd(dev->descriptor);
desc_.usb_spec_number = dd.bcdUSB; desc_.usb_spec_number = dd.bcdUSB;
desc_.device_class = dd.bDeviceClass; desc_.device_class = dd.bDeviceClass;
@@ -383,3 +386,18 @@ PICout operator<<(PICout s, const PIUSB::Endpoint & v) {
s.restoreControl(); s.restoreControl();
return s; return s;
} }
void PIUSB::configureFromFullPath(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0: setVendorID(p.toUShort(16)); break;
case 1: setProductID(p.toUShort(16)); break;
case 2: setDeviceNumber(p.toInt()); break;
case 3: setEndpointRead(Endpoint(p.toInt())); break;
case 4: setEndpointWrite(Endpoint(p.toInt())); break;
}
}
}

57
piusb.h
View File

@@ -4,7 +4,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
USB, based on libusb USB, based on libusb
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -27,7 +27,9 @@
struct usb_dev_handle; struct usb_dev_handle;
class PIP_EXPORT PIUSB: public PIIODevice { class PIP_EXPORT PIUSB: public PIIODevice
{
PIIODEVICE(PIUSB)
public: public:
PIUSB(ushort vid = 0, ushort pid = 0); PIUSB(ushort vid = 0, ushort pid = 0);
@@ -58,7 +60,7 @@ public:
ushort class_code; ushort class_code;
ushort subclass_code; ushort subclass_code;
ushort protocol_code; ushort protocol_code;
PIVector<Endpoint> endpoints; PIVector<PIUSB::Endpoint> endpoints;
}; };
struct Configuration { struct Configuration {
@@ -69,7 +71,7 @@ public:
ushort max_power; // mA ushort max_power; // mA
bool self_powered; bool self_powered;
bool remote_wakeup; bool remote_wakeup;
PIVector<Interface> interfaces; PIVector<PIUSB::Interface> interfaces;
}; };
struct Descriptor { struct Descriptor {
@@ -85,37 +87,38 @@ public:
uchar index_manufacturer; uchar index_manufacturer;
uchar index_product; uchar index_product;
uchar index_serial; uchar index_serial;
PIVector<Configuration> configurations; PIVector<PIUSB::Configuration> configurations;
}; };
const Descriptor & currentDescriptor() const {return desc_;} const PIUSB::Descriptor & currentDescriptor() const {return desc_;}
const Configuration & currentConfiguration() const {return conf_;} const PIUSB::Configuration & currentConfiguration() const {return conf_;}
const Interface & currentInterface() const {return iface_;} const PIUSB::Interface & currentInterface() const {return iface_;}
ushort vendorID() const {return vid_;} ushort vendorID() const {return vid_;}
ushort productID() const {return pid_;} ushort productID() const {return pid_;}
int deviceNumber() const {return dev_num;} int deviceNumber() const {return property("deviceNumber").toInt();}
int timeoutRead() const {return property("timeoutRead").toInt();}
int timeoutWrite() const {return property("timeoutWrite").toInt();}
const PIUSB::Endpoint & endpointRead() {return ep_read;}
const PIUSB::Endpoint & endpointWrite() {return ep_write;}
const PIVector<Endpoint> & endpoints() const {return eps;} const PIVector<PIUSB::Endpoint> & endpoints() const {return eps;}
PIVector<Endpoint> endpointsRead(); PIVector<PIUSB::Endpoint> endpointsRead();
PIVector<Endpoint> endpointsWrite(); PIVector<PIUSB::Endpoint> endpointsWrite();
Endpoint getEndpointByAddress(uchar address); PIUSB::Endpoint getEndpointByAddress(uchar address);
const Endpoint & endpointRead() {return ep_read;} void setVendorID(ushort vid) {vid_ = vid; setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));}
const Endpoint & endpointWrite() {return ep_write;} void setProductID(ushort pid) {pid_ = pid; setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));}
void setVendorID(ushort vid) {vid_ = vid; path_ = PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0");}
void setProductID(ushort pid) {pid_ = pid; path_ = PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0");}
bool setConfiguration(uchar value); bool setConfiguration(uchar value);
bool setInterface(uchar value); bool setInterface(uchar value);
void setEndpointRead(const Endpoint & ep) {ep_read = ep;} void setEndpointRead(const PIUSB::Endpoint & ep) {ep_read = ep;}
void setEndpointWrite(const Endpoint & ep) {ep_write = ep;} void setEndpointWrite(const PIUSB::Endpoint & ep) {ep_write = ep;}
void setDeviceNumber(int dn) {dev_num = dn;} void setDeviceNumber(int dn) {setProperty("deviceNumber", dn);}
void setTimeoutRead(int t) {timeout_r = t;} void setTimeoutRead(int t) {setProperty("timeoutRead", t);}
void setTimeoutWrite(int t) {timeout_w = t;} void setTimeoutWrite(int t) {setProperty("timeoutWrite", t);}
int read(void * read_to, int max_size); int read(void * read_to, int max_size);
int write(const void * data, int max_size); int write(const void * data, int max_size);
@@ -124,16 +127,18 @@ public:
void flush(); void flush();
protected: protected:
PIString fullPathPrefix() const {return "usb";}
void configureFromFullPath(const PIString & full_path);
bool configureDevice(const void * e_main, const void * e_parent = 0); bool configureDevice(const void * e_main, const void * e_parent = 0);
//bool init(); //bool init();
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();
PIVector<Endpoint> eps; PIVector<PIUSB::Endpoint> eps;
ushort vid_, pid_; ushort vid_, pid_;
int dev_num, intefrace_, timeout_r, timeout_w; int intefrace_, timeout_r, timeout_w;
int interface_claimed; int interface_claimed;
Endpoint ep_read, ep_write; PIUSB::Endpoint ep_read, ep_write;
Descriptor desc_; Descriptor desc_;
Configuration conf_; Configuration conf_;
Interface iface_; Interface iface_;

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Variant type Variant type
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -33,9 +33,10 @@ void PIVariant::operator =(const PIVariant & v) {
_vbitarray = v._vbitarray; _vbitarray = v._vbitarray;
_vstring = v._vstring; _vstring = v._vstring;
_vstringlist = v._vstringlist; _vstringlist = v._vstringlist;
_vcustom = v._vcustom;
} }
/*
bool PIVariant::operator ==(const PIVariant & v) const { bool PIVariant::operator ==(const PIVariant & v) const {
if (type_ != v.type_) return false; if (type_ != v.type_) return false;
switch (type_) { switch (type_) {
@@ -67,7 +68,7 @@ bool PIVariant::operator ==(const PIVariant & v) const {
}; };
return false; return false;
} }
*/
PIVariant::Type PIVariant::typeFromName(const PIString & tname) { PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", ""); PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
@@ -126,6 +127,7 @@ PIString PIVariant::typeName(PIVariant::Type type) {
case PIVariant::Date: return "Date"; case PIVariant::Date: return "Date";
case PIVariant::DateTime: return "DateTime"; case PIVariant::DateTime: return "DateTime";
case PIVariant::SystemTime: return "SystemTime"; case PIVariant::SystemTime: return "SystemTime";
case PIVariant::Custom: return "Custom";
default: break; default: break;
} }
return "Invalid"; return "Invalid";

View File

@@ -47,6 +47,7 @@
#define _vvsystime(v) (*((PISystemTime*)v._vraw)) #define _vvsystime(v) (*((PISystemTime*)v._vraw))
class PIP_EXPORT PIVariant { class PIP_EXPORT PIVariant {
friend PICout operator <<(PICout s, const PIVariant & v);
public: public:
enum Type { enum Type {
Invalid = 0, Invalid = 0,
@@ -73,8 +74,8 @@ public:
Time, Time,
Date, Date,
DateTime, DateTime,
SystemTime/*, SystemTime,
Custom = 0xFF*/ Custom = 0xFF
}; };
PIVariant(); PIVariant();
@@ -147,6 +148,35 @@ public:
PIBitArray toBitArray() const; PIBitArray toBitArray() const;
PIByteArray toByteArray() const; PIByteArray toByteArray() const;
template<typename T>
T toValue() const {if (_vcustom.size() != sizeof(T)) return T(); return *((T*)_vcustom.data());}
/*
operator bool() const {return toBool();}
operator char() const {return toInt();}
operator uchar() const {return toInt();}
operator short() const {return toInt();}
operator ushort() const {return toInt();}
operator int() const {return toInt();}
operator uint() const {return toInt();}
operator long() const {return toInt();}
operator ulong() const {return toInt();}
operator llong() const {return toLLong();}
operator ullong() const {return (ullong)toLLong();}
operator float() const {return toFloat();}
operator double() const {return toDouble();}
operator ldouble() const {return toLDouble();}
operator complexd() const {return toComplexd();}
operator complexld() const {return toComplexld();}
operator PITime() const {return toTime();}
operator PIDate() const {return toDate();}
operator PIDateTime() const {return toDateTime();}
operator PIString() const {return toString();}
operator PIStringList() const {return toStringList();}
operator PIBitArray() const {return toBitArray();}
operator PIByteArray() const {return toByteArray();}
operator const char*() const {return toString().data();}
operator void*() const {return (void*)(toLLong());}
*/
void operator =(const PIVariant & v); void operator =(const PIVariant & v);
void operator =(const char * v) {setValue(PIString(v));} void operator =(const char * v) {setValue(PIString(v));}
void operator =(const bool v) {setValue(v);} void operator =(const bool v) {setValue(v);}
@@ -177,15 +207,21 @@ public:
bool operator ==(const PIVariant & v) const; bool operator ==(const PIVariant & v) const;
bool operator !=(const PIVariant & v) const {return !(*this == v);} bool operator !=(const PIVariant & v) const {return !(*this == v);}
PIVariant::Type type() const {return type_;} PIVariant::Type type() const {return type_;}
PIString typeName() const {return typeName(type_);} PIString typeName() const {return typeName(type_);}
bool isValid() const {return type_ != PIVariant::Invalid;} bool isValid() const {return type_ != PIVariant::Invalid;}
template <typename T>
static PIVariant fromValue(const T & v) {PIVariant ret; ret._vcustom.resize(sizeof(T)); new((T*)(ret._vcustom.data()))T(v); ret.type_ = PIVariant::Custom; return ret;}
static PIVariant::Type typeFromName(const PIString & tname); static PIVariant::Type typeFromName(const PIString & tname);
static PIString typeName(PIVariant::Type type); static PIString typeName(PIVariant::Type type);
private: private:
void destroy() {_vcustom.clear();}
union { union {
int _vint; int _vint;
llong _vllong; llong _vllong;
@@ -204,12 +240,71 @@ private:
PIByteArray _vbytearray; PIByteArray _vbytearray;
PIString _vstring; PIString _vstring;
PIStringList _vstringlist; PIStringList _vstringlist;
PIByteArray _vcustom;
PIVariant::Type type_; PIVariant::Type type_;
}; };
template<> inline bool PIVariant::toValue() const {return toBool();}
template<> inline char PIVariant::toValue() const {return (char)toInt();}
template<> inline uchar PIVariant::toValue() const {return (uchar)toInt();}
template<> inline short PIVariant::toValue() const {return (short)toInt();}
template<> inline ushort PIVariant::toValue() const {return (ushort)toInt();}
template<> inline int PIVariant::toValue() const {return toInt();}
template<> inline uint PIVariant::toValue() const {return (uint)toInt();}
template<> inline long PIVariant::toValue() const {return (long)toInt();}
template<> inline ulong PIVariant::toValue() const {return (ulong)toInt();}
template<> inline llong PIVariant::toValue() const {return toLLong();}
template<> inline ullong PIVariant::toValue() const {return (ullong)toLLong();}
template<> inline float PIVariant::toValue() const {return toFloat();}
template<> inline double PIVariant::toValue() const {return toDouble();}
template<> inline ldouble PIVariant::toValue() const {return toLDouble();}
template<> inline complexd PIVariant::toValue() const {return toComplexd();}
template<> inline complexld PIVariant::toValue() const {return toComplexld();}
template<> inline void* PIVariant::toValue() const {return (void*)toLLong();}
template<> inline const char* PIVariant::toValue() const {return toString().data();}
template<> inline PITime PIVariant::toValue() const {return toTime();}
template<> inline PIDate PIVariant::toValue() const {return toDate();}
template<> inline PIDateTime PIVariant::toValue() const {return toDateTime();}
template<> inline PIString PIVariant::toValue() const {return toString();}
template<> inline PIStringList PIVariant::toValue() const {return toStringList();}
template<> inline PIBitArray PIVariant::toValue() const {return toBitArray();}
template<> inline PIByteArray PIVariant::toValue() const {return toByteArray();}
inline PICout operator <<(PICout s, const PIVariant & v) {s.space(); s.setControl(0, true); s << "PIVariant(" << PIVariant::typeName(v.type()) << ", " << v.toString() << ")"; s.restoreControl(); return s;} //template<> inline PIVariant PIVariant::fromValue(const char * v) {return PIVariant(PIString(v));}
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const char & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const uchar & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const short & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const ushort & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const int & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const uint & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const long & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const ulong & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const llong & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const ullong & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const float & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const double & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const ldouble & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const complexd & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const complexld & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIBitArray & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIByteArray & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIString & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIStringList & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PITime & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIDate & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIDateTime & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PISystemTime & v) {return PIVariant(v);}
inline PICout operator <<(PICout s, const PIVariant & v) {
s.space(); s.setControl(0, true);
s << "PIVariant(" << PIVariant::typeName(v.type()) << ", ";
if (v.type() == PIVariant::Custom) s << v._vcustom.size() << " bytes";
else s << v.toString();
s << ")";
s.restoreControl(); return s;
}
#endif // PIVARIANT_H #endif // PIVARIANT_H

View File

@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Dynamic array of any type Dynamic array of any type
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -201,7 +201,7 @@ public:
return *this; return *this;
} }
PIVector<T> & assign(const T & f = T()) {return fill(f);} PIVector<T> & assign(const T & f = T()) {return fill(f);}
PIVector<T> & assign(size_t new_size, const T & f) {resize(new_size); fill(f);} PIVector<T> & assign(size_t new_size, const T & f) {resize(new_size); return fill(f);}
PIVector<T> & resize(size_t new_size, const T & f = T()) { PIVector<T> & resize(size_t new_size, const T & f = T()) {
if (new_size < piv_size) { if (new_size < piv_size) {
T * de = &(piv_data[new_size]); T * de = &(piv_data[new_size]);
@@ -261,6 +261,13 @@ public:
PIVector<T> & push_back(const T & v) {alloc(piv_size + 1); new(piv_data + piv_size - 1)T(v); return *this;} PIVector<T> & push_back(const T & v) {alloc(piv_size + 1); new(piv_data + piv_size - 1)T(v); return *this;}
PIVector<T> & append(const T & v) {return push_back(v);} PIVector<T> & append(const T & v) {return push_back(v);}
PIVector<T> & operator <<(const T & v) {return push_back(v);} PIVector<T> & operator <<(const T & v) {return push_back(v);}
PIVector<T> & operator <<(const PIVector<T> & t) {
size_t ps = piv_size;
alloc(piv_size + t.piv_size);
for (int i = 0; i < t.piv_size; ++i)
new(piv_data + ps + i)T(t.piv_data[i]);
return *this;
}
PIVector<T> & push_front(const T & v) {insert(0, v); return *this;} PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
PIVector<T> & prepend(const T & v) {return push_front(v);} PIVector<T> & prepend(const T & v) {return push_front(v);}

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Remote console viewer Remote console viewer
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
System tests program System tests program
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by