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:
@@ -101,6 +101,7 @@ target_link_libraries(pip_test pip)
|
||||
|
||||
add_subdirectory(system_test)
|
||||
add_subdirectory(remote_console)
|
||||
add_subdirectory(code_model_generator)
|
||||
|
||||
if (DEFINED LIB)
|
||||
unset(LIB)
|
||||
|
||||
4
clean
4
clean
@@ -10,3 +10,7 @@ cd remote_console
|
||||
rm -rvf ./CMakeFiles
|
||||
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
|
||||
cd ..
|
||||
cd code_model_generator
|
||||
rm -rvf ./CMakeFiles
|
||||
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
|
||||
cd ..
|
||||
|
||||
17
code_model_generator/CMakeLists.txt
Normal file
17
code_model_generator/CMakeLists.txt
Normal 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 ()
|
||||
225
code_model_generator/main.cpp
Normal file
225
code_model_generator/main.cpp
Normal 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;
|
||||
};
|
||||
48
code_model_generator/main_test.cpp
Normal file
48
code_model_generator/main_test.cpp
Normal 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
140
main.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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>
|
||||
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
|
||||
|
||||
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[]) {
|
||||
//piCout << (S(1,2));
|
||||
//(1,2));
|
||||
//CodeParser cd;
|
||||
//cd.parseFile("test.cpp");
|
||||
PIString s("this\t :is \n(SPARTA)!");
|
||||
piCout << s.findCWord("this");
|
||||
piCout << s.findCWord("is");
|
||||
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>().toType<PIString>();
|
||||
//PIFile::remove("ki");
|
||||
/*PIConfig conf("protocols_commod.conf");
|
||||
piCout << conf.allTree();
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
REGISTER_DEVICE(PIBinaryLog);
|
||||
|
||||
|
||||
PIBinaryLog::PIBinaryLog() {
|
||||
binlog_sig[0] = 'B';
|
||||
@@ -51,10 +53,13 @@ PIBinaryLog::PIBinaryLog() {
|
||||
binlog_sig[4] = 'O';
|
||||
binlog_sig[5] = 'G';
|
||||
setThreadedReadBufferSize(65536);
|
||||
is_started = rapid_start = false;
|
||||
playspeed = 1.0f;
|
||||
default_id = 1;
|
||||
playmode = PlayVariableSpeed;
|
||||
is_started = false;
|
||||
setPlaySpeed(1.f);
|
||||
setDefaultID(1);
|
||||
setPlayMode(PlayVariableSpeed);
|
||||
setLogDir(PIString());
|
||||
setFilePrefix(PIString());
|
||||
setRapidStart(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,23 +69,23 @@ bool PIBinaryLog::openDevice() {
|
||||
is_started = false;
|
||||
is_thread_ok = true;
|
||||
if (mode_ == ReadWrite) {
|
||||
piCoutObj << "ReadWrite mode not supported, use WriteOnly or ReadOnly";
|
||||
piCoutObj << "Error: ReadWrite mode not supported, use WriteOnly or ReadOnly";
|
||||
return false;
|
||||
}
|
||||
if (!file.open(path_, mode_))
|
||||
if (!file.open(path(), mode_))
|
||||
return false;
|
||||
setName(path_);
|
||||
setName(path());
|
||||
if (mode_ == WriteOnly) {
|
||||
file.resize(0);
|
||||
if (!writeFileHeader()) {
|
||||
piCoutObj << "Can't write binlog file header";
|
||||
piCoutObj << "Error: Can't write binlog file header";
|
||||
return false;
|
||||
}
|
||||
is_started = true;
|
||||
}
|
||||
if (mode_ == ReadOnly) {
|
||||
if (file.isEmpty()) {
|
||||
piCoutObj << "File is null";
|
||||
piCoutObj << "Error: File is null";
|
||||
fileError();
|
||||
return false;
|
||||
}
|
||||
@@ -88,11 +93,11 @@ bool PIBinaryLog::openDevice() {
|
||||
fileError();
|
||||
return false;
|
||||
}
|
||||
if (isEmpty()) piCoutObj << "Empty BinLog file";
|
||||
if (isEmpty()) piCoutObj << "Error: Empty BinLog file";
|
||||
// startlogtime = currentSystemTime();
|
||||
play_time = 0;
|
||||
// nextrecord = readsRecord();
|
||||
if (!rapid_start) is_started = true;
|
||||
if (!rapidStart()) is_started = true;
|
||||
}
|
||||
startlogtime = currentSystemTime();
|
||||
return true;
|
||||
@@ -112,7 +117,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
is_thread_ok = false;
|
||||
PISystemTime pt;
|
||||
double delay;
|
||||
switch (playmode) {
|
||||
switch (playMode()) {
|
||||
case PlayRealTime:
|
||||
pt = currentSystemTime() - startlogtime;
|
||||
// if (real_speedX > 0)
|
||||
@@ -129,7 +134,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
break;
|
||||
case PlayVariableSpeed:
|
||||
delay = lastrecord.timestamp.toMilliseconds() - play_time;
|
||||
delay /= playspeed;
|
||||
delay /= playSpeed();
|
||||
if (is_started) {
|
||||
if (delay > 0)
|
||||
PISystemTime::fromMilliseconds(delay).sleep();
|
||||
@@ -147,7 +152,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
|
||||
PIString PIBinaryLog::createNewFile() {
|
||||
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();
|
||||
piCoutObj << "Can't create new file, maybe LogDir is invalid.";
|
||||
return PIString();
|
||||
@@ -225,15 +230,14 @@ int PIBinaryLog::read(void *read_to, int max_size) {
|
||||
}
|
||||
|
||||
|
||||
void PIBinaryLog::restart()
|
||||
{
|
||||
void PIBinaryLog::restart() {
|
||||
bool th = isRunning();
|
||||
if (th) stopThreadedRead();
|
||||
if (!canRead()) return;
|
||||
lastrecord.timestamp = PISystemTime();
|
||||
lastrecord.id = 0;
|
||||
is_thread_ok = true;
|
||||
if (rapid_start) is_started = false;
|
||||
if (rapidStart()) is_started = false;
|
||||
else is_started = true;
|
||||
play_time = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
class PIBinaryLog: public PIIODevice
|
||||
{
|
||||
PIOBJECT(PIBinaryLog)
|
||||
PIIODEVICE(PIBinaryLog)
|
||||
public:
|
||||
PIBinaryLog();
|
||||
~PIBinaryLog() {closeDevice();}
|
||||
@@ -44,32 +44,38 @@ public:
|
||||
|
||||
|
||||
//! Current \a PlayMode
|
||||
PlayMode playMode() const {return playmode;}
|
||||
PlayMode playMode() const {return (PlayMode)(property("playMode").toInt());}
|
||||
|
||||
//! Current directory where billogs wiil be saved
|
||||
const PIString & logDir() const {return logdir;}
|
||||
PIString logDir() const {return property("logDir").toString();}
|
||||
|
||||
//! 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
|
||||
int dafaultID() const {return default_id;}
|
||||
int defaultID() const {return property("defaultID").toInt();}
|
||||
|
||||
//! 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
|
||||
void setPlayMode(PlayMode mode) {playmode = mode;}
|
||||
void setPlayMode(PlayMode mode) {setProperty("playMode", (int)mode);}
|
||||
|
||||
//! 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
|
||||
void setFilePrefix(const PIString & prefix) {fileprefix = prefix;}
|
||||
void setFilePrefix(const PIString & prefix) {setProperty("filePrefix", prefix);}
|
||||
|
||||
//! 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.
|
||||
// * 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;}
|
||||
// //! Returns current play speed multiplyer
|
||||
// float realSpeedX() const {return real_speedX;}
|
||||
//! Set play speed, used only in \a PlayMode = \a PlayVariableSpeed, default value 1.0
|
||||
void setSpeed(float speed) {playspeed = speed;}
|
||||
//! Set play speed, used only if \a playMode = \a PlayVariableSpeed, default value 1.0
|
||||
void setPlaySpeed(float speed) {setProperty("playSpeed", speed);}
|
||||
|
||||
|
||||
//! 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
|
||||
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
|
||||
bool isEnd() {if (!opened_) return true; return file.isEnd();}
|
||||
@@ -103,14 +109,11 @@ public:
|
||||
int read(void *read_to, int max_size);
|
||||
|
||||
//! Write one record to BinLog file, with ID = "defaultID"
|
||||
int write(const void * data, int size) {return writeBinLog(default_id, data, size);}
|
||||
int write(const void * data, int size) {return writeBinLog(defaultID(), data, size);}
|
||||
|
||||
//! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead
|
||||
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
|
||||
void restart();
|
||||
|
||||
@@ -139,6 +142,8 @@ public:
|
||||
EVENT(fileError)
|
||||
|
||||
protected:
|
||||
PIString fullPathPrefix() const {return "binlog";}
|
||||
void configureFromFullPath(const PIString & full_path);
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
bool threadedRead(uchar *readed, int size);
|
||||
@@ -156,16 +161,12 @@ private:
|
||||
BinLogRecord readRecord();
|
||||
|
||||
PIFile file;
|
||||
PIString logdir, fileprefix;
|
||||
BinLogRecord lastrecord;
|
||||
PISystemTime startlogtime;
|
||||
//BinLogRecord nextrecord;
|
||||
PlayMode playmode;
|
||||
double play_time; //milliseconds
|
||||
float playspeed;
|
||||
int default_id;
|
||||
//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];
|
||||
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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);
|
||||
public:
|
||||
//! 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
|
||||
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;}
|
||||
@@ -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
|
||||
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;}
|
||||
|
||||
|
||||
2
pichar.h
2
pichar.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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) {
|
||||
last = 0;
|
||||
for (int j = 1; j < cra.length(); ++j) {
|
||||
bool found = false;
|
||||
piForeach (Argument & a, _args) {
|
||||
if (a.short_key == cra[j]) {
|
||||
a.found = true;
|
||||
last = &a;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) break;
|
||||
}
|
||||
} else {
|
||||
if (last == 0 ? true : !last->has_value) {
|
||||
@@ -77,7 +80,7 @@ void PICLI::parse() {
|
||||
_args_mand << cra;
|
||||
continue;
|
||||
}
|
||||
if (_args_opt.size_s() < _count_opt) {
|
||||
if (_args_opt.size_s() < _count_opt || _count_opt < 0) {
|
||||
_args_opt << cra;
|
||||
continue;
|
||||
}
|
||||
|
||||
12
picli.h
12
picli.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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;}
|
||||
|
||||
//! 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;}
|
||||
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();}
|
||||
@@ -71,10 +71,10 @@ public:
|
||||
const PIString & fullKeyPrefix() const {return _prefix_full;}
|
||||
int mandatoryArgumentsCount() const {return _count_mand;}
|
||||
int optionalArgumentsCount() const {return _count_opt;}
|
||||
void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix;}
|
||||
void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix;}
|
||||
void setMandatoryArgumentsCount(const int count) {_count_mand = count;}
|
||||
void setOptionalArgumentsCount(const int count) {_count_opt = count;}
|
||||
void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix; needParse = true;}
|
||||
void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix; needParse = true;}
|
||||
void setMandatoryArgumentsCount(const int count) {_count_mand = count; needParse = true;}
|
||||
void setOptionalArgumentsCount(const int count) {_count_opt = count; needParse = true;}
|
||||
|
||||
private:
|
||||
struct Argument {
|
||||
|
||||
189
picode.cpp
189
picode.cpp
@@ -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;
|
||||
}
|
||||
80
picode.h
80
picode.h
@@ -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
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
26
picodeinfo.cpp
Normal file
26
picodeinfo.cpp
Normal 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
147
picodeinfo.h
Normal 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
762
picodeparser.cpp
Normal 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
148
picodeparser.h
Normal 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
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
PIStringList PICollection::groups() {
|
||||
PIStringList sl;
|
||||
piForeachC (Group & g, _groups)
|
||||
piForeachC (Group & g, *_groups)
|
||||
sl << g.name;
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
||||
PIVector<const PIObject * > PICollection::groupElements(const PIString & group) {
|
||||
piForeachC (Group & g, _groups)
|
||||
piForeachC (Group & g, *_groups)
|
||||
if (g.name == group)
|
||||
return g.elements;
|
||||
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) {
|
||||
//piCout << "add to" << group << element;
|
||||
PIString n = element->className();
|
||||
piForeach (Group & g, _groups)
|
||||
piForeach (Group & g, *_groups)
|
||||
if (g.name == group) {
|
||||
for (int i = 0; i < g.elements.size_s(); ++i)
|
||||
if (PIString(g.elements[i]->className()) == n)
|
||||
return;
|
||||
g.elements << element;
|
||||
//piCout << "new group" << group << ", ok";
|
||||
return;
|
||||
}
|
||||
_groups << Group(group);
|
||||
_groups.back().elements << element;
|
||||
*_groups << Group(group);
|
||||
_groups->back().elements << element;
|
||||
//piCout << "new group" << group << ", ok";
|
||||
}
|
||||
|
||||
|
||||
PIVector<PICollection::Group> PICollection::_groups;
|
||||
bool __PICollectionInitializer::_inited_(false);
|
||||
PIVector<PICollection::Group> * PICollection::_groups;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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());
|
||||
#endif
|
||||
|
||||
class PICollection
|
||||
class PIP_EXPORT PICollection
|
||||
{
|
||||
friend class __PICollectionInitializer;
|
||||
public:
|
||||
PICollection() {;}
|
||||
|
||||
@@ -74,8 +75,20 @@ protected:
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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::Entry::_empty;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -39,6 +39,10 @@ public:
|
||||
template<typename Type0, typename Type1>
|
||||
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
||||
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;}
|
||||
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;}
|
||||
@@ -284,7 +288,7 @@ public:
|
||||
_CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
||||
|
||||
//! 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
|
||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
|
||||
2
picrc.h
2
picrc.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
44
pidevicepool.cpp
Normal file
44
pidevicepool.cpp
Normal 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
65
pidevicepool.h
Normal 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
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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;
|
||||
PIVector<DirEntry> l;
|
||||
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));
|
||||
delete list[i];
|
||||
}
|
||||
|
||||
2
pidir.h
2
pidir.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
105
piethernet.cpp
105
piethernet.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -38,58 +38,60 @@
|
||||
*
|
||||
*
|
||||
* \section PIEthernet_sec2 UDP
|
||||
* User Datagram Protocol
|
||||
* User Datagram Protocol
|
||||
*
|
||||
* \section PIEthernet_sec3 TCP
|
||||
* Transmission Control Protocol
|
||||
*
|
||||
* */
|
||||
|
||||
REGISTER_DEVICE(PIEthernet);
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
type_ = UDP;
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = sock_s = -1;
|
||||
connected_ = connecting_ = false;
|
||||
params = PIEthernet::ReuseAddress;
|
||||
server_thread_.setData(this);
|
||||
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++;
|
||||
setPriority(piHigh);
|
||||
type_ = type;
|
||||
parseAddress(ip_port, &ip_, &port_);
|
||||
ip_s = "";
|
||||
port_s = 0;
|
||||
sock = sock_s = -1;
|
||||
connected_ = connecting_ = false;
|
||||
params = params_;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
setPriority(piHigh);
|
||||
setType(type_);
|
||||
setParameters(params_);
|
||||
if (type_ != UDP) init();
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
piMonitor.ethernets++;
|
||||
setPriority(piHigh);
|
||||
type_ = TCP_Client;
|
||||
path_ = ip_port;
|
||||
parseAddress(ip_port, &ip_s, &port_s);
|
||||
sock = sock_;
|
||||
sock_s = -1;
|
||||
server_thread_.setData(this);
|
||||
params = PIEthernet::ReuseAddress;
|
||||
init_ = opened_ = connected_ = true;
|
||||
connecting_ = false;
|
||||
server_thread_.setData(this);
|
||||
setParameters(PIEthernet::ReuseAddress);
|
||||
setThreadedReadBufferSize(65536);
|
||||
setPriority(piHigh);
|
||||
setType(TCP_Client);
|
||||
setPath(ip_port);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +116,7 @@ bool PIEthernet::init() {
|
||||
#else
|
||||
int so = 1;
|
||||
#endif
|
||||
if (type_ == UDP) {
|
||||
if (type() == UDP) {
|
||||
st = SOCK_DGRAM;
|
||||
pr = IPPROTO_UDP;
|
||||
} else {
|
||||
@@ -122,7 +124,7 @@ bool PIEthernet::init() {
|
||||
pr = IPPROTO_TCP;
|
||||
}
|
||||
#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_s = WSASocket(AF_INET, st, pr, NULL, 0, WSA_FLAG_OVERLAPPED);
|
||||
#else
|
||||
@@ -133,6 +135,7 @@ bool PIEthernet::init() {
|
||||
piCoutObj << "Can`t create socket, " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
PIFlags<Parameters> params = parameters();
|
||||
#ifndef WINDOWS
|
||||
timeval to;
|
||||
to.tv_sec = 10;
|
||||
@@ -160,14 +163,15 @@ void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
|
||||
bool PIEthernet::openDevice() {
|
||||
if (connected_) return true;
|
||||
init();
|
||||
if (sock == -1 || path_.isEmpty()) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
if (type_ != UDP)
|
||||
if (sock == -1 || path().isEmpty()) return false;
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
if (type() != UDP)
|
||||
return true;
|
||||
//piCout << "bind to" << (params[PIEthernet::Broadcast] ? "bc" : ip_) << ":" << port_ << " ...";
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_family = AF_INET;
|
||||
addr_.sin_port = htons(port_);
|
||||
PIFlags<Parameters> params = parameters();
|
||||
if (params[PIEthernet::Broadcast]) addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
#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) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type_ != UDP) {
|
||||
if (type() != UDP) {
|
||||
piCoutObj << "Only UDP sockets can join multicast groups";
|
||||
return false;
|
||||
}
|
||||
@@ -229,10 +240,12 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
if (mcast_queue.contains(group))
|
||||
return false;
|
||||
mcast_queue.enqueue(group);
|
||||
if (!mcast_groups.contains(group)) mcast_groups << group;
|
||||
return true;
|
||||
}
|
||||
PIFlags<Parameters> params = parameters();
|
||||
#ifdef WINDOWS
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_family = AF_INET;
|
||||
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();
|
||||
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
|
||||
# ifndef QNX
|
||||
if (!params[Broadcast])
|
||||
piCoutObj << "Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!";
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
struct ip_mreqn mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.imr_ifindex = 0;
|
||||
@@ -267,6 +283,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
piCoutObj << "Can`t join multicast group " << group << ", " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
if (!mcast_groups.contains(group)) mcast_groups << group;
|
||||
# endif
|
||||
#endif
|
||||
return true;
|
||||
@@ -276,19 +293,21 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type_ != UDP) {
|
||||
if (type() != UDP) {
|
||||
piCoutObj << "Only UDP sockets can leave multicast groups";
|
||||
return false;
|
||||
}
|
||||
PIFlags<Parameters> params = parameters();
|
||||
#ifdef WINDOWS
|
||||
SOCKET s = leafs[group];
|
||||
if (s != SOCKET()) {
|
||||
leafs.erase(group);
|
||||
closesocket(s);
|
||||
mcast_groups.removeAll(group);
|
||||
}
|
||||
#else
|
||||
# ifndef QNX
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
struct ip_mreqn mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
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();
|
||||
return false;
|
||||
}
|
||||
mcast_groups.removeAll(group);
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
@@ -330,7 +350,7 @@ bool PIEthernet::connect() {
|
||||
bool PIEthernet::listen() {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port_);
|
||||
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;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
//piCoutObj << "read from " << ip_ << ":" << port_ << endl;
|
||||
switch (type_) {
|
||||
switch (type()) {
|
||||
case TCP_SingleTCP:
|
||||
::listen(sock, 64);
|
||||
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
||||
@@ -382,7 +402,7 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
case TCP_Client:
|
||||
if (connecting_) {
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
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";
|
||||
int ret = 0;
|
||||
switch (type_) {
|
||||
switch (type()) {
|
||||
case TCP_SingleTCP:
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
addr_.sin_port = htons(port_s);
|
||||
@@ -486,7 +506,7 @@ int PIEthernet::write(const void * data, int max_size) {
|
||||
case TCP_Client:
|
||||
if (connecting_) {
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
parseAddress(path(), &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = AF_INET;
|
||||
@@ -517,7 +537,7 @@ void PIEthernet::server_func(void * eth) {
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
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;
|
||||
}
|
||||
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 il;
|
||||
Interface ci;
|
||||
|
||||
43
piethernet.h
43
piethernet.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
class PIP_EXPORT PIEthernet: public PIIODevice
|
||||
{
|
||||
PIOBJECT(PIEthernet)
|
||||
PIIODEVICE(PIEthernet)
|
||||
friend class PIPeer;
|
||||
public:
|
||||
|
||||
@@ -57,16 +57,16 @@ public:
|
||||
|
||||
|
||||
//! 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"
|
||||
void setReadAddress(const PIString & ip_port) {path_ = ip_port;}
|
||||
void setReadAddress(const PIString & ip_port) {setPath(ip_port);}
|
||||
|
||||
//! 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
|
||||
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
|
||||
@@ -83,13 +83,13 @@ public:
|
||||
|
||||
|
||||
//! Returns read address in format "i.i.i.i:p"
|
||||
PIString readAddress() {return path_;}
|
||||
PIString readAddress() {return path();}
|
||||
|
||||
//! Returns read IP
|
||||
PIString readIP() {parseAddress(path_, &ip_, &port_); return ip_;}
|
||||
PIString readIP() {parseAddress(path(), &ip_, &port_); return ip_;}
|
||||
|
||||
//! 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"
|
||||
@@ -103,21 +103,21 @@ public:
|
||||
|
||||
|
||||
//! 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
|
||||
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
|
||||
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
|
||||
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);}
|
||||
|
||||
//! 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
|
||||
@@ -126,15 +126,18 @@ public:
|
||||
//! Leave multicast group with address "group". Use only for UDP
|
||||
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
|
||||
bool connect();
|
||||
|
||||
//! 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
|
||||
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
|
||||
bool isConnected() const {return connected_;}
|
||||
@@ -308,6 +311,8 @@ public:
|
||||
protected:
|
||||
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);
|
||||
|
||||
//! Executes when any read function was successful. Default implementation does nothing
|
||||
@@ -329,14 +334,14 @@ protected:
|
||||
PIThread server_thread_;
|
||||
PIVector<PIEthernet * > clients_;
|
||||
PIQueue<PIString> mcast_queue;
|
||||
PIStringList mcast_groups;
|
||||
#ifdef WINDOWS
|
||||
PIMap<PIString, SOCKET> leafs;
|
||||
#endif
|
||||
PIFlags<PIEthernet::Parameters> params;
|
||||
Type type_;
|
||||
|
||||
private:
|
||||
static void server_func(void * eth);
|
||||
void setType(Type t) {setProperty("type", (int)t); if (isOpened()) {closeDevice(); init(); openDevice();}}
|
||||
|
||||
static std::string ethErrorString() {
|
||||
#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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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("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("defined", 1);
|
||||
clearCustomVariables();
|
||||
//addVariable("n", 0.);
|
||||
//addVariable("x1", 123);
|
||||
@@ -245,6 +246,7 @@ PIEvaluatorTypes::BaseFunctions PIEvaluatorContent::getBaseFunction(const PIStri
|
||||
if (name == "clamp") return PIEvaluatorTypes::bfClamp;
|
||||
if (name == "step") return PIEvaluatorTypes::bfStep;
|
||||
if (name == "mix") return PIEvaluatorTypes::bfMix;
|
||||
if (name == "defined") return PIEvaluatorTypes::bfDefined;
|
||||
return PIEvaluatorTypes::bfUnknown;
|
||||
}
|
||||
|
||||
@@ -1148,6 +1150,9 @@ inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci)
|
||||
ttmp = value(ci.operators[2]);
|
||||
tmpvars[oi].value = stmp.real() * (1. - tmp.real()) + ttmp.real() * tmp.real();
|
||||
break;
|
||||
case PIEvaluatorTypes::bfDefined:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. ? complexd_1 : complexd_0;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfRandom:
|
||||
tmp = static_cast<ldouble>(rand()) / RAND_MAX;
|
||||
stmp = value(ci.operators[1]) - value(ci.operators[0]);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "pistring.h"
|
||||
#include "pimath.h"
|
||||
|
||||
typedef complexd (*FuncFunc)(void * , int, complexd * );
|
||||
|
||||
namespace PIEvaluatorTypes {
|
||||
static const int operationCount = 14;
|
||||
|
||||
@@ -42,9 +44,10 @@ namespace PIEvaluatorTypes {
|
||||
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||
bfRad, bfDeg, bfJ0, bfJ1, bfJN,
|
||||
bfY0, bfY1, bfYN, bfMin, bfMax,
|
||||
bfClamp, bfStep, bfMix
|
||||
bfClamp, bfStep, bfMix, bfDefined,
|
||||
bfCustom = 0xFFFF
|
||||
};
|
||||
|
||||
|
||||
struct Instruction {
|
||||
Instruction() {;}
|
||||
Instruction(Operation oper, PIVector<int> opers, int out_ind, int func = -1) {
|
||||
@@ -63,10 +66,12 @@ namespace PIEvaluatorTypes {
|
||||
int var_num;
|
||||
};
|
||||
struct Function {
|
||||
Function() {arguments = 0; type = bfUnknown;}
|
||||
Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype;}
|
||||
Function() {arguments = 0; type = bfUnknown; handler = 0;}
|
||||
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;
|
||||
BaseFunctions type;
|
||||
FuncFunc handler;
|
||||
int arguments;
|
||||
};
|
||||
struct Variable {
|
||||
@@ -83,6 +88,7 @@ namespace PIEvaluatorTypes {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
|
||||
class PIP_EXPORT PIEvaluatorContent
|
||||
{
|
||||
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 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 variablesCount() const {return variables.size();}
|
||||
int customVariablesCount() const {return variables.size() - cv_count;}
|
||||
@@ -119,16 +126,24 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIP_EXPORT PIEvaluator
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructs an empty evaluator
|
||||
PIEvaluator() {correct = false;}
|
||||
PIEvaluator() {correct = false; data_ = 0;}
|
||||
|
||||
~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
|
||||
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 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
|
||||
complexd evaluate();
|
||||
|
||||
@@ -200,6 +218,7 @@ private:
|
||||
PIString currentString, lastError;
|
||||
complexd out;
|
||||
bool correct;
|
||||
void * data_;
|
||||
};
|
||||
|
||||
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||
|
||||
13
pifile.cpp
13
pifile.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -40,12 +40,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
REGISTER_DEVICE(PIFile);
|
||||
|
||||
|
||||
bool PIFile::openDevice() {
|
||||
close();
|
||||
if (path_.isEmpty()) return false;
|
||||
if (path().isEmpty()) return false;
|
||||
//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);
|
||||
#ifndef WINDOWS
|
||||
if (opened_) fcntl(fileno(fd), F_SETFL, O_NONBLOCK);
|
||||
@@ -144,3 +146,8 @@ bool PIFile::isExists(const PIString & path) {
|
||||
if (ok) fclose(f);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void PIFile::configureFromFullPath(const PIString & full_path) {
|
||||
setPath(full_path);
|
||||
}
|
||||
|
||||
16
pifile.h
16
pifile.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,11 +28,11 @@
|
||||
|
||||
class PIP_EXPORT PIFile: public PIIODevice
|
||||
{
|
||||
PIOBJECT(PIFile)
|
||||
PIIODEVICE(PIFile)
|
||||
public:
|
||||
|
||||
//! 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();}
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
|
||||
|
||||
//! 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
|
||||
llong size();
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
//! Write to file binary content of "v"
|
||||
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"
|
||||
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;}
|
||||
|
||||
|
||||
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_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_HANDLER1(void, resize, llong, new_size) {resize(new_size, 0);}
|
||||
EVENT_HANDLER2(void, resize, llong, new_size, uchar, fill);
|
||||
|
||||
@@ -222,6 +222,8 @@ public:
|
||||
//! \}
|
||||
|
||||
protected:
|
||||
PIString fullPathPrefix() const {return "file";}
|
||||
void configureFromFullPath(const PIString & full_path);
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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 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
|
||||
|
||||
|
||||
65
piincludes.h
65
piincludes.h
@@ -7,7 +7,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,7 +27,7 @@
|
||||
#define PIINCLUDES_H
|
||||
|
||||
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
|
||||
#define PIP_VERSION 0x000308
|
||||
#define PIP_VERSION 0x000400
|
||||
|
||||
//! Major value of PIP version
|
||||
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
||||
@@ -39,7 +39,7 @@
|
||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||
|
||||
//! Suffix of PIP version
|
||||
#define PIP_VERSION_SUFFIX "_beta"
|
||||
#define PIP_VERSION_SUFFIX "_prealpha"
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
@@ -84,8 +84,13 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__WIN64__)
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
# define WINDOWS
|
||||
# define ARCH_BITS_32
|
||||
#endif
|
||||
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
|
||||
# define WINDOWS
|
||||
# define ARCH_BITS_64
|
||||
#endif
|
||||
#if defined(__QNX__) || defined(__QNXNTO__)
|
||||
# define QNX
|
||||
@@ -112,6 +117,15 @@
|
||||
# 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__
|
||||
# define CC_GCC
|
||||
# define CC_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
|
||||
@@ -128,8 +142,10 @@
|
||||
# pragma GCC diagnostic ignored "-Wextra"
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
# endif
|
||||
# define DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
# define CC_VC
|
||||
# pragma warning(disable: 4018)
|
||||
# pragma warning(disable: 4061)
|
||||
# pragma warning(disable: 4100)
|
||||
# pragma warning(disable: 4239)
|
||||
@@ -144,15 +160,15 @@
|
||||
# pragma warning(disable: 4820)
|
||||
# pragma warning(disable: 4986)
|
||||
# pragma warning(disable: 4996)
|
||||
# define DEPRECATED
|
||||
# ifdef ARCH_BITS_32
|
||||
typedef long ssize_t;
|
||||
# else
|
||||
typedef long long ssize_t;
|
||||
# endif
|
||||
#else
|
||||
# define CC_OTHER
|
||||
#endif
|
||||
#ifdef PIP_DEBUG
|
||||
# undef NDEBUG
|
||||
#else
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
# define DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
@@ -164,7 +180,7 @@
|
||||
#endif
|
||||
|
||||
#include "pip_export.h"
|
||||
#if defined(DOXYGEN) || defined(CC_GCC)
|
||||
#if defined(DOXYGEN) || defined(CC_GCC) || defined(PICODE)
|
||||
# undef PIP_EXPORT
|
||||
# define PIP_EXPORT
|
||||
#endif
|
||||
@@ -190,6 +206,7 @@
|
||||
#include <ctime>
|
||||
#include <csignal>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
//#include <signal.h>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
@@ -236,7 +253,7 @@
|
||||
# endif
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
# include "ifaddrs_3rd.h"
|
||||
//# include "ifaddrs_3rd.h"
|
||||
# define tcdrain(fd) ioctl(fd, TCSBRK, 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;}
|
||||
@@ -259,6 +276,13 @@
|
||||
#ifdef FREE_BSD
|
||||
extern char ** environ;
|
||||
#endif
|
||||
#if defined(DOXYGEN) || defined(PICODE)
|
||||
# undef PIP_EXPORT
|
||||
# define PIP_EXPORT
|
||||
# undef DEPRECATED
|
||||
# define DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "pimonitor.h"
|
||||
|
||||
extern PIMonitor piMonitor;
|
||||
@@ -294,12 +318,9 @@ using std::map;
|
||||
using std::multimap;
|
||||
using std::string;
|
||||
#ifndef QNX
|
||||
using std::wstring;
|
||||
//# ifndef WINDOWS
|
||||
//static locale_t currentLocale_t = 0;
|
||||
//# endif
|
||||
using std::wstring;
|
||||
#else
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
|
||||
/*! \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 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);}
|
||||
__attribute__((deprecated)) inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||
DEPRECATED inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);}
|
||||
DEPRECATED inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
@@ -721,7 +742,7 @@ private:
|
||||
|
||||
#else
|
||||
# define piCout if (piDebug) PICout()
|
||||
# define piCoutObj if (piDebug && debug_) PICout() << "" << (PIString("[") + className() + " \"" + name() + "\"]")
|
||||
# define piCoutObj if (piDebug && debug()) PICout() << "" << (PIString("[") + className() + " \"" + name() + "\"]")
|
||||
#endif
|
||||
|
||||
class PIObject;
|
||||
@@ -787,7 +808,7 @@ namespace PICoutManipulators {
|
||||
BackMagenta /*! Magenta background */ = 0x800000,
|
||||
BackCyan /*! Cyan background */ = 0x1000000,
|
||||
BackWhite /*! White background */ = 0x2000000,
|
||||
Default /*! Default format */ = 0x4000000,
|
||||
Default /*! Default format */ = 0x4000000
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
118
piiodevice.cpp
118
piiodevice.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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
|
||||
* receive pointer to this buffer in first argument. You can adjust size of this buffer
|
||||
* 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
|
||||
* When threaded read is begin its call \a open() if device is closed. While threaded
|
||||
@@ -70,11 +70,42 @@
|
||||
* function \a configureDevice().
|
||||
* \n Each ancestor of %PIIODevice reimlements \a configureDevice() function to be able
|
||||
* 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
|
||||
* Implement example:
|
||||
* Implementation example:
|
||||
* \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
|
||||
* \snippet piiodevice.cpp 0
|
||||
*/
|
||||
@@ -82,38 +113,18 @@
|
||||
|
||||
PIIODevice::PIIODevice(): PIThread() {
|
||||
mode_ = ReadOnly;
|
||||
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();
|
||||
init();
|
||||
_init();
|
||||
setPath(PIString());
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Constructs a PIIODevice with path and mode
|
||||
* \param path path to device
|
||||
* \param type mode for open
|
||||
* \param initNow init or not in constructor */
|
||||
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool initNow): PIThread() {
|
||||
path_ = path;
|
||||
mode_ = type;
|
||||
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();
|
||||
* \param type mode for open */
|
||||
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIThread() {
|
||||
mode_ = mode;
|
||||
_init();
|
||||
setPath(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
//cout << "check " << tread_started_ << endl;
|
||||
if (open()) {
|
||||
@@ -176,7 +201,7 @@ void PIIODevice::begin() {
|
||||
return;
|
||||
}
|
||||
//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;
|
||||
if (timeout_ms <= 0.) return str;
|
||||
int ret;
|
||||
uchar td[threadedReadBufferSize()];
|
||||
uchar * td = new uchar[threadedReadBufferSize()];
|
||||
timer.reset();
|
||||
while (timer.elapsed_m() < timeout_ms) {
|
||||
ret = read(td, threadedReadBufferSize());
|
||||
if (ret <= 0) msleep(1);
|
||||
else str.append(td, ret);
|
||||
}
|
||||
delete td;
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -237,16 +263,30 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
|
||||
PIConfig::Entry * ep = 0;
|
||||
if (parent_section) ep = em.parent();
|
||||
if (ep != 0) {
|
||||
setReopenEnabled(ep->getValue("reopenEnabled", reopen_enabled_, &ex));
|
||||
if (!ex) setReopenEnabled(em.getValue("reopenEnabled", reopen_enabled_));
|
||||
setReopenTimeout(ep->getValue("reopenTimeout", reopen_timeout_, &ex));
|
||||
if (!ex) setReopenTimeout(em.getValue("reopenTimeout", reopen_timeout_));
|
||||
setReopenEnabled(ep->getValue("reopenEnabled", isReopenEnabled(), &ex));
|
||||
if (!ex) setReopenEnabled(em.getValue("reopenEnabled", isReopenEnabled()));
|
||||
setReopenTimeout(ep->getValue("reopenTimeout", reopenTimeout(), &ex));
|
||||
if (!ex) setReopenTimeout(em.getValue("reopenTimeout", reopenTimeout()));
|
||||
setThreadedReadBufferSize(ep->getValue("threadedReadBufferSize", buffer_tr.size_s(), &ex));
|
||||
if (!ex) setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s()));
|
||||
} else {
|
||||
setReopenEnabled(em.getValue("reopenEnabled", reopen_enabled_));
|
||||
setReopenTimeout(em.getValue("reopenTimeout", reopen_timeout_));
|
||||
setReopenEnabled(em.getValue("reopenEnabled", isReopenEnabled()));
|
||||
setReopenTimeout(em.getValue("reopenTimeout", reopenTimeout()));
|
||||
setThreadedReadBufferSize(em.getValue("threadedReadBufferSize", buffer_tr.size_s()));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
65
piiodevice.h
65
piiodevice.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,12 +23,27 @@
|
||||
#ifndef PIIODEVICE_H
|
||||
#define PIIODEVICE_H
|
||||
|
||||
#include "picollection.h"
|
||||
#include "pivariant.h"
|
||||
#include "pitimer.h"
|
||||
|
||||
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||
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
|
||||
{
|
||||
@@ -45,17 +60,17 @@ public:
|
||||
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();
|
||||
|
||||
//! Current open mode of device
|
||||
DeviceMode mode() const {return mode_;}
|
||||
|
||||
//! Current path of device
|
||||
PIString path() const {return path_;}
|
||||
PIString path() const {return property("path").toString();}
|
||||
|
||||
//! 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
|
||||
bool isReadable() const {return (mode_ & ReadOnly);}
|
||||
@@ -79,17 +94,17 @@ public:
|
||||
|
||||
|
||||
//! 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
|
||||
void setReopenTimeout(int msecs = 1000) {reopen_timeout_ = msecs;}
|
||||
void setReopenTimeout(int msecs) {setProperty("reopenTimeout", msecs);}
|
||||
|
||||
|
||||
//! Return reopen enable
|
||||
bool isReopenEnabled() const {return reopen_enabled_;}
|
||||
bool isReopenEnabled() const {return property("reopenEnabled").toBool();}
|
||||
|
||||
//! Return reopen timeout
|
||||
int reopenTimeout() {return reopen_timeout_;}
|
||||
int reopenTimeout() {return property("reopenTimeout").toInt();}
|
||||
|
||||
|
||||
/** \brief Set "threaded read slot"
|
||||
@@ -172,12 +187,18 @@ public:
|
||||
|
||||
//! Configure device from section "section" of file "config_file", if "parent_section" parent section also will be read
|
||||
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_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_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, initialize) {init_ = init(); return init_;}
|
||||
|
||||
@@ -249,12 +270,9 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
//! Function executed from the end of constructor
|
||||
virtual void created() {;}
|
||||
|
||||
//! Function executed before first \a openDevice() or from constructor
|
||||
virtual bool init() {return true;}
|
||||
|
||||
|
||||
//! Reimplement to configure device from entries "e_main" and "e_parent", cast arguments to \a PIConfig::Entry*
|
||||
virtual bool configureDevice(const void * e_main, const void * e_parent = 0) {return true;}
|
||||
|
||||
@@ -267,20 +285,31 @@ protected:
|
||||
//! 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;}
|
||||
|
||||
|
||||
//! 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();
|
||||
|
||||
|
||||
PIString path_;
|
||||
DeviceMode mode_;
|
||||
ReadRetFunc ret_func_;
|
||||
bool init_, opened_, thread_started_, reopen_enabled_, raise_threaded_read_;
|
||||
int reopen_timeout_;
|
||||
bool init_, opened_, thread_started_, raise_threaded_read_;
|
||||
void * ret_data_;
|
||||
|
||||
private:
|
||||
EVENT_HANDLER2(void, check_start, void * , data, int, delim);
|
||||
EVENT_HANDLER(void, write_func);
|
||||
|
||||
virtual PIIODevice * copy() const {return 0;}
|
||||
void _init();
|
||||
void begin();
|
||||
void run();
|
||||
void end() {terminate();}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
* \brief Keyboard console input listener
|
||||
* \details This class provide listening of console keyboard input.
|
||||
* 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()
|
||||
*
|
||||
* Also there is static variable \a exiting which by default is set to
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
bool PIKbdListener::exiting;
|
||||
|
||||
PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
||||
PIKbdListener::PIKbdListener(KBFunc slot, void * _data): PIThread() {
|
||||
#ifdef WINDOWS
|
||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hIn, &smode);
|
||||
@@ -49,7 +49,7 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
||||
#endif
|
||||
is_active = true;
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
data_ = _data;
|
||||
PIKbdListener::exiting = exit_enabled = false;
|
||||
start();
|
||||
}
|
||||
@@ -134,8 +134,8 @@ void PIKbdListener::run() {
|
||||
return;
|
||||
}
|
||||
if (ret > 0) {
|
||||
keyPressed(lc, data);
|
||||
if (ret_func != 0) ret_func(lc, data);
|
||||
keyPressed(lc, data_);
|
||||
if (ret_func != 0) ret_func(lc, data_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -56,8 +56,11 @@ public:
|
||||
~PIKbdListener() {terminate(); end();}
|
||||
|
||||
|
||||
//! Set custom data to "data"
|
||||
void setData(void * data_) {data = data_;}
|
||||
//! Returns custom data
|
||||
void * data() {return data_;}
|
||||
|
||||
//! Set custom data to "_data"
|
||||
void setData(void * _data) {data_ = _data;}
|
||||
|
||||
//! Set external function to "slot"
|
||||
void setSlot(KBFunc slot) {ret_func = slot;}
|
||||
@@ -111,7 +114,7 @@ private:
|
||||
KBFunc ret_func;
|
||||
char exit_key;
|
||||
bool exit_enabled, is_active;
|
||||
void * data;
|
||||
void * data_;
|
||||
#ifdef WINDOWS
|
||||
DWORD ret, rc;
|
||||
void * hIn;
|
||||
|
||||
13
pimap.h
13
pimap.h
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;}
|
||||
Type & at(const Key & key_) {return value(key_);}
|
||||
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
||||
PIVector<Key> keys() const {
|
||||
PIVector<Key> ret;
|
||||
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();}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pimath.h
2
pimath.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
10
piobject.cpp
10
piobject.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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) {
|
||||
PIObject * o = findByName(src);
|
||||
if (o == 0) {
|
||||
|
||||
34
piobject.h
34
piobject.h
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -227,26 +227,26 @@ class PIP_EXPORT PIObject
|
||||
public:
|
||||
|
||||
//! 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);}
|
||||
|
||||
|
||||
//! Returns object name
|
||||
const PIString & name() const {return name_;}
|
||||
PIString name() const {return property("name").toString();}
|
||||
|
||||
//! Returns object class name
|
||||
virtual const char * className() const {return "PIObject";}
|
||||
|
||||
//! Return if debug of this object is active
|
||||
bool debug() const {return debug_;}
|
||||
bool debug() const {return property("debug").toBool();}
|
||||
|
||||
|
||||
//! Set object name
|
||||
void setName(const PIString & name) {name_ = name;}
|
||||
void setName(const PIString & name) {setProperty("name", name);}
|
||||
|
||||
//! Set object debug active
|
||||
void setDebug(bool debug) {debug_ = debug;}
|
||||
void setDebug(bool debug) {setProperty("debug", debug);}
|
||||
|
||||
//! Returns properties of the object
|
||||
const PIMap<PIString, PIVariant> & properties() const {return properties_;}
|
||||
@@ -255,13 +255,13 @@ public:
|
||||
int propertiesCount() const {return properties_.size_s();}
|
||||
|
||||
//! 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
|
||||
void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value;}
|
||||
|
||||
//! 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();
|
||||
@@ -475,10 +475,17 @@ public:
|
||||
}
|
||||
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:
|
||||
PIString name_;
|
||||
bool debug_;
|
||||
|
||||
private:
|
||||
struct Connection {
|
||||
@@ -493,13 +500,6 @@ private:
|
||||
PIMap<PIString, PIVariant> properties_;
|
||||
|
||||
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
4
pip.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -31,4 +31,6 @@
|
||||
#include "picrc.h"
|
||||
#include "pistatemachine.h"
|
||||
#include "picollection.h"
|
||||
#include "piserial.h"
|
||||
#include "pibinarylog.h"
|
||||
#include "piusb.h"
|
||||
|
||||
18
pip.pro
18
pip.pro
@@ -9,11 +9,11 @@ INCLUDEPATH += .
|
||||
QT -= core gui
|
||||
CONFIG -= qt
|
||||
CONFIG += dll
|
||||
VERSION = 0.3.8
|
||||
VERSION = 0.4.0
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
pivariable.h \
|
||||
pivariant.h \
|
||||
pitimer.h \
|
||||
pithread.h \
|
||||
pisystemtests.h \
|
||||
@@ -49,10 +49,12 @@ HEADERS += \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
picollection.h \
|
||||
ifaddrs_3rd.h \
|
||||
pidiagnostics.h
|
||||
pidiagnostics.h \
|
||||
pibinarylog.h \
|
||||
picodeparser.h \
|
||||
piusb.h
|
||||
SOURCES += main.cpp \
|
||||
pivariable.cpp \
|
||||
pivariant.cpp \
|
||||
pitimer.cpp \
|
||||
pithread.cpp \
|
||||
pisystemtests.cpp \
|
||||
@@ -80,8 +82,10 @@ SOURCES += main.cpp \
|
||||
picli.cpp \
|
||||
pibytearray.cpp \
|
||||
picollection.cpp \
|
||||
ifaddrs_3rd.c \
|
||||
pidiagnostics.cpp
|
||||
pidiagnostics.cpp \
|
||||
pibinarylog.cpp \
|
||||
picodeparser.cpp \
|
||||
piusb.cpp
|
||||
win32 {
|
||||
LIBS += -lws2_32 -lIphlpapi
|
||||
} else {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,3,8,0
|
||||
PRODUCTVERSION 0,3,8,0
|
||||
FILEVERSION 0,4,0,0
|
||||
PRODUCTVERSION 0,4,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS VOS__WINDOWS32
|
||||
@@ -19,7 +19,7 @@ VS_VERSION_INFO VERSIONINFO
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Peri4\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 "OriginalFilename", "libpip.dll\0"
|
||||
VALUE "ProductName", "PIP\0"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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) {
|
||||
ret_func_header = 0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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
|
||||
{
|
||||
PIOBJECT(PIPacketExtractor)
|
||||
PIIODEVICE(PIPacketExtractor)
|
||||
public:
|
||||
|
||||
//! Contructs extractor with child device "device_", header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize"
|
||||
@@ -106,6 +106,7 @@ protected:
|
||||
|
||||
private:
|
||||
bool threadedRead(uchar * readed, int size);
|
||||
PIString fullPathPrefix() const {return "pckext";}
|
||||
bool openDevice() {if (dev == 0) return false; return dev->open();}
|
||||
|
||||
PIIODevice * dev;
|
||||
|
||||
10
pipeer.cpp
10
pipeer.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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_MSG_SIZE 8192
|
||||
|
||||
PIPeer::PIPeer(const PIString & name): PIObject() {
|
||||
PIPeer::PIPeer(const PIString & name_): PIObject() {
|
||||
rec_mc = rec_bc = false;
|
||||
setName(name);
|
||||
setName(name_);
|
||||
self_info.name = name_;
|
||||
self_info.dist = 0;
|
||||
eth_send = 0;
|
||||
@@ -272,7 +272,7 @@ bool PIPeer::multicastRead(uchar * data, int size) {
|
||||
PIVector<PeerInfo> rpeers;
|
||||
ba >> 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);
|
||||
diag_s.received(size);
|
||||
//piCout << "analyz ...";
|
||||
@@ -319,7 +319,7 @@ bool PIPeer::multicastRead(uchar * data, int size) {
|
||||
for (uint i = 0; i < rpeers.size(); ++i) {
|
||||
PeerInfo & rpeer(rpeers[i]);
|
||||
//piCout << " to sync " << rpeer.name;
|
||||
if (rpeer.name == name_) continue;
|
||||
if (rpeer.name == name()) continue;
|
||||
bool exist = false;
|
||||
for (uint j = 0; j < peers.size(); ++j) {
|
||||
PeerInfo & peer(peers[j]);
|
||||
|
||||
6
pipeer.h
6
pipeer.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
PIDiagnostics & diagnosticService() {return diag_s;}
|
||||
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;}
|
||||
|
||||
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 sendPeerRemove(const PIString & peer);
|
||||
void sendSelfInfo() {sendPeerInfo(self_info);}
|
||||
void sendSelfRemove() {sendPeerRemove(name_);}
|
||||
void sendSelfRemove() {sendPeerRemove(name());}
|
||||
void syncPeers();
|
||||
void findNearestAddresses();
|
||||
void initEths(const PIStringList & al);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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)
|
||||
piCoutObj << "Warning: null send data size!";*/
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PI
|
||||
pp.setFlag(PISerial::TwoStopBits, flag);
|
||||
}
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -346,7 +346,7 @@ void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const
|
||||
if (recDataSize == 0)
|
||||
piCoutObj << "Warning: null receive data size!";*/
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
@@ -416,7 +416,7 @@ void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const
|
||||
if (recDataSize == 0)
|
||||
piCoutObj << "Warning: null receive data size!";*/
|
||||
} 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";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
127
piserial.cpp
127
piserial.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -32,39 +32,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
REGISTER_DEVICE(PISerial);
|
||||
|
||||
|
||||
PISerial::PISerial(): PIIODevice("", ReadWrite) {
|
||||
piMonitor.serials++;
|
||||
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();
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_): PIIODevice(device_, ReadWrite) {
|
||||
piMonitor.serials++;
|
||||
setPriority(piHigh);
|
||||
path_ = device_;
|
||||
fd = -1;
|
||||
block_read = true;
|
||||
params = params_;
|
||||
ispeed = ospeed = speed_;
|
||||
vtime = 1;
|
||||
#ifdef WINDOWS
|
||||
block_write = true;
|
||||
hCom = 0;
|
||||
#endif
|
||||
dbits = 8;
|
||||
init();
|
||||
_init();
|
||||
setPath(device_);
|
||||
setSpeed(speed_);
|
||||
setParameters(params_);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
switch (number) {
|
||||
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) {
|
||||
#ifndef WINDOWS
|
||||
if (fd < 0) {
|
||||
piCoutObj << "setBit" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||
piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
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 {
|
||||
#ifndef WINDOWS
|
||||
if (fd < 0) {
|
||||
piCoutObj << "isBit" << bname << " error: \"" << path_ << "\" is not opened!";
|
||||
piCoutObj << "isBit" << bname << " error: \"" << path() << "\" is not opened!";
|
||||
return false;
|
||||
}
|
||||
int ret = 0;
|
||||
@@ -334,29 +344,31 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
|
||||
|
||||
bool PISerial::openDevice() {
|
||||
piCout << "ser open" << path();
|
||||
if (path().isEmpty()) return false;
|
||||
#ifdef WINDOWS
|
||||
DWORD ds = 0, sm = 0;
|
||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||
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);
|
||||
if (hCom == INVALID_HANDLE_VALUE) {
|
||||
piCoutObj << "Unable to open \"" << path_ << "\"";
|
||||
piCoutObj << "Unable to open \"" << path() << "\"";
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
#else
|
||||
int om = 0;
|
||||
switch (mode_) {
|
||||
switch (mode()) {
|
||||
case PIIODevice::ReadOnly: om = O_RDONLY; break;
|
||||
case PIIODevice::WriteOnly: om = O_WRONLY; break;
|
||||
case PIIODevice::ReadWrite: om = O_RDWR; break;
|
||||
}
|
||||
//cout << "init ser " << path_ << " mode " << om << " param " << params << endl;
|
||||
fd = ::open(path_.data(), O_NOCTTY | om);
|
||||
fd = ::open(path().data(), O_NOCTTY | om);
|
||||
if (fd == -1) {
|
||||
piCoutObj << "Unable to open \"" << path_ << "\"";
|
||||
piCoutObj << "Unable to open \"" << path() << "\"";
|
||||
return false;
|
||||
}
|
||||
tcgetattr(fd, &desc);
|
||||
@@ -378,24 +390,25 @@ void PISerial::applySettings() {
|
||||
times.WriteTotalTimeoutConstant = 0;
|
||||
times.WriteTotalTimeoutMultiplier = block_write ? 0 : 1;
|
||||
if (SetCommTimeouts(hCom, ×) == -1)
|
||||
piCoutObj << "Unable to set timeouts for \"" << path_ << "\"";
|
||||
piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
GetCommMask(hCom, &mask);
|
||||
SetCommMask(hCom, EV_RXCHAR);
|
||||
GetCommState(hCom, &sdesc);
|
||||
desc = sdesc;
|
||||
desc.DCBlength = sizeof(desc);
|
||||
desc.BaudRate = convertSpeed(ispeed);
|
||||
if (dbits >= 5 && dbits <= 8)
|
||||
desc.ByteSize = dbits;
|
||||
desc.BaudRate = convertSpeed(outSpeed());
|
||||
if (dataBitsCount() >= 5 && dataBitsCount() <= 8)
|
||||
desc.ByteSize = dataBitsCount();
|
||||
else
|
||||
desc.ByteSize = 8;
|
||||
PIFlags<Parameters> params = parameters();
|
||||
if (params[PISerial::ParityControl]) {
|
||||
desc.fParity = 1;
|
||||
desc.Parity = params[PISerial::ParityOdd] ? 1 : 2;
|
||||
}
|
||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
if (SetCommState(hCom, &desc) == -1) {
|
||||
piCoutObj << "Unable to set comm state for \"" << path_ << "\"";
|
||||
piCoutObj << "Unable to set comm state for \"" << path() << "\"";
|
||||
return;
|
||||
}
|
||||
#else
|
||||
@@ -404,13 +417,14 @@ void PISerial::applySettings() {
|
||||
desc.c_oflag = desc.c_lflag = desc.c_cflag = 0;
|
||||
desc.c_iflag = IGNBRK;
|
||||
desc.c_cflag = CLOCAL | HUPCL;
|
||||
switch (dbits) {
|
||||
switch (dataBitsCount()) {
|
||||
case 5: desc.c_cflag |= (CSIZE & CS5); break;
|
||||
case 6: desc.c_cflag |= (CSIZE & CS6); break;
|
||||
case 7: desc.c_cflag |= (CSIZE & CS7); break;
|
||||
case 8: default: desc.c_cflag |= (CSIZE & CS8); break;
|
||||
};
|
||||
if (isReadable()) desc.c_cflag |= CREAD;
|
||||
PIFlags<Parameters> params = parameters();
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
|
||||
if (params[PISerial::ParityControl]) {
|
||||
desc.c_iflag |= INPCK;
|
||||
@@ -420,14 +434,14 @@ void PISerial::applySettings() {
|
||||
desc.c_cc[VMIN] = 1;
|
||||
desc.c_cc[VTIME] = vtime;
|
||||
|
||||
cfsetispeed(&desc, convertSpeed(ispeed));
|
||||
cfsetospeed(&desc, convertSpeed(ospeed));
|
||||
cfsetispeed(&desc, convertSpeed(inSpeed()));
|
||||
cfsetospeed(&desc, convertSpeed(outSpeed()));
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
fcntl(fd, F_SETFL, block_read ? 0 : O_NONBLOCK);
|
||||
|
||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||
piCoutObj << "Can`t set attributes for \"" << path_ << "\"";
|
||||
piCoutObj << "Can`t set attributes for \"" << path() << "\"";
|
||||
return;
|
||||
}
|
||||
#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 * ep = (PIConfig::Entry * )e_parent;
|
||||
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));
|
||||
setParameter(PISerial::ParityControl, readDeviceSetting<bool>("parityControl", isParameterSet(PISerial::ParityControl), 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> spds;
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
|
||||
@@ -518,11 +551,11 @@ PIStringList PISerial::availableDevices(bool test) {
|
||||
PIStringList dl;
|
||||
#ifdef WINDOWS
|
||||
HKEY key = 0;
|
||||
RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", &key);
|
||||
RegOpenKey(HKEY_LOCAL_MACHINE, (LPCTSTR)"HARDWARE\\DEVICEMAP\\SERIALCOMM", &key);
|
||||
if (key != 0) {
|
||||
char name[256], data[1024];
|
||||
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);
|
||||
index++;
|
||||
}
|
||||
|
||||
40
piserial.h
40
piserial.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -91,7 +91,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
class PIP_EXPORT PISerial: public PIIODevice {
|
||||
class PIP_EXPORT PISerial: public PIIODevice
|
||||
{
|
||||
PIIODEVICE(PISerial)
|
||||
public:
|
||||
|
||||
//! Contructs an empty %PISerial
|
||||
@@ -134,36 +136,36 @@ public:
|
||||
|
||||
|
||||
//! 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"
|
||||
void setOutSpeed(PISerial::Speed speed) {ospeed = speed; applySettings();}
|
||||
void setOutSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); applySettings();}
|
||||
|
||||
//! 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"
|
||||
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_"
|
||||
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
|
||||
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
|
||||
bool isParameterSet(PISerial::Parameters parameter) const {return params[parameter];}
|
||||
bool isParameterSet(PISerial::Parameters parameter) const;
|
||||
|
||||
//! 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
|
||||
void setDataBitsCount(int bits) {dbits = bits; applySettings();}
|
||||
void setDataBitsCount(int bits) {setProperty("dataBitsCount", bits); applySettings();}
|
||||
|
||||
//! 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)
|
||||
@@ -200,13 +202,13 @@ public:
|
||||
|
||||
|
||||
//! Returns device name
|
||||
const PIString & device() const {return path_;}
|
||||
PIString device() const {return path();}
|
||||
|
||||
//! Returns output speed
|
||||
PISerial::Speed outSpeed() const {return ospeed;}
|
||||
PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());}
|
||||
|
||||
//! Returns input speed
|
||||
PISerial::Speed inSpeed() const {return ispeed;}
|
||||
PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());}
|
||||
|
||||
int VTime() const {return vtime;}
|
||||
|
||||
@@ -271,17 +273,19 @@ public:
|
||||
//! \}
|
||||
|
||||
protected:
|
||||
PIString fullPathPrefix() const {return "ser";}
|
||||
void configureFromFullPath(const PIString & full_path);
|
||||
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
||||
int write(const void * data, int max_size) {return write(data, max_size, true);}
|
||||
|
||||
//! Executes when any read function was successful. Default implementation does nothing
|
||||
virtual void received(const void * data, int size) {;}
|
||||
|
||||
void _init();
|
||||
void applySettings();
|
||||
int convertSpeed(PISerial::Speed speed);
|
||||
bool setBit(int bit, bool on, const PIString & bname);
|
||||
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 closeDevice();
|
||||
@@ -295,11 +299,9 @@ protected:
|
||||
termios desc, sdesc;
|
||||
uint readed;
|
||||
#endif
|
||||
int fd, vtime, dbits;
|
||||
int fd, vtime;
|
||||
bool block_read;
|
||||
PISerial::Speed ospeed, ispeed;
|
||||
PITimer timer;
|
||||
PIFlags<PISerial::Parameters> params;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
40
pistring.cpp
40
pistring.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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 ret;
|
||||
int sz = size_s(), ss = -1;
|
||||
|
||||
97
pistring.h
97
pistring.h
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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:
|
||||
//! 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;}
|
||||
PIString & operator +=(const PIChar & c) {push_back(c); return *this;}
|
||||
@@ -49,63 +49,63 @@ public:
|
||||
#endif
|
||||
|
||||
//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"
|
||||
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 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);}
|
||||
|
||||
/*! \brief Contructs string from c-string "str"
|
||||
* \details "str" should be null-terminated\n
|
||||
* 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"
|
||||
* \details "str" should be null-terminated\n
|
||||
* 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"
|
||||
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
|
||||
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
|
||||
|
||||
//! 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"
|
||||
* \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"
|
||||
* \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"
|
||||
* \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 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 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 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 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 double & 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 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 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 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 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);}
|
||||
|
||||
|
||||
/*
|
||||
//! 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() {piMonitor.strings--; piMonitor.containers++;}
|
||||
|
||||
|
||||
PIString & operator =(const PIString & o) {clear(); *this += o; return *this;}
|
||||
|
||||
/*! \brief Return c-string representation of string
|
||||
* \details Converts content of string to c-string and return
|
||||
* 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;}
|
||||
|
||||
|
||||
/*! \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
|
||||
* \details Example: \snippet pistring.cpp PIString::takeSymbol
|
||||
* \sa \a takeWord(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange() */
|
||||
@@ -422,7 +437,7 @@ public:
|
||||
const char * data() const;
|
||||
|
||||
//! \brief Return \c std::string representation of this string
|
||||
const string stdString() const {return convertToStd();}
|
||||
std::string stdString() const {return convertToStd();}
|
||||
#ifdef HAS_LOCALE
|
||||
wstring stdWString() const {return convertToWString();}
|
||||
#endif
|
||||
@@ -478,7 +493,20 @@ public:
|
||||
//! \brief Search substring "str" from symbol at index "start" and return last occur position
|
||||
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||
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
|
||||
int length() const {return size();}
|
||||
@@ -640,6 +668,9 @@ public:
|
||||
//! \details Example: \snippet pistring.cpp PIString::readableSize
|
||||
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:
|
||||
static const char toBaseN[];
|
||||
static const int fromBaseN[];
|
||||
@@ -699,8 +730,8 @@ private:
|
||||
if (cs < 0 || cs >= base) break;
|
||||
digits << cs;
|
||||
}
|
||||
piForeachRC (int & i, digits) {
|
||||
ret += i * m;
|
||||
for (int i = digits.size_s() - 1; i >= 0; --i) {
|
||||
ret += digits[i] * m;
|
||||
m *= base;
|
||||
}
|
||||
if (neg) ret = -ret;
|
||||
@@ -788,6 +819,8 @@ public:
|
||||
|
||||
//! 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 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
|
||||
@@ -812,6 +845,8 @@ public:
|
||||
//! 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;}
|
||||
|
||||
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 PIStringList & sl) {piForeachC (PIString & i, sl) push_back(i); return *this;}
|
||||
//inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
pitime.h
2
pitime.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
34
piusb.cpp
34
piusb.cpp
@@ -9,16 +9,19 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
REGISTER_DEVICE(PIUSB);
|
||||
|
||||
PIUSB::PIUSB(ushort vid, ushort pid): PIIODevice("", ReadWrite, false) {
|
||||
|
||||
PIUSB::PIUSB(ushort vid, ushort pid): PIIODevice("", ReadWrite) {
|
||||
vid_ = vid;
|
||||
pid_ = pid;
|
||||
path_ = PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0");
|
||||
dev_num = 1;
|
||||
intefrace_ = 0;
|
||||
hdev = 0;
|
||||
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() {
|
||||
#ifdef PIP_USB
|
||||
if (path_.size_s() >= 8) {
|
||||
vid_ = path_.left(4).toInt(16);
|
||||
pid_ = path_.right(4).toInt(16);
|
||||
if (path().size_s() >= 8) {
|
||||
vid_ = path().left(4).toInt(16);
|
||||
pid_ = path().right(4).toInt(16);
|
||||
}
|
||||
if (hdev != 0) closeDevice();
|
||||
hdev = 0;
|
||||
@@ -172,7 +175,7 @@ bool PIUSB::openDevice() {
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
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);
|
||||
desc_.usb_spec_number = dd.bcdUSB;
|
||||
desc_.device_class = dd.bDeviceClass;
|
||||
@@ -383,3 +386,18 @@ PICout operator<<(PICout s, const PIUSB::Endpoint & v) {
|
||||
s.restoreControl();
|
||||
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
57
piusb.h
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,7 +27,9 @@
|
||||
|
||||
struct usb_dev_handle;
|
||||
|
||||
class PIP_EXPORT PIUSB: public PIIODevice {
|
||||
class PIP_EXPORT PIUSB: public PIIODevice
|
||||
{
|
||||
PIIODEVICE(PIUSB)
|
||||
public:
|
||||
PIUSB(ushort vid = 0, ushort pid = 0);
|
||||
|
||||
@@ -58,7 +60,7 @@ public:
|
||||
ushort class_code;
|
||||
ushort subclass_code;
|
||||
ushort protocol_code;
|
||||
PIVector<Endpoint> endpoints;
|
||||
PIVector<PIUSB::Endpoint> endpoints;
|
||||
};
|
||||
|
||||
struct Configuration {
|
||||
@@ -69,7 +71,7 @@ public:
|
||||
ushort max_power; // mA
|
||||
bool self_powered;
|
||||
bool remote_wakeup;
|
||||
PIVector<Interface> interfaces;
|
||||
PIVector<PIUSB::Interface> interfaces;
|
||||
};
|
||||
|
||||
struct Descriptor {
|
||||
@@ -85,37 +87,38 @@ public:
|
||||
uchar index_manufacturer;
|
||||
uchar index_product;
|
||||
uchar index_serial;
|
||||
PIVector<Configuration> configurations;
|
||||
PIVector<PIUSB::Configuration> configurations;
|
||||
};
|
||||
|
||||
const Descriptor & currentDescriptor() const {return desc_;}
|
||||
const Configuration & currentConfiguration() const {return conf_;}
|
||||
const Interface & currentInterface() const {return iface_;}
|
||||
const PIUSB::Descriptor & currentDescriptor() const {return desc_;}
|
||||
const PIUSB::Configuration & currentConfiguration() const {return conf_;}
|
||||
const PIUSB::Interface & currentInterface() const {return iface_;}
|
||||
|
||||
ushort vendorID() const {return vid_;}
|
||||
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;}
|
||||
PIVector<Endpoint> endpointsRead();
|
||||
PIVector<Endpoint> endpointsWrite();
|
||||
Endpoint getEndpointByAddress(uchar address);
|
||||
const PIVector<PIUSB::Endpoint> & endpoints() const {return eps;}
|
||||
PIVector<PIUSB::Endpoint> endpointsRead();
|
||||
PIVector<PIUSB::Endpoint> endpointsWrite();
|
||||
PIUSB::Endpoint getEndpointByAddress(uchar address);
|
||||
|
||||
const Endpoint & endpointRead() {return ep_read;}
|
||||
const Endpoint & endpointWrite() {return ep_write;}
|
||||
|
||||
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");}
|
||||
void setVendorID(ushort vid) {vid_ = vid; setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));}
|
||||
void setProductID(ushort pid) {pid_ = pid; setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));}
|
||||
|
||||
bool setConfiguration(uchar value);
|
||||
bool setInterface(uchar value);
|
||||
|
||||
void setEndpointRead(const Endpoint & ep) {ep_read = ep;}
|
||||
void setEndpointWrite(const Endpoint & ep) {ep_write = ep;}
|
||||
void setDeviceNumber(int dn) {dev_num = dn;}
|
||||
void setTimeoutRead(int t) {timeout_r = t;}
|
||||
void setTimeoutWrite(int t) {timeout_w = t;}
|
||||
void setEndpointRead(const PIUSB::Endpoint & ep) {ep_read = ep;}
|
||||
void setEndpointWrite(const PIUSB::Endpoint & ep) {ep_write = ep;}
|
||||
void setDeviceNumber(int dn) {setProperty("deviceNumber", dn);}
|
||||
void setTimeoutRead(int t) {setProperty("timeoutRead", t);}
|
||||
void setTimeoutWrite(int t) {setProperty("timeoutWrite", t);}
|
||||
|
||||
int read(void * read_to, int max_size);
|
||||
int write(const void * data, int max_size);
|
||||
@@ -124,16 +127,18 @@ public:
|
||||
void flush();
|
||||
|
||||
protected:
|
||||
PIString fullPathPrefix() const {return "usb";}
|
||||
void configureFromFullPath(const PIString & full_path);
|
||||
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
||||
//bool init();
|
||||
bool openDevice();
|
||||
bool closeDevice();
|
||||
|
||||
PIVector<Endpoint> eps;
|
||||
PIVector<PIUSB::Endpoint> eps;
|
||||
ushort vid_, pid_;
|
||||
int dev_num, intefrace_, timeout_r, timeout_w;
|
||||
int intefrace_, timeout_r, timeout_w;
|
||||
int interface_claimed;
|
||||
Endpoint ep_read, ep_write;
|
||||
PIUSB::Endpoint ep_read, ep_write;
|
||||
Descriptor desc_;
|
||||
Configuration conf_;
|
||||
Interface iface_;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
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;
|
||||
_vstring = v._vstring;
|
||||
_vstringlist = v._vstringlist;
|
||||
_vcustom = v._vcustom;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
bool PIVariant::operator ==(const PIVariant & v) const {
|
||||
if (type_ != v.type_) return false;
|
||||
switch (type_) {
|
||||
@@ -67,7 +68,7 @@ bool PIVariant::operator ==(const PIVariant & v) const {
|
||||
};
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
|
||||
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
|
||||
@@ -126,6 +127,7 @@ PIString PIVariant::typeName(PIVariant::Type type) {
|
||||
case PIVariant::Date: return "Date";
|
||||
case PIVariant::DateTime: return "DateTime";
|
||||
case PIVariant::SystemTime: return "SystemTime";
|
||||
case PIVariant::Custom: return "Custom";
|
||||
default: break;
|
||||
}
|
||||
return "Invalid";
|
||||
|
||||
101
pivariant.h
101
pivariant.h
@@ -47,6 +47,7 @@
|
||||
#define _vvsystime(v) (*((PISystemTime*)v._vraw))
|
||||
|
||||
class PIP_EXPORT PIVariant {
|
||||
friend PICout operator <<(PICout s, const PIVariant & v);
|
||||
public:
|
||||
enum Type {
|
||||
Invalid = 0,
|
||||
@@ -73,8 +74,8 @@ public:
|
||||
Time,
|
||||
Date,
|
||||
DateTime,
|
||||
SystemTime/*,
|
||||
Custom = 0xFF*/
|
||||
SystemTime,
|
||||
Custom = 0xFF
|
||||
};
|
||||
|
||||
PIVariant();
|
||||
@@ -147,6 +148,35 @@ public:
|
||||
PIBitArray toBitArray() 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 char * v) {setValue(PIString(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 {return !(*this == v);}
|
||||
|
||||
|
||||
PIVariant::Type type() const {return type_;}
|
||||
PIString typeName() const {return typeName(type_);}
|
||||
|
||||
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 PIString typeName(PIVariant::Type type);
|
||||
|
||||
private:
|
||||
void destroy() {_vcustom.clear();}
|
||||
|
||||
union {
|
||||
int _vint;
|
||||
llong _vllong;
|
||||
@@ -204,12 +240,71 @@ private:
|
||||
PIByteArray _vbytearray;
|
||||
PIString _vstring;
|
||||
PIStringList _vstringlist;
|
||||
PIByteArray _vcustom;
|
||||
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
|
||||
|
||||
11
pivector.h
11
pivector.h
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
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()) {
|
||||
if (new_size < piv_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> & append(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> & prepend(const T & v) {return push_front(v);}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
Reference in New Issue
Block a user