23.06.2014 - PICodeParser, PICodeInfo, PIConnection, new binary "pip_cmg"
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
Pelipenko Ivan (peri4) peri4ko@gmail.com
|
Pelipenko Ivan (peri4) peri4ko@yandex.ru
|
||||||
Bychkov Andrey (blizer) wapmobil@gmail.com
|
Bychkov Andrey () work.a.b@yandex.ru
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ project(pip)
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
set(VERSION "0.0308")
|
set(VERSION "0.0400")
|
||||||
set(SOVERSION ${VERSION})
|
set(SOVERSION ${VERSION})
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
set(LIBS)
|
set(LIBS)
|
||||||
@@ -83,7 +83,8 @@ else ()
|
|||||||
if (NOT APPLE)
|
if (NOT APPLE)
|
||||||
list(APPEND LIBS rt)
|
list(APPEND LIBS rt)
|
||||||
endif()
|
endif()
|
||||||
add_definitions("-Wall -g3")
|
add_definitions("-Wall")
|
||||||
|
add_definitions("-g3")
|
||||||
add_library(pip SHARED ${CPPS})
|
add_library(pip SHARED ${CPPS})
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
@@ -92,11 +93,11 @@ target_link_libraries(pip ${LIBS})
|
|||||||
|
|
||||||
|
|
||||||
# Test program
|
# Test program
|
||||||
#find_package(Qt4 REQUIRED)
|
find_package(Qt4 REQUIRED)
|
||||||
#include_directories(${QT_INCLUDES})
|
include_directories(${QT_INCLUDES})
|
||||||
add_executable(pip_test "main.cpp")
|
add_executable(pip_test "main.cpp")
|
||||||
#target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY})
|
target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY})
|
||||||
target_link_libraries(pip_test pip)
|
#target_link_libraries(pip_test pip)
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(system_test)
|
add_subdirectory(system_test)
|
||||||
|
|||||||
2
Doxyfile
2
Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = PIP
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.3.8
|
PROJECT_NUMBER = 0.4.0
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ void writeModel(PICodeParser & parser, const PIString out) {
|
|||||||
PIFile f(out + ".cpp");
|
PIFile f(out + ".cpp");
|
||||||
f.clear();
|
f.clear();
|
||||||
f.open(PIIODevice::WriteOnly);
|
f.open(PIIODevice::WriteOnly);
|
||||||
f << "// Generated by \"PIP Code model generator\" " << currentDateTime().toString("dd.MM.yyyy hh:mm:ss\n\n");
|
f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n");
|
||||||
f << "#include <string.h>\n#include \"" << out << ".h\"\n\nusing namespace PICodeInfo;\n\n";
|
f << "#include <string.h>\n#include \"" << out << ".h\"\n\nusing namespace PICodeInfo;\n\n";
|
||||||
piForeachC (PIString & i, inc_files)
|
piForeachC (PIString & i, inc_files)
|
||||||
f << "#include \"" << i << "\"\n";
|
f << "#include \"" << i << "\"\n";
|
||||||
@@ -180,7 +180,7 @@ void writeModel(PICodeParser & parser, const PIString out) {
|
|||||||
f.setPath(out + ".h");
|
f.setPath(out + ".h");
|
||||||
f.clear();
|
f.clear();
|
||||||
f.open(PIIODevice::WriteOnly);
|
f.open(PIIODevice::WriteOnly);
|
||||||
f << "// Generated by \"PIP Code model generator\" " << currentDateTime().toString("dd.MM.yyyy hh:mm:ss\n\n");
|
f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n");
|
||||||
f << "#ifndef " << defname << "\n#define " << defname << "\n\n";
|
f << "#ifndef " << defname << "\n#define " << defname << "\n\n";
|
||||||
f << "#include \"pivariant.h\"\n#include \"picodeinfo.h\"\n\n";
|
f << "#include \"pivariant.h\"\n#include \"picodeinfo.h\"\n\n";
|
||||||
piForeachC (PICodeParser::Entity * e, ventities)
|
piForeachC (PICodeParser::Entity * e, ventities)
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ int main(int argc, char * argv[]) {
|
|||||||
execFunction(&tm, "stop");
|
execFunction(&tm, "stop");
|
||||||
execFunction(&tm, "stop_");
|
execFunction(&tm, "stop_");
|
||||||
piMSleep(1000);*/
|
piMSleep(1000);*/
|
||||||
typedef std::pair<PIString, PICodeInfo::ClassInfo * > mpair;
|
typedef PIMap<PIString, PICodeInfo::ClassInfo* >::value_type mpair;
|
||||||
piForeachC (mpair & i, *(PICodeInfo::classesInfo))
|
piForeachC (mpair & i, *(PICodeInfo::classesInfo))
|
||||||
piCout << *i.second;
|
piCout << *i.second;
|
||||||
piCout << "\n\n";
|
piCout << "\n\n";
|
||||||
typedef std::pair<PIString, PICodeInfo::EnumInfo * > epair;
|
typedef PIMap<PIString, PICodeInfo::EnumInfo * >::value_type epair;
|
||||||
piForeachC (epair & i, *(PICodeInfo::enumsInfo))
|
piForeachC (epair & i, *(PICodeInfo::enumsInfo))
|
||||||
piCout << *i.second;
|
piCout << *i.second;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
7084
code_model_generator/test.cpp
Normal file
7084
code_model_generator/test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
100
code_model_generator/test.h
Normal file
100
code_model_generator/test.h
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Generated by "PIP Code model generator" 29.04.2014 18:03:05
|
||||||
|
|
||||||
|
#ifndef TEST_H
|
||||||
|
#define TEST_H
|
||||||
|
|
||||||
|
#include "pivariant.h"
|
||||||
|
#include "picodeinfo.h"
|
||||||
|
|
||||||
|
class PIMutex;
|
||||||
|
class PIBitArray;
|
||||||
|
class PIHuffman;
|
||||||
|
class PIByteArray;
|
||||||
|
class PIChar;
|
||||||
|
class PIString;
|
||||||
|
class PIStringList;
|
||||||
|
class PISystemTime;
|
||||||
|
struct PITime;
|
||||||
|
struct PIDate;
|
||||||
|
struct PIDateTime;
|
||||||
|
class Solver;
|
||||||
|
class PIFFT;
|
||||||
|
class PIVariant;
|
||||||
|
class PIObject;
|
||||||
|
class PIThread;
|
||||||
|
class PITimer;
|
||||||
|
class PIKbdListener;
|
||||||
|
class PIIODevice;
|
||||||
|
class PISerial;
|
||||||
|
class PIFile;
|
||||||
|
class PIProcess;
|
||||||
|
class PIEthernet;
|
||||||
|
class PIPacketExtractor;
|
||||||
|
class PIConfig;
|
||||||
|
class PIMultiProtocolBase;
|
||||||
|
class PIProtocol;
|
||||||
|
class PIDiagnostics;
|
||||||
|
class PISystemMonitor;
|
||||||
|
class PIConsole;
|
||||||
|
class PICLI;
|
||||||
|
class PIEvaluatorContent;
|
||||||
|
class PIEvaluator;
|
||||||
|
class PIMultiProtocol;
|
||||||
|
class PIRepeater;
|
||||||
|
class PICodec;
|
||||||
|
class PIPeer;
|
||||||
|
class PIBinaryLog;
|
||||||
|
class PIUSB;
|
||||||
|
|
||||||
|
|
||||||
|
PIVariant execFunction(PIMutex * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIBitArray * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIHuffman * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIByteArray * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIChar * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIString * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIStringList * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PISystemTime * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PITime * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIDate * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIDateTime * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(Solver * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIFFT * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIVariant * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIObject * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIThread * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PITimer * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIKbdListener * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIIODevice * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PISerial * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIFile * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIProcess * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIEthernet * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIPacketExtractor * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIConfig * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIMultiProtocolBase * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIProtocol * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIDiagnostics * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PISystemMonitor * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIConsole * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PICLI * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIEvaluatorContent * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIEvaluator * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIMultiProtocol * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIRepeater * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PICodec * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIPeer * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIBinaryLog * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
PIVariant execFunction(PIUSB * object, const char * function, const PIVariant & arg0 = PIVariant(), const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());
|
||||||
|
|
||||||
|
|
||||||
|
class __ClassInfo_TEST_H_Initializer__ {
|
||||||
|
public:
|
||||||
|
__ClassInfo_TEST_H_Initializer__();
|
||||||
|
static bool _inited_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static __ClassInfo_TEST_H_Initializer__ __classinfo_test_h_initializer__;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TEST_H
|
||||||
223
main.cpp
223
main.cpp
@@ -46,90 +46,119 @@ class ElementD: public PIObject {
|
|||||||
#include "pip.h"
|
#include "pip.h"
|
||||||
#include "pivariant.h"
|
#include "pivariant.h"
|
||||||
|
|
||||||
/*
|
|
||||||
Test::PIVariant<> * pv;
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
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 "picodeparser.h"
|
#include "picodeparser.h"
|
||||||
|
#include "pidir.h"
|
||||||
|
#include "piconnection.h"
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
#define S(a, b) a#b
|
bool readed(void*, uchar * data, int size) {
|
||||||
|
piCout << Hex << "readed" << PIByteArray(data, size);
|
||||||
enum TypeFlag {NoFlag, Const = 0x01, Static = 0x02, Mutable = 0x04, Volatile = 0x08, Inline = 0x10, Virtual = 0x20};
|
//piCout << PIString((char*)data, size);
|
||||||
typedef PIFlags<TypeFlag> TypeFlags;
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class A: public PIObject {
|
||||||
|
PIOBJECT(A)
|
||||||
|
public:
|
||||||
|
EVENT_HANDLER2(void, cr, const PIString &, from, const PIByteArray &, data) {
|
||||||
|
piCout << "A readed" << from << Hex << data;
|
||||||
|
}
|
||||||
|
EVENT_HANDLER2(void, per, uchar *, data, int, size) {
|
||||||
|
piCout << "A readed" << size << ":\"" << PIString((const char *)data, size) << "\"" << NewLine;
|
||||||
|
//piCout << "A readed \"";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TC: public PIConnection {
|
||||||
|
public:
|
||||||
|
TC() {
|
||||||
|
PIPacketExtractor * pe = addFilter("h&f", addDevice("file://piiodevice.h", PIIODevice::ReadOnly, false), PIPacketExtractor::HeaderAndFooter);
|
||||||
|
pe->setHeader(PIString("//!").toByteArray());
|
||||||
|
pe->setFooter(PIString("\n").toByteArray());
|
||||||
|
pe = addFilter(" h ", "file://piiodevice.h", PIPacketExtractor::Header);
|
||||||
|
addChannel(pe, addDevice("file://out.txt", PIIODevice::WriteOnly));
|
||||||
|
pe->setHeader(PIString("PI").toByteArray());
|
||||||
|
pe->setPayloadSize(3);
|
||||||
|
startAllThreadedReads();
|
||||||
|
}
|
||||||
|
virtual void dataReceived(const PIString & from, const PIByteArray & data) {
|
||||||
|
piCout << "dataReceived" << from << (data.size());
|
||||||
|
}
|
||||||
|
virtual void packetReceived(const PIString & from, const PIByteArray & data) {
|
||||||
|
piCout << "packetReceived" << from << (data.size()) << PIString(data);
|
||||||
|
}
|
||||||
|
virtual bool filterValidatePayload(const PIString & filter_name, uchar * rec, int size) {
|
||||||
|
//piCout << "filterValidatePayload" << filter_name << PIString((char*)rec, size);
|
||||||
|
if (filter_name == " h ") return PIString((char*)rec, size) == "IOD";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main (int argc, char * argv[]) {
|
int main (int argc, char * argv[]) {
|
||||||
PIString s("this\t :is \n(SPARTA)!");
|
/*A a_;
|
||||||
piCout << s.findCWord("this");
|
PIFile file("piiodevice.h", PIIODevice::ReadOnly);
|
||||||
piCout << s.findCWord("is");
|
PIByteArray header = PIString("PI").toByteArray();
|
||||||
piCout << s.findCWord("SPARTA");
|
PIByteArray footer = PIString("}").toByteArray();
|
||||||
piCout << s.findCWord("SPARTA!");
|
PIPacketExtractor pe(&file);
|
||||||
|
//pe.setPacketData(header.data(), header.size_s(), 10);
|
||||||
|
pe.setSplitMode(PIPacketExtractor::Footer);
|
||||||
|
pe.setHeader(header);
|
||||||
|
pe.setFooter(footer);
|
||||||
|
pe.setPayloadSize(3);
|
||||||
|
pe.setThreadedReadBufferSize(40);
|
||||||
|
//pe.setBufferSize(256);
|
||||||
|
//pe.setPacketData(0, 0, 20);
|
||||||
|
CONNECT2(void, uchar * , int , &pe, packetReceived, &a_, per)
|
||||||
|
pe.startThreadedRead();
|
||||||
|
piMSleep(500);*/
|
||||||
|
|
||||||
|
TC tc;
|
||||||
|
piMSleep(500);
|
||||||
|
piCout << tc.makeConfig();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*tm = PISystemTime::current();
|
||||||
|
for (int i = 0; i < 10000000; ++i) {
|
||||||
|
ql.append(i*10);
|
||||||
|
ql.prepend(i*10 + 1);
|
||||||
|
}
|
||||||
|
piCout << (PISystemTime::current() - tm).toMicroseconds();
|
||||||
|
*/
|
||||||
|
//tm = PISystemTime::current();
|
||||||
|
/*for (int i = 0; i < 100000000; ++i) {
|
||||||
|
pl.append(i*10);
|
||||||
|
pl.prepend(i*10 + 1);
|
||||||
|
}*/
|
||||||
|
//PICodeParser cd_;
|
||||||
|
//cd.includeDirectory("../qpicalculator");
|
||||||
|
//cd_.parseFile("piincludes.h");
|
||||||
|
//piCout << (PISystemTime::current() - tm).toMilliseconds();
|
||||||
|
/*piCout << NewLine;
|
||||||
|
piForeachCA (i, pl)
|
||||||
|
piCout << i;
|
||||||
|
|
||||||
|
pl.remove(1, 2).prepend(111).prepend(222);
|
||||||
|
pl.remove(1, 1);
|
||||||
|
piCout << NewLine;
|
||||||
|
piForeachCA (i, pl)
|
||||||
|
piCout << i;*/
|
||||||
|
/*piCout << NewLine;
|
||||||
|
for (int i = 0; i < pl.size_s(); ++i)
|
||||||
|
piCout << pl[i];
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*PIEthernet eth(PIEthernet::UDP);
|
||||||
|
eth.setReadAddress("192.168.0.30:4001");
|
||||||
|
eth.setSendAddress("192.168.0.50:4001");
|
||||||
|
eth.startThreadedRead(readed);
|
||||||
|
piCout << "Connected";
|
||||||
|
//eth.send(PIString("This is test string!\n").toByteArray());
|
||||||
|
FOREVER_WAIT*/
|
||||||
|
|
||||||
if (argc < 2) return 0;
|
if (argc < 2) return 0;
|
||||||
PICodeParser cd;
|
PICodeParser cd;
|
||||||
//cd.includeDirectory("../qpicalculator");
|
//cd.includeDirectory("../qpicalculator");
|
||||||
@@ -137,48 +166,6 @@ int main (int argc, char * argv[]) {
|
|||||||
piForeachC (PICodeParser::Enum & e, cd.enums)
|
piForeachC (PICodeParser::Enum & e, cd.enums)
|
||||||
piCout << e.name << e.members;
|
piCout << e.name << e.members;
|
||||||
|
|
||||||
ClassInfo ci;
|
|
||||||
PICodeParser::Entity * e = cd.findEntityByName("PITimer");
|
|
||||||
if (!e) return 0;
|
|
||||||
ci.name = e->name;
|
|
||||||
piForeachC (PICodeParser::Entity * p, e->parents)
|
|
||||||
ci.parents << p->name;
|
|
||||||
piForeachC (PICodeParser::Member & m, e->members) {
|
|
||||||
TypeInfo ni;
|
|
||||||
ni.name = m.name;
|
|
||||||
ni.type = m.type;
|
|
||||||
if (m.attributes[PICodeParser::Const]) ni.flags |= Const;
|
|
||||||
if (m.attributes[PICodeParser::Static]) ni.flags |= Static;
|
|
||||||
if (m.attributes[PICodeParser::Mutable]) ni.flags |= Mutable;
|
|
||||||
if (m.attributes[PICodeParser::Volatile]) ni.flags |= Volatile;
|
|
||||||
if (m.attributes[PICodeParser::Inline]) ni.flags |= Inline;
|
|
||||||
if (m.attributes[PICodeParser::Virtual]) ni.flags |= Virtual;
|
|
||||||
ci.variables << ni;
|
|
||||||
}
|
|
||||||
piForeachC (PICodeParser::Member & m, e->functions) {
|
|
||||||
FunctionInfo fi;
|
|
||||||
fi.name = m.name;
|
|
||||||
fi.return_type.type = m.type;
|
|
||||||
if (m.attributes[PICodeParser::Const]) fi.return_type.flags |= Const;
|
|
||||||
if (m.attributes[PICodeParser::Static]) fi.return_type.flags |= Static;
|
|
||||||
piForeachC (PIString & a, m.arguments_full) {
|
|
||||||
TypeInfo ni;
|
|
||||||
PIString arg(a);
|
|
||||||
arg.prepend(" ");
|
|
||||||
if (arg.find(" const ") >= 0) {
|
|
||||||
ni.flags |= Const;
|
|
||||||
arg.replaceAll(" const ", " ");
|
|
||||||
}
|
|
||||||
int ts = 0;
|
|
||||||
for (ts = arg.size_s() - 1; ts >= 0; --ts)
|
|
||||||
if (!_isCChar(arg[ts]) && !(arg[ts].isDigit())) break;
|
|
||||||
ni.name = arg.takeRight(arg.size_s() - ts - 1).trim();
|
|
||||||
ni.type = arg.trim();
|
|
||||||
fi.arguments << ni;
|
|
||||||
}
|
|
||||||
ci.functions << fi;
|
|
||||||
}
|
|
||||||
piCout << NewLine << ci;
|
|
||||||
|
|
||||||
//piCout << v.toType<float>();
|
//piCout << v.toType<float>();
|
||||||
//piCout << v.toType<float>().toType<PIString>();
|
//piCout << v.toType<float>().toType<PIString>();
|
||||||
|
|||||||
0
make_lib.bat
Executable file → Normal file
0
make_lib.bat
Executable file → Normal file
0
make_rc_win.bat
Executable file → Normal file
0
make_rc_win.bat
Executable file → Normal file
@@ -94,12 +94,12 @@ bool PIBinaryLog::openDevice() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isEmpty()) piCoutObj << "Error: Empty BinLog file";
|
if (isEmpty()) piCoutObj << "Error: Empty BinLog file";
|
||||||
// startlogtime = currentSystemTime();
|
// startlogtime = PISystemTime::current();
|
||||||
play_time = 0;
|
play_time = 0;
|
||||||
// nextrecord = readsRecord();
|
// nextrecord = readsRecord();
|
||||||
if (!rapidStart()) is_started = true;
|
if (!rapidStart()) is_started = true;
|
||||||
}
|
}
|
||||||
startlogtime = currentSystemTime();
|
startlogtime = PISystemTime::current();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
double delay;
|
double delay;
|
||||||
switch (playMode()) {
|
switch (playMode()) {
|
||||||
case PlayRealTime:
|
case PlayRealTime:
|
||||||
pt = currentSystemTime() - startlogtime;
|
pt = PISystemTime::current() - startlogtime;
|
||||||
// if (real_speedX > 0)
|
// if (real_speedX > 0)
|
||||||
// for (int i=0; i<real_speedX-1; i++) pt += pt;
|
// for (int i=0; i<real_speedX-1; i++) pt += pt;
|
||||||
// piCout << pt << lastrecord.timestamp << lastrecord.timestamp - pt;
|
// piCout << pt << lastrecord.timestamp << lastrecord.timestamp - pt;
|
||||||
@@ -127,10 +127,10 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
if (lastrecord.timestamp > pt)
|
if (lastrecord.timestamp > pt)
|
||||||
(lastrecord.timestamp - pt).sleep();
|
(lastrecord.timestamp - pt).sleep();
|
||||||
} else {
|
} else {
|
||||||
startlogtime = currentSystemTime() - lastrecord.timestamp;
|
startlogtime = PISystemTime::current() - lastrecord.timestamp;
|
||||||
is_started = true;
|
is_started = true;
|
||||||
}
|
}
|
||||||
// int delay = piRoundd(lastread_timestamp.toMilliseconds() - (currentSystemTime() - startlogtime).toMilliseconds());
|
// int delay = piRoundd(lastread_timestamp.toMilliseconds() - (PISystemTime::current() - startlogtime).toMilliseconds());
|
||||||
break;
|
break;
|
||||||
case PlayVariableSpeed:
|
case PlayVariableSpeed:
|
||||||
delay = lastrecord.timestamp.toMilliseconds() - play_time;
|
delay = lastrecord.timestamp.toMilliseconds() - play_time;
|
||||||
@@ -152,7 +152,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
|
|
||||||
PIString PIBinaryLog::createNewFile() {
|
PIString PIBinaryLog::createNewFile() {
|
||||||
if (!file.close()) return PIString();
|
if (!file.close()) return PIString();
|
||||||
if (open(logDir() + "/" + filePrefix() + currentDateTime().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly))
|
if (open(logDir() + "/" + filePrefix() + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly))
|
||||||
return file.path();
|
return file.path();
|
||||||
piCoutObj << "Can't create new file, maybe LogDir is invalid.";
|
piCoutObj << "Can't create new file, maybe LogDir is invalid.";
|
||||||
return PIString();
|
return PIString();
|
||||||
@@ -162,7 +162,7 @@ PIString PIBinaryLog::createNewFile() {
|
|||||||
int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
||||||
if (size <= 0 || !canWrite()) return -1;
|
if (size <= 0 || !canWrite()) return -1;
|
||||||
PIByteArray logdata;
|
PIByteArray logdata;
|
||||||
logdata << id << size << (currentSystemTime() - startlogtime) << PIByteArray::RawData(data, size);
|
logdata << id << size << (PISystemTime::current() - startlogtime) << PIByteArray::RawData(data, size);
|
||||||
int res = file.write(logdata.data(), logdata.size());
|
int res = file.write(logdata.data(), logdata.size());
|
||||||
file.flush();
|
file.flush();
|
||||||
if (res > 0) return size;
|
if (res > 0) return size;
|
||||||
@@ -242,7 +242,7 @@ void PIBinaryLog::restart() {
|
|||||||
play_time = 0;
|
play_time = 0;
|
||||||
file.seekToBegin();
|
file.seekToBegin();
|
||||||
checkFileHeader();
|
checkFileHeader();
|
||||||
startlogtime = currentSystemTime();
|
startlogtime = PISystemTime::current();
|
||||||
if (th) startThreadedRead();
|
if (th) startThreadedRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,6 +306,13 @@ PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIBinaryLog::constructFullPath() const {
|
||||||
|
PIString ret(fullPathPrefix() + "://");
|
||||||
|
ret << logDir() << ":" << filePrefix() << ":" << defaultID();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBinaryLog::configureFromFullPath(const PIString & full_path) {
|
void PIBinaryLog::configureFromFullPath(const PIString & full_path) {
|
||||||
PIStringList pl = full_path.split(":");
|
PIStringList pl = full_path.split(":");
|
||||||
for (int i = 0; i < pl.size_s(); ++i) {
|
for (int i = 0; i < pl.size_s(); ++i) {
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ public:
|
|||||||
//! Go to begin of BinLog file
|
//! Go to begin of BinLog file
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
//! \handlers
|
//! \handlers
|
||||||
//! \{
|
//! \{
|
||||||
|
|||||||
156
pibytearray.cpp
156
pibytearray.cpp
@@ -18,23 +18,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
|
#include "pistring.h"
|
||||||
|
|
||||||
/*! \class PIByteArray
|
/*! \class PIByteArray
|
||||||
* \brief Byte array
|
* \brief Byte array
|
||||||
* \details This class based on PIVector<uchar> and provide some handle function
|
* \details This class based on PIDeque<uchar> and provide some handle function
|
||||||
* to manipulate it.
|
* to manipulate it.
|
||||||
*
|
*
|
||||||
* \section PIByteArray_sec0 Usage
|
* \section PIByteArray_sec0 Usage
|
||||||
* %PIByteArray can be used to store custom data and manipulate it. There are many
|
* %PIByteArray can be used to store custom data and manipulate it. There are many
|
||||||
* stream operators to store/restore common types to byte array. Store operators
|
* stream operators to store/restore common types to byte array. Store operators
|
||||||
* places data at the end of arraym restore operators takes data from the beginning
|
* places data at the end of array, restore operators takes data from the beginning
|
||||||
* of array.
|
* of array.
|
||||||
* In addition there are Base 64 convertions and checksums:
|
* In addition there are Base 64 convertions and checksums:
|
||||||
* * plain 8-bit
|
* * plain 8-bit
|
||||||
* * plain 32-bit
|
* * plain 32-bit
|
||||||
* * CRC 8-bit
|
|
||||||
* * CRC 16-bit
|
|
||||||
* * CRC 32-bit
|
|
||||||
*
|
*
|
||||||
* One of the major usage of %PIByteArray is stream functions. You can form binary
|
* One of the major usage of %PIByteArray is stream functions. You can form binary
|
||||||
* packet from many types (also dynamic types, e.g. PIVector) with one line:
|
* packet from many types (also dynamic types, e.g. PIVector) with one line:
|
||||||
@@ -114,13 +112,13 @@ int PIHuffman::nodeCompare(const void * f, const void * s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIVector<uchar> PIHuffman::compress(const PIVector<uchar> & src) {
|
PIDeque<uchar> PIHuffman::compress(const PIDeque<uchar> & src) {
|
||||||
calcFrequencies(src);
|
calcFrequencies(src);
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIHuffman::calcFrequencies(const PIVector<uchar> & src) {
|
void PIHuffman::calcFrequencies(const PIDeque<uchar> & src) {
|
||||||
nodes.resize(256);
|
nodes.resize(256);
|
||||||
for (int i = 0; i < 256; ++i) {
|
for (int i = 0; i < 256; ++i) {
|
||||||
nodes[i].parent = nodes[i].right = nodes[i].left = 0;
|
nodes[i].parent = nodes[i].right = nodes[i].left = 0;
|
||||||
@@ -247,7 +245,7 @@ PIByteArray & PIByteArray::decompressRLE(uchar threshold) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar PIByteArray::checksumPlain8() {
|
uchar PIByteArray::checksumPlain8() const {
|
||||||
uchar c = 0;
|
uchar c = 0;
|
||||||
int sz = size_s();
|
int sz = size_s();
|
||||||
for (int i = 0; i < sz; ++i)
|
for (int i = 0; i < sz; ++i)
|
||||||
@@ -257,7 +255,7 @@ uchar PIByteArray::checksumPlain8() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint PIByteArray::checksumPlain32() {
|
uint PIByteArray::checksumPlain32() const {
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
int sz = size_s();
|
int sz = size_s();
|
||||||
for (int i = 0; i < sz; ++i)
|
for (int i = 0; i < sz; ++i)
|
||||||
@@ -267,137 +265,29 @@ uint PIByteArray::checksumPlain32() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar PIByteArray::checksumCRC8() {
|
PIString PIByteArray::toString(int base) const {
|
||||||
const uchar CRC8Table[256] = {
|
PIString ret;
|
||||||
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
|
|
||||||
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
|
|
||||||
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
|
|
||||||
0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
|
|
||||||
0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
|
|
||||||
0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
|
|
||||||
0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
|
|
||||||
0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
|
|
||||||
0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
|
|
||||||
0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
|
|
||||||
0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
|
|
||||||
0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
|
|
||||||
0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
|
|
||||||
0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
|
|
||||||
0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
|
|
||||||
0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
|
|
||||||
0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
|
|
||||||
0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
|
|
||||||
0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
|
|
||||||
0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
|
|
||||||
0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
|
|
||||||
0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
|
|
||||||
0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
|
|
||||||
0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
|
|
||||||
0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
|
|
||||||
0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
|
|
||||||
0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
|
|
||||||
0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
|
|
||||||
0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
|
|
||||||
0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
|
|
||||||
0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
|
|
||||||
0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC};
|
|
||||||
int sz = size_s();
|
int sz = size_s();
|
||||||
ushort ret = 0xFF;
|
|
||||||
for (int i = 0; i < sz; ++i)
|
|
||||||
ret = CRC8Table[at(i) ^ ret];
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ushort PIByteArray::checksumCRC16() {
|
|
||||||
const ushort CRC16Table[256] = {
|
|
||||||
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
|
||||||
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
|
||||||
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
|
||||||
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
|
||||||
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
|
||||||
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
|
||||||
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
|
||||||
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
|
||||||
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
|
||||||
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
|
||||||
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
|
||||||
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
|
||||||
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
|
||||||
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
|
||||||
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
|
||||||
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
|
||||||
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
|
||||||
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
|
||||||
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
|
||||||
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
|
||||||
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
|
||||||
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
|
||||||
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
|
||||||
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
|
||||||
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
|
||||||
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
|
||||||
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
|
||||||
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
|
||||||
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
|
||||||
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
|
||||||
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
|
||||||
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};
|
|
||||||
|
|
||||||
int sz = size_s();
|
|
||||||
uchar nTemp;
|
|
||||||
ushort ret = 0xFFFF;
|
|
||||||
for (int i = 0; i < sz; ++i) {
|
for (int i = 0; i < sz; ++i) {
|
||||||
nTemp = at(i) ^ ret;
|
if (i > 0) ret += " ";
|
||||||
ret >>= 8;
|
if (base == 2) ret += "b";
|
||||||
ret ^= CRC16Table[nTemp];
|
if (base == 8) ret += "0";
|
||||||
|
if (base == 16) ret += "0x";
|
||||||
|
ret += PIString::fromNumber(at(i), base);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint PIByteArray::checksumCRC32() {
|
PIByteArray PIByteArray::fromString(PIString str) {
|
||||||
const uint CRC32Table[256] = {
|
PIByteArray ret;
|
||||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
if (str.trim().isEmpty()) return ret;
|
||||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
str.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ");
|
||||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
PIStringList bl(str.split(" "));
|
||||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
bool ok(false);
|
||||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
piForeachC (PIString & b, bl) {
|
||||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
int bv = b.toInt(-1, &ok);
|
||||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
if (ok) ret << uchar(bv);
|
||||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
|
||||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
|
||||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
|
||||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
|
||||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
|
||||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
|
||||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
|
||||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
|
||||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
|
||||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
|
||||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
|
||||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
|
||||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
|
||||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
|
||||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
|
||||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
|
||||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
|
||||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
|
||||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
|
||||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
|
||||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
|
||||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
|
||||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
|
||||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
|
||||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
|
|
||||||
|
|
||||||
int sz = size_s();
|
|
||||||
uchar nTemp;
|
|
||||||
uint ret = 0xFFFFFFFF;
|
|
||||||
for (int i = 0; i < sz; ++i) {
|
|
||||||
nTemp = at(i) ^ ret;
|
|
||||||
ret >>= 8;
|
|
||||||
ret ^= CRC32Table[nTemp];
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,27 +30,28 @@
|
|||||||
|
|
||||||
#include "pibitarray.h"
|
#include "pibitarray.h"
|
||||||
|
|
||||||
|
class PIString;
|
||||||
class PIByteArray;
|
class PIByteArray;
|
||||||
|
|
||||||
class PIHuffman {
|
class PIHuffman {
|
||||||
public:
|
public:
|
||||||
PIVector<uchar> compress(const PIVector<uchar> & src);
|
PIDeque<uchar> compress(const PIDeque<uchar> & src);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct node {
|
struct node {
|
||||||
int freq;
|
int freq;
|
||||||
PIVector<uchar> word;
|
PIDeque<uchar> word;
|
||||||
PIBitArray path;
|
PIBitArray path;
|
||||||
node * parent;
|
node * parent;
|
||||||
node * right;
|
node * right;
|
||||||
node * left;
|
node * left;
|
||||||
};
|
};
|
||||||
static int nodeCompare(const void * f, const void * s);
|
static int nodeCompare(const void * f, const void * s);
|
||||||
void calcFrequencies(const PIVector<uchar> & src);
|
void calcFrequencies(const PIDeque<uchar> & src);
|
||||||
PIVector<node> nodes;
|
PIVector<node> nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PIP_EXPORT PIByteArray: public PIVector<uchar>
|
class PIP_EXPORT PIByteArray: public PIDeque<uchar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ public:
|
|||||||
PIByteArray(const uint size) {resize(size);}
|
PIByteArray(const uint size) {resize(size);}
|
||||||
|
|
||||||
//! Constructs byte array from data "data" and size "size"
|
//! Constructs byte array from data "data" and size "size"
|
||||||
PIByteArray(const void * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);}
|
PIByteArray(const void * data, const uint size): PIDeque<uchar>((const uchar*)data, size_t(size)) {/*for (uint i = 0; i < size; ++i) push_back(((uchar * )data)[i]);*/}
|
||||||
|
|
||||||
|
|
||||||
//! Help struct to store/restore custom blocks of data to/from PIByteArray
|
//! Help struct to store/restore custom blocks of data to/from PIByteArray
|
||||||
@@ -80,7 +81,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Return resized byte array
|
//! Return resized byte array
|
||||||
PIByteArray resized(int new_size) {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
PIByteArray resized(int new_size) const {PIByteArray tv(*this); tv.resize(new_size); return tv;}
|
||||||
|
|
||||||
//! Convert data to Base 64 and return this byte array
|
//! Convert data to Base 64 and return this byte array
|
||||||
PIByteArray & convertToBase64();
|
PIByteArray & convertToBase64();
|
||||||
@@ -89,10 +90,10 @@ public:
|
|||||||
PIByteArray & convertFromBase64();
|
PIByteArray & convertFromBase64();
|
||||||
|
|
||||||
//! Return converted to Base 64 data
|
//! Return converted to Base 64 data
|
||||||
PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
|
PIByteArray toBase64() const {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
|
||||||
|
|
||||||
//! Return converted from Base 64 data
|
//! Return converted from Base 64 data
|
||||||
PIByteArray fromBase64() {PIByteArray ba(*this); ba.convertFromBase64(); return ba;}
|
PIByteArray fromBase64() const {PIByteArray ba(*this); ba.convertFromBase64(); return ba;}
|
||||||
|
|
||||||
PIByteArray & compressRLE(uchar threshold = 192);
|
PIByteArray & compressRLE(uchar threshold = 192);
|
||||||
PIByteArray & decompressRLE(uchar threshold = 192);
|
PIByteArray & decompressRLE(uchar threshold = 192);
|
||||||
@@ -101,6 +102,8 @@ public:
|
|||||||
|
|
||||||
PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
|
PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
|
||||||
|
|
||||||
|
PIString toString(int base = 16) const;
|
||||||
|
|
||||||
//! Add to the end data "data" with size "size"
|
//! Add to the end data "data" with size "size"
|
||||||
PIByteArray & append(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
|
PIByteArray & append(const void * data_, int size_) {uint ps = size(); enlarge(size_); memcpy(data(ps), data_, size_); return *this;}
|
||||||
|
|
||||||
@@ -115,21 +118,14 @@ public:
|
|||||||
//PIByteArray & operator <<(const PIByteArray & v) {for (uint i = 0; i < v.size(); ++i) push_back(v[i]); return *this;}
|
//PIByteArray & operator <<(const PIByteArray & v) {for (uint i = 0; i < v.size(); ++i) push_back(v[i]); return *this;}
|
||||||
|
|
||||||
//! Returns plain 8-bit checksum
|
//! Returns plain 8-bit checksum
|
||||||
uchar checksumPlain8();
|
uchar checksumPlain8() const;
|
||||||
|
|
||||||
//! Returns plain 32-bit checksum
|
//! Returns plain 32-bit checksum
|
||||||
uint checksumPlain32();
|
uint checksumPlain32() const;
|
||||||
|
|
||||||
//! Returns CRC 8-bit checksum
|
void operator =(const PIDeque<uchar> & d) {resize(d.size()); memcpy(data(), d.data(), d.size());}
|
||||||
uchar checksumCRC8();
|
|
||||||
|
|
||||||
//! Returns CRC 16-bit checksum
|
static PIByteArray fromString(PIString str);
|
||||||
ushort checksumCRC16();
|
|
||||||
|
|
||||||
//! Returns CRC 32-bit checksum
|
|
||||||
uint checksumCRC32();
|
|
||||||
|
|
||||||
void operator =(const PIVector<uchar> & d) {resize(d.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = d[i];}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union base64HelpStruct {
|
union base64HelpStruct {
|
||||||
@@ -189,16 +185,19 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {s << v
|
|||||||
//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details
|
//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;}
|
||||||
//! \relatesalso PIByteArray \brief Store operator
|
//! \relatesalso PIByteArray \brief Store operator
|
||||||
template <typename T>
|
template<typename Type0, typename Type1>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
|
||||||
|
//! \relatesalso PIByteArray \brief Store operator
|
||||||
|
template<typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
//! \relatesalso PIByteArray \brief Store operator
|
//! \relatesalso PIByteArray \brief Store operator
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIList<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIList<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
//! \relatesalso PIByteArray \brief Store operator
|
//! \relatesalso PIByteArray \brief Store operator
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {s << v.size_s(); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
|
||||||
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
|
inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -232,19 +231,26 @@ inline PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {assert(s.siz
|
|||||||
//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
|
//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy(v.d, s.data(), v.s); s.remove(0, v.s); return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy(v.d, s.data(), v.s); s.remove(0, v.s); return s;}
|
||||||
//! \relatesalso PIByteArray \brief Restore operator
|
//! \relatesalso PIByteArray \brief Restore operator
|
||||||
template <typename T>
|
template<typename Type0, typename Type1>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
|
||||||
|
//! \relatesalso PIByteArray \brief Restore operator
|
||||||
|
template<typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
//! \relatesalso PIByteArray \brief Restore operator
|
//! \relatesalso PIByteArray \brief Restore operator
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIList<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIList<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
//! \relatesalso PIByteArray \brief Restore operator
|
//! \relatesalso PIByteArray \brief Restore operator
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
|
// //! \relatesalso PIByteArray \brief Restore operator
|
||||||
|
//template <typename Key, typename T>
|
||||||
|
//inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;}
|
||||||
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
#ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef PBA_OPERATOR_FROM
|
#undef PBA_OPERATOR_FROM
|
||||||
|
|
||||||
//! \relatesalso PIByteArray \brief Byte arrays compare operator
|
//! \relatesalso PIByteArray \brief Byte arrays compare operator
|
||||||
|
|||||||
2
pichar.h
2
pichar.h
@@ -155,7 +155,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(PIChar)
|
__PICONTAINERS_SIMPLE_TYPE__(PIChar)
|
||||||
|
|
||||||
//! Output operator to \c std::ostream
|
//! Output operator to \c std::ostream
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||||
|
|||||||
@@ -20,6 +20,22 @@
|
|||||||
#include "picodeinfo.h"
|
#include "picodeinfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIString PICodeInfo::EnumInfo::memberName(int value_) const {
|
||||||
|
piForeachC (PICodeInfo::EnumeratorInfo & e, members)
|
||||||
|
if (e.value == value_)
|
||||||
|
return e.name;
|
||||||
|
return PIString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
|
||||||
|
piForeachC (PICodeInfo::EnumeratorInfo & e, members)
|
||||||
|
if (e.name == name_)
|
||||||
|
return e.value;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
|
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
|
||||||
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
|
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ struct EnumeratorInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct EnumInfo {
|
struct EnumInfo {
|
||||||
|
PIString memberName(int value) const;
|
||||||
|
int memberValue(const PIString & name) const;
|
||||||
PIString name;
|
PIString name;
|
||||||
PIVector<PICodeInfo::EnumeratorInfo> members;
|
PIVector<PICodeInfo::EnumeratorInfo> members;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -110,10 +110,10 @@ public:
|
|||||||
Entry * parent() const {return _parent;}
|
Entry * parent() const {return _parent;}
|
||||||
|
|
||||||
//! Returns children count
|
//! Returns children count
|
||||||
int childCount() {return _children.size_s();}
|
int childCount() const {return _children.size_s();}
|
||||||
|
|
||||||
//! Returns children as \a PIConfig::Branch
|
//! Returns children as \a PIConfig::Branch
|
||||||
Branch & children() {_children.delim = delim; return _children;}
|
Branch & children() const {_children.delim = delim; return _children;}
|
||||||
|
|
||||||
//! Returns child at index "index"
|
//! Returns child at index "index"
|
||||||
Entry * child(const int index) const {return _children[index];}
|
Entry * child(const int index) const {return _children[index];}
|
||||||
@@ -303,7 +303,7 @@ public:
|
|||||||
|
|
||||||
static Entry _empty;
|
static Entry _empty;
|
||||||
Entry * _parent;
|
Entry * _parent;
|
||||||
Branch _children;
|
mutable Branch _children;
|
||||||
PIString _tab;
|
PIString _tab;
|
||||||
PIString _name;
|
PIString _name;
|
||||||
PIString _value;
|
PIString _value;
|
||||||
|
|||||||
764
piconnection.cpp
Normal file
764
piconnection.cpp
Normal file
@@ -0,0 +1,764 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Complex I/O point
|
||||||
|
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 "piconnection.h"
|
||||||
|
#include "piconfig.h"
|
||||||
|
|
||||||
|
/** \class PIConnection
|
||||||
|
* \brief Complex Input/Output point
|
||||||
|
*
|
||||||
|
* \section PIConnection_synopsis Synopsis
|
||||||
|
* %PIConnection provides abstract layer over physical devices,
|
||||||
|
* filtering and connecting data streams. Each %PIConnection
|
||||||
|
* works through Device Pool, so several %PIConnections can
|
||||||
|
* read from single physical device. General scheme:
|
||||||
|
* \image html piconnection.png
|
||||||
|
*
|
||||||
|
* \section PIConnection_pool Device pool concept
|
||||||
|
* Device pool is static object, single for each application, which
|
||||||
|
* contains unique devices. Each %PIConnection works with real devices
|
||||||
|
* through Device pool. Each device has assosiated thread for read
|
||||||
|
* and it can be started or stopped with %PIConnection functions
|
||||||
|
* \a startThreadedRead() and \a stopThreadedRead().
|
||||||
|
*
|
||||||
|
* \section PIConnection_config Configuration
|
||||||
|
* You can create %PIConnection from config file section or configure
|
||||||
|
* it later with function \a configureFromConfig(). Devices describes
|
||||||
|
* with its full pathes, for details see \ref PIIODevice_sec7. Example:
|
||||||
|
* \image html piconnection_conf.png
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIConnection * > PIConnection::_connections;
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::PIConnection(): PIObject() {
|
||||||
|
_connections << this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::PIConnection(const PIString & config, const PIString & name_): PIObject(name_) {
|
||||||
|
_connections << this;
|
||||||
|
configureFromConfig(config, name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::~PIConnection() {
|
||||||
|
__device_pool__->unboundConnection(this);
|
||||||
|
removeAllFilters();
|
||||||
|
_connections.removeAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::configureFromConfig(const PIString & conf_path, const PIString & name_) {
|
||||||
|
PIConfig conf(conf_path, PIIODevice::ReadOnly);
|
||||||
|
if (!conf.isOpened()) return false;
|
||||||
|
__device_pool__->unboundConnection(this);
|
||||||
|
removeAllChannels();
|
||||||
|
removeAllFilters();
|
||||||
|
removeAllDevices();
|
||||||
|
setName(name_);
|
||||||
|
PIConfig::Entry ce(conf.getValue(name_));
|
||||||
|
PIConfig::Branch db(ce.getValue("device").children()), fb(ce.getValue("filter").children()), cb(ce.getValue("channel").children());
|
||||||
|
PIStringList dev_list(ce.getValue("device").value());
|
||||||
|
piForeachC (PIConfig::Entry * e, db)
|
||||||
|
dev_list << e->value();
|
||||||
|
dev_list.removeStrings("");
|
||||||
|
piForeachC (PIString & s, dev_list) {
|
||||||
|
PIString fn(s);
|
||||||
|
PIIODevice::DeviceMode dm = PIIODevice::ReadWrite;
|
||||||
|
if (fn.find("(") > 0 && fn.find(")") > 0) {
|
||||||
|
PIString dms(fn.right(fn.length() - fn.find("(")).takeRange("(", ")").trim().toLowerCase().removeAll(" "));
|
||||||
|
//piCout << dms;
|
||||||
|
if (dms == "r" || dms == "ro" || dms == "read" || dms == "readonly")
|
||||||
|
dm = PIIODevice::ReadOnly;
|
||||||
|
if (dms == "w" || dms == "wo" || dms == "write" || dms == "writeonly")
|
||||||
|
dm = PIIODevice::WriteOnly;
|
||||||
|
fn.cutRight(fn.length() - fn.find("(") + 1).trim();
|
||||||
|
}
|
||||||
|
//piCout << fn;
|
||||||
|
PIIODevice * dev = addDevice(fn, dm);
|
||||||
|
if (dev) dev->setName(name_ + ".device." + s);
|
||||||
|
}
|
||||||
|
piForeachC (PIConfig::Entry * e, fb) {
|
||||||
|
PIPacketExtractor::SplitMode sm = PIPacketExtractor::None;
|
||||||
|
PIString sms(e->getValue("splitMode").value());
|
||||||
|
int smi = sms.toInt();
|
||||||
|
if (smi >= 1 && smi <= 5) sm = (PIPacketExtractor::SplitMode)smi;
|
||||||
|
else {
|
||||||
|
sms = sms.trim().toLowerCase();
|
||||||
|
if (sms.find("header") >= 0 && sms.find("footer") >= 0)
|
||||||
|
sm = PIPacketExtractor::HeaderAndFooter;
|
||||||
|
else {
|
||||||
|
if (sms.find("header") >= 0)
|
||||||
|
sm = PIPacketExtractor::Header;
|
||||||
|
else {
|
||||||
|
if (sms.find("footer") >= 0)
|
||||||
|
sm = PIPacketExtractor::Footer;
|
||||||
|
else {
|
||||||
|
if (sms.find("time") >= 0)
|
||||||
|
sm = PIPacketExtractor::Timeout;
|
||||||
|
else {
|
||||||
|
if (sms.find("size") >= 0)
|
||||||
|
sm = PIPacketExtractor::Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PIStringList devs(e->value());
|
||||||
|
PIConfig::Branch db(e->getValue("device").children());
|
||||||
|
piForeachC (PIConfig::Entry * e2, db)
|
||||||
|
devs << e2->value();
|
||||||
|
devs.removeStrings("");
|
||||||
|
if (devs.isEmpty()) continue;
|
||||||
|
PIPacketExtractor * pe = addFilter(e->name(), devs.front(), sm);
|
||||||
|
if (pe == 0) continue;
|
||||||
|
for (int i = 1; i < devs.size_s(); ++i)
|
||||||
|
addFilter(e->name(), devs[i], sm);
|
||||||
|
pe->setPayloadSize(e->getValue("payloadSize", pe->payloadSize()));
|
||||||
|
pe->setPacketSize(e->getValue("packetSize", pe->packetSize()));
|
||||||
|
pe->setTimeout(e->getValue("timeout", pe->timeout()));
|
||||||
|
pe->setHeader(PIByteArray::fromString(e->getValue("header", "").value()));
|
||||||
|
pe->setFooter(PIByteArray::fromString(e->getValue("footer", "").value()));
|
||||||
|
}
|
||||||
|
piForeachC (PIConfig::Entry * e, cb) {
|
||||||
|
PIString f(e->getValue("from").value()), t(e->getValue("to").value());
|
||||||
|
addChannel(f, t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIConnection::makeConfig() const {
|
||||||
|
PIString ret;
|
||||||
|
ret << "[" << name() << "]\n";
|
||||||
|
PIVector<PIIODevice * > devs(boundedDevices());
|
||||||
|
int dn(0);
|
||||||
|
piForeachC (PIIODevice * d, devs) {
|
||||||
|
ret << "device." << dn << " = " << d->constructFullPath(); ++dn;
|
||||||
|
if (d->mode() == PIIODevice::ReadOnly) ret << " (ro)";
|
||||||
|
if (d->mode() == PIIODevice::WriteOnly) ret << " (wo)";
|
||||||
|
ret << "\n";
|
||||||
|
}
|
||||||
|
piForeachC (PEPair & f, extractors) {
|
||||||
|
if (f.second == 0) continue;
|
||||||
|
if (f.second->extractor == 0) continue;
|
||||||
|
PIString prefix = "filter." + f.first;
|
||||||
|
for (int i = 0; i < f.second->devices.size_s(); ++i)
|
||||||
|
ret << prefix << ".device." << i << " = " << f.second->devices[i]->constructFullPath() << "\n";
|
||||||
|
ret << prefix << ".splitMode = ";
|
||||||
|
switch (f.second->extractor->splitMode()) {
|
||||||
|
case PIPacketExtractor::None: ret << "none"; break;
|
||||||
|
case PIPacketExtractor::Header: ret << "header"; break;
|
||||||
|
case PIPacketExtractor::Footer: ret << "footer"; break;
|
||||||
|
case PIPacketExtractor::HeaderAndFooter: ret << "header & footer"; break;
|
||||||
|
case PIPacketExtractor::Size: ret << "size"; break;
|
||||||
|
case PIPacketExtractor::Timeout: ret << "timeout"; break;
|
||||||
|
}
|
||||||
|
ret << "\n";
|
||||||
|
ret << prefix << ".payloadSize = " << f.second->extractor->payloadSize() << "\n";
|
||||||
|
ret << prefix << ".packetSize = " << f.second->extractor->packetSize() << "\n";
|
||||||
|
ret << prefix << ".timeout = " << f.second->extractor->timeout() << "\n";
|
||||||
|
ret << prefix << ".header = " << f.second->extractor->header().toString() << "\n";
|
||||||
|
ret << prefix << ".footer = " << f.second->extractor->footer().toString() << "\n";
|
||||||
|
}
|
||||||
|
dn = 0;
|
||||||
|
piForeachC (CPair & c, channels_) {
|
||||||
|
piForeachC (PIIODevice * d, c.second) {
|
||||||
|
PIString prefix = "channel." + PIString::fromNumber(dn); ++dn;
|
||||||
|
ret << prefix << ".from = " << devPath(c.first) << "\n";
|
||||||
|
ret << prefix << ".to = " << devPath(d) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret << "[]\n";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIIODevice * PIConnection::addDevice(const PIString & full_path, PIIODevice::DeviceMode mode, bool start) {
|
||||||
|
PIIODevice * dev = __device_pool__->addDevice(this, full_path, mode, start);
|
||||||
|
if (dev) {
|
||||||
|
dev->setName(name() + ".device." + full_path);
|
||||||
|
device_modes[dev] = mode;
|
||||||
|
}
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeDevice(const PIString & full_path) {
|
||||||
|
PIIODevice * dev = __device_pool__->device(full_path);
|
||||||
|
if (dev == 0) return false;
|
||||||
|
device_modes.remove(dev);
|
||||||
|
piForeachC (PEPair & i, extractors) {
|
||||||
|
if (i.second == 0) continue;
|
||||||
|
i.second->devices.removeAll(dev);
|
||||||
|
}
|
||||||
|
bounded_extractors.remove(dev);
|
||||||
|
channels_.remove(dev);
|
||||||
|
for (PIMap<PIIODevice * , PIVector<PIIODevice * > >::iterator it = channels_.begin(); it != channels_.end(); ++it)
|
||||||
|
it.value().removeAll(dev);
|
||||||
|
return __device_pool__->removeDevice(this, full_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::removeAllDevices() {
|
||||||
|
PIVector<PIIODevice * > bdevs(__device_pool__->boundedDevices(this));
|
||||||
|
piForeach (PIIODevice * d, bdevs) {
|
||||||
|
channels_.remove(d);
|
||||||
|
for (PIMap<PIIODevice * , PIVector<PIIODevice * > >::iterator it = channels_.begin(); it != channels_.end(); ++it)
|
||||||
|
it.value().removeAll(d);
|
||||||
|
}
|
||||||
|
__device_pool__->unboundConnection(this);
|
||||||
|
device_modes.clear();
|
||||||
|
bounded_extractors.clear();
|
||||||
|
piForeachC (PEPair & i, extractors) {
|
||||||
|
if (i.second == 0) continue;
|
||||||
|
i.second->devices.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIIODevice * PIConnection::device(const PIString & full_path) const {
|
||||||
|
DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path);
|
||||||
|
if (dd == 0) return 0;
|
||||||
|
if (dd->dev == 0) return 0;
|
||||||
|
if (!dd->listeners.contains(const_cast<PIConnection * >(this))) return 0;
|
||||||
|
return dd->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIIODevice * > PIConnection::boundedDevices() const {
|
||||||
|
return __device_pool__->boundedDevices(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIString & full_path, PIPacketExtractor::SplitMode mode) {
|
||||||
|
Extractor * e = extractors.value(name_);
|
||||||
|
PIIODevice * dev = __device_pool__->device(full_path);
|
||||||
|
if (dev == 0) {
|
||||||
|
piCoutObj << "\"addPacketExtractor\" error: no such device \"" << full_path << "\"!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (e == 0) {
|
||||||
|
e = new Extractor();
|
||||||
|
extractors[name_] = e;
|
||||||
|
}
|
||||||
|
if (e->extractor == 0) {
|
||||||
|
e->extractor = new PIPacketExtractor(0, mode);
|
||||||
|
e->extractor->setName(name_);
|
||||||
|
e->extractor->setThreadedReadData(new PIPair<PIConnection * , PIString>(this, name_));
|
||||||
|
e->extractor->setHeaderCheckSlot(filterValidateHeaderS);
|
||||||
|
e->extractor->setFooterCheckSlot(filterValidateFooterS);
|
||||||
|
e->extractor->setPayloadCheckSlot(filterValidatePayloadS);
|
||||||
|
CONNECT2(void, uchar * , int, e->extractor, packetReceived, this, packetExtractorReceived)
|
||||||
|
}
|
||||||
|
if (!e->devices.contains(dev)) {
|
||||||
|
bounded_extractors[dev] << e->extractor;
|
||||||
|
e->devices << dev;
|
||||||
|
}
|
||||||
|
return e->extractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIIODevice * dev, PIPacketExtractor::SplitMode mode) {
|
||||||
|
if (dev == 0) return 0;
|
||||||
|
PIString fp;
|
||||||
|
if (dev->isPropertyExists("__fullPath__")) fp = dev->property("__fullPath__").toString();
|
||||||
|
fp = dev->constructFullPath();
|
||||||
|
return addFilter(name_, fp, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeFilter(const PIString & name_, const PIString & full_path) {
|
||||||
|
Extractor * p = extractors.value(name_);
|
||||||
|
if (p == 0) return false;
|
||||||
|
bool ret = false;
|
||||||
|
for (int i = 0; i < p->devices.size_s(); ++i) {
|
||||||
|
if (p->devices[i]->property("__fullPath__").toString() == full_path) {
|
||||||
|
bounded_extractors[p->devices[i]].removeAll(p->extractor);
|
||||||
|
p->devices.remove(i);
|
||||||
|
--i;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p->devices.isEmpty()) {
|
||||||
|
unboundExtractor(p->extractor);
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeFilter(const PIString & name, const PIIODevice * dev) {
|
||||||
|
if (dev == 0) return false;
|
||||||
|
return removeFilter(name, dev->property("__fullPath__").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeFilter(const PIString & name_) {
|
||||||
|
Extractor * p = extractors.value(name_);
|
||||||
|
if (p == 0) return false;
|
||||||
|
unboundExtractor(p->extractor);
|
||||||
|
delete p;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::removeAllFilters() {
|
||||||
|
piForeachC (PEPair & i, extractors) {
|
||||||
|
if (i.second == 0) continue;
|
||||||
|
channels_.remove(i.second->extractor);
|
||||||
|
for (PIMap<PIIODevice * , PIVector<PIIODevice * > >::iterator it = channels_.begin(); it != channels_.end(); ++it)
|
||||||
|
it.value().removeAll(i.second->extractor);
|
||||||
|
delete i.second;
|
||||||
|
}
|
||||||
|
extractors.clear();
|
||||||
|
bounded_extractors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIPacketExtractor * > PIConnection::filters() const {
|
||||||
|
PIVector<PIPacketExtractor * > ret;
|
||||||
|
piForeachC (PEPair & i, extractors)
|
||||||
|
if (i.second != 0)
|
||||||
|
if (i.second->extractor != 0) ret << i.second->extractor;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIStringList PIConnection::filterNames() const {
|
||||||
|
PIStringList ret;
|
||||||
|
piForeachC (PEPair & i, extractors)
|
||||||
|
if (i.second != 0)
|
||||||
|
if (i.second->extractor != 0) ret << i.first;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIPacketExtractor * PIConnection::filter(const PIString & name) const {
|
||||||
|
piForeachC (PEPair & i, extractors)
|
||||||
|
if (i.second != 0)
|
||||||
|
if (i.second->extractor != 0 && i.first == name)
|
||||||
|
return i.second->extractor;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIIODevice * > PIConnection::filterBoundedDevices(const PIString & name_) const {
|
||||||
|
PIVector<PIIODevice * > ret;
|
||||||
|
Extractor * p = extractors.value(name_);
|
||||||
|
if (p == 0) return ret;
|
||||||
|
return p->devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::addChannel(const PIString & name0, const PIString & name1) {
|
||||||
|
//piCout << "addChannel" << name0 << name1;
|
||||||
|
if (name0.isEmpty() || name1.isEmpty()) return false;
|
||||||
|
PIIODevice * dev0 = device(name0), * dev1 = device(name1);
|
||||||
|
PIPacketExtractor * pe0(0), * pe1(0);
|
||||||
|
if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
|
||||||
|
if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor;
|
||||||
|
if (pe0 != 0) dev0 = pe0;
|
||||||
|
if (pe1 != 0) dev1 = pe1;
|
||||||
|
if (dev0 == 0 || dev1 == 0) {
|
||||||
|
if (dev0 == 0) piCoutObj << "\"addChannel\" error: no such device \"" << name0 << "\"!";
|
||||||
|
if (dev1 == 0) piCoutObj << "\"addChannel\" error: no such device \"" << name1 << "\"!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!channels_[dev0].contains(dev1))
|
||||||
|
channels_[dev0] << dev1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeChannel(const PIString & name0, const PIString & name1) {
|
||||||
|
PIIODevice * dev0 = device(name0), * dev1 = device(name1);
|
||||||
|
PIPacketExtractor * pe0(0), * pe1(0);
|
||||||
|
if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
|
||||||
|
if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor;
|
||||||
|
if (pe0 != 0) dev0 = pe0;
|
||||||
|
if (pe1 != 0) dev1 = pe1;
|
||||||
|
if (dev0 == 0 || dev1 == 0) return false;
|
||||||
|
channels_[dev0].removeAll(dev1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::removeChannel(const PIString & name0) {
|
||||||
|
PIIODevice * dev0 = device(name0);
|
||||||
|
PIPacketExtractor * pe0(0);
|
||||||
|
if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor;
|
||||||
|
if (pe0 != 0) dev0 = pe0;
|
||||||
|
if (dev0 == 0) return false;
|
||||||
|
channels_.remove(dev0);
|
||||||
|
for (PIMap<PIIODevice * , PIVector<PIIODevice * > >::iterator it = channels_.begin(); it != channels_.end(); ++it)
|
||||||
|
it.value().removeAll(dev0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::removeAllChannels() {
|
||||||
|
channels_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIConnection::devPath(const PIIODevice * d) const {
|
||||||
|
if (d == 0) return PIString();
|
||||||
|
if (strcmp(d->className(), "PIPacketExtractor") == 0) return d->name();
|
||||||
|
return d->constructFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIConnection::devFPath(const PIIODevice * d) const {
|
||||||
|
if (d == 0) return PIString();
|
||||||
|
if (d->isPropertyExists("__fullPath__")) return d->property("__fullPath__").toString();
|
||||||
|
return d->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIPair<PIString, PIString > > PIConnection::channels() const {
|
||||||
|
PIVector<PIPair<PIString, PIString > > ret;
|
||||||
|
piForeachC (CPair & i, channels_) {
|
||||||
|
PIString fp0(devFPath(i.first));
|
||||||
|
piForeachC (PIIODevice * d, i.second)
|
||||||
|
ret << PIPair<PIString, PIString>(fp0, devFPath(d));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::startThreadedRead(const PIString & full_path) {
|
||||||
|
DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path, 0);
|
||||||
|
if (dd == 0) return;
|
||||||
|
if (dd->dev == 0) return;
|
||||||
|
if (dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return;
|
||||||
|
dd->rthread->start();
|
||||||
|
dd->started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::startAllThreadedReads() {
|
||||||
|
piForeachC (DevicePool::DDPair & d, __device_pool__->devices)
|
||||||
|
startThreadedRead(d.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::stopThreadedRead(const PIString & full_path) {
|
||||||
|
DevicePool::DeviceData * dd = __device_pool__->devices.value(full_path, 0);
|
||||||
|
if (dd == 0) return;
|
||||||
|
if (dd->dev == 0) return;
|
||||||
|
if (!dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return;
|
||||||
|
dd->rthread->stop();
|
||||||
|
dd->started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::stopAllThreadedReads() {
|
||||||
|
piForeachC (DevicePool::DDPair & d, __device_pool__->devices)
|
||||||
|
stopThreadedRead(d.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIConnection::write(const PIString & full_path, const PIByteArray & data) {
|
||||||
|
PIIODevice * dev = __device_pool__->device(full_path);
|
||||||
|
if (dev == 0) {
|
||||||
|
piCoutObj << "Null Device!";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!dev->canWrite()) {
|
||||||
|
piCoutObj << "Device \"" << full_path << "\" can`t write!";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return dev->write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector< PIConnection * > PIConnection::allConnections() {
|
||||||
|
return _connections;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector< PIIODevice * > PIConnection::allDevices() {
|
||||||
|
return __device_pool__->boundedDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PIIODevice * PIConnection::DevicePool::addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode, bool start) {
|
||||||
|
DeviceData * dd = devices[fp];
|
||||||
|
int pmode(0);
|
||||||
|
bool need_start = false;
|
||||||
|
if (dd == 0) {
|
||||||
|
dd = new DeviceData();
|
||||||
|
devices[fp] = dd;
|
||||||
|
}
|
||||||
|
if (dd->dev == 0) {
|
||||||
|
//piCout << "new device" << fp;
|
||||||
|
dd->dev = PIIODevice::createFromFullPath(fp);
|
||||||
|
if (dd->dev == 0) {
|
||||||
|
piCoutObj << "Error: can`t create device \"" << fp << "\"!"; //:" << errorString();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dd->dev->setProperty("__fullPath__", fp);
|
||||||
|
} else
|
||||||
|
pmode = dd->dev->mode();
|
||||||
|
if (!dd->listeners.contains(parent))
|
||||||
|
dd->listeners << parent;
|
||||||
|
if (pmode == mode || pmode == PIIODevice::ReadWrite)
|
||||||
|
return dd->dev;
|
||||||
|
if ((mode & PIIODevice::ReadOnly) > 0) {
|
||||||
|
if (dd->rthread != 0) {
|
||||||
|
delete dd->rthread;
|
||||||
|
dd->rthread = 0;
|
||||||
|
dd->started = false;
|
||||||
|
}
|
||||||
|
dd->rthread = new PIThread(dd, threadReadDP);
|
||||||
|
need_start = true;
|
||||||
|
pmode |= PIIODevice::ReadOnly;
|
||||||
|
}
|
||||||
|
if ((mode & PIIODevice::WriteOnly) > 0)
|
||||||
|
pmode |= PIIODevice::WriteOnly;
|
||||||
|
dd->dev->close();
|
||||||
|
dd->dev->open((PIIODevice::DeviceMode)pmode);
|
||||||
|
if (need_start && start) {
|
||||||
|
dd->rthread->start();
|
||||||
|
dd->started = true;
|
||||||
|
}
|
||||||
|
return dd->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::DevicePool::removeDevice(PIConnection * parent, const PIString & fp) {
|
||||||
|
DeviceData * dd = devices.value(fp);
|
||||||
|
if (dd == 0)
|
||||||
|
return false;
|
||||||
|
if (dd->dev == 0)
|
||||||
|
return false;
|
||||||
|
bool ok = dd->listeners.contains(parent);
|
||||||
|
dd->listeners.removeAll(parent);
|
||||||
|
if (dd->listeners.isEmpty()) {
|
||||||
|
delete dd;
|
||||||
|
devices.remove(fp);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::DevicePool::unboundConnection(PIConnection * parent) {
|
||||||
|
PIStringList rem;
|
||||||
|
piForeachC (DDPair & i, devices) {
|
||||||
|
if (i.second == 0) {
|
||||||
|
rem << i.first;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i.second->listeners.removeAll(parent);
|
||||||
|
if (i.second->listeners.isEmpty())
|
||||||
|
rem << i.first;
|
||||||
|
}
|
||||||
|
piForeachC (PIString & i, rem) {
|
||||||
|
DeviceData * dd = devices.value(i);
|
||||||
|
if (dd == 0)
|
||||||
|
continue;
|
||||||
|
delete dd;
|
||||||
|
devices.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIIODevice * PIConnection::DevicePool::device(const PIString & fp) const {
|
||||||
|
DeviceData * dd = devices.value(fp);
|
||||||
|
if (dd == 0) return 0;
|
||||||
|
return dd->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIConnection * > PIConnection::DevicePool::boundedConnections() const {
|
||||||
|
PIVector<PIConnection * > ret;
|
||||||
|
piForeachC (DDPair & i, devices) {
|
||||||
|
if (i.second == 0)
|
||||||
|
continue;
|
||||||
|
ret << i.second->listeners;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ret.size_s(); ++i)
|
||||||
|
for (int j = i + 1; j < ret.size_s(); ++j)
|
||||||
|
if (ret[i] == ret[j]) {
|
||||||
|
ret.remove(j);
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector< PIIODevice * > PIConnection::DevicePool::boundedDevices() const {
|
||||||
|
PIVector<PIIODevice * > ret;
|
||||||
|
piForeachC (DDPair & i, devices) {
|
||||||
|
if (i.second == 0) continue;
|
||||||
|
if (i.second->dev == 0) continue;
|
||||||
|
ret << i.second->dev;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVector<PIIODevice * > PIConnection::DevicePool::boundedDevices(const PIConnection * parent) const {
|
||||||
|
PIVector<PIIODevice * > ret;
|
||||||
|
piForeachC (DDPair & i, devices) {
|
||||||
|
if (i.second == 0) continue;
|
||||||
|
if (i.second->dev == 0) continue;
|
||||||
|
if (i.second->listeners.contains(const_cast<PIConnection*>(parent)))
|
||||||
|
ret << i.second->dev;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::DevicePool::DeviceData::~DeviceData() {
|
||||||
|
if (rthread != 0) {
|
||||||
|
rthread->stop();
|
||||||
|
delete rthread;
|
||||||
|
rthread = 0;
|
||||||
|
}
|
||||||
|
if (dev != 0) {
|
||||||
|
delete dev;
|
||||||
|
dev = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::DevicePool::threadReadDP(void * ddp) {
|
||||||
|
DeviceData * dd((DeviceData * )ddp);
|
||||||
|
if (dd->dev == 0) {piMSleep(100); return;}
|
||||||
|
PIByteArray ba;
|
||||||
|
ba = dd->dev->read(dd->dev->threadedReadBufferSize());
|
||||||
|
if (ba.isEmpty()) {piMSleep(10); return;}
|
||||||
|
//piCout << "Readed from" << dd->dev->path() << Hex << ba;
|
||||||
|
__device_pool__->deviceReaded(dd, ba);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::DevicePool::deviceReaded(PIConnection::DevicePool::DeviceData * dd, const PIByteArray & data) {
|
||||||
|
PIString from = dd->dev->property("__fullPath__").toString();
|
||||||
|
piForeach (PIConnection * ld, dd->listeners)
|
||||||
|
ld->rawReceived(dd->dev, from, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidateHeaderS(void * c, uchar * src, uchar * rec, int size) {
|
||||||
|
PIPair<PIConnection * , PIString> * p((PIPair<PIConnection * , PIString> * )c);
|
||||||
|
return p->first->filterValidateHeader(p->second, src, rec, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidateFooterS(void * c, uchar * src, uchar * rec, int size) {
|
||||||
|
PIPair<PIConnection * , PIString> * p((PIPair<PIConnection * , PIString> * )c);
|
||||||
|
return p->first->filterValidateFooter(p->second, src, rec, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidatePayloadS(void * c, uchar * rec, int size) {
|
||||||
|
PIPair<PIConnection * , PIString> * p((PIPair<PIConnection * , PIString> * )c);
|
||||||
|
return p->first->filterValidatePayload(p->second, rec, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data) {
|
||||||
|
dataReceived(from, data);
|
||||||
|
dataReceivedEvent(from, data);
|
||||||
|
PIVector<PIPacketExtractor * > be(bounded_extractors.value(dev));
|
||||||
|
//piCout << be;
|
||||||
|
piForeach (PIPacketExtractor * i, be)
|
||||||
|
i->threadedRead(const_cast<uchar * >(data.data()), data.size_s());
|
||||||
|
PIVector<PIIODevice * > chd(channels_.value(dev));
|
||||||
|
piForeach (PIIODevice * d, chd)
|
||||||
|
d->write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidateHeader(const PIString & filter_name, uchar * src, uchar * rec, int size) {
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
if (src[i] != rec[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidateFooter(const PIString & filter_name, uchar * src, uchar * rec, int size) {
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
if (src[i] != rec[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIConnection::filterValidatePayload(const PIString & filter_name, uchar * rec, int size) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::Extractor::~Extractor() {
|
||||||
|
if (extractor != 0) {
|
||||||
|
if (extractor->threadedReadData() != 0)
|
||||||
|
delete (PIPair<PIConnection * , PIString> * )(extractor->threadedReadData());
|
||||||
|
delete extractor;
|
||||||
|
extractor = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::unboundExtractor(PIPacketExtractor * pe) {
|
||||||
|
if (pe == 0) return;
|
||||||
|
channels_.remove(pe);
|
||||||
|
for (PIMap<PIIODevice * , PIVector<PIIODevice * > >::iterator it = channels_.begin(); it != channels_.end(); ++it)
|
||||||
|
it.value().removeAll(pe);
|
||||||
|
PIVector<PIIODevice * > k = bounded_extractors.keys();
|
||||||
|
piForeach (PIIODevice * i, k) {
|
||||||
|
PIVector<PIPacketExtractor*> & be(bounded_extractors[i]);
|
||||||
|
be.removeAll(pe);
|
||||||
|
if (be.isEmpty())
|
||||||
|
bounded_extractors.remove(i);
|
||||||
|
}
|
||||||
|
extractors.remove(pe->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIConnection::packetExtractorReceived(uchar * data, int size) {
|
||||||
|
PIString from(emitter() == 0 ? "" : emitter()->name());
|
||||||
|
packetReceived(from, PIByteArray(data, size));
|
||||||
|
packetReceivedEvent(from, PIByteArray(data, size));
|
||||||
|
PIIODevice * cd = (PIIODevice * )emitter();
|
||||||
|
if (cd == 0) return;
|
||||||
|
PIVector<PIIODevice * > chd(channels_.value(cd));
|
||||||
|
piForeach (PIIODevice * d, chd)
|
||||||
|
d->write(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PIConnection::DevicePool * __device_pool__;
|
||||||
|
|
||||||
|
bool __DevicePoolContainer__::inited_(false);
|
||||||
|
|
||||||
|
__DevicePoolContainer__::__DevicePoolContainer__() {
|
||||||
|
if (inited_) return;
|
||||||
|
inited_ = true;
|
||||||
|
__device_pool__ = new PIConnection::DevicePool();
|
||||||
|
}
|
||||||
291
piconnection.h
Normal file
291
piconnection.h
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
/*! \file piconnection.h
|
||||||
|
* \brief Complex I/O point
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Complex I/O point
|
||||||
|
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 PICONNECTION_H
|
||||||
|
#define PICONNECTION_H
|
||||||
|
|
||||||
|
#include "pipacketextractor.h"
|
||||||
|
|
||||||
|
|
||||||
|
class PIP_EXPORT PIConnection: public PIObject
|
||||||
|
{
|
||||||
|
PIOBJECT(PIConnection)
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructs an empty connection
|
||||||
|
PIConnection();
|
||||||
|
|
||||||
|
//! Constructs connection and configure it from config file "config" from section "name"
|
||||||
|
PIConnection(const PIString & config, const PIString & name);
|
||||||
|
|
||||||
|
~PIConnection();
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Configure connection from config file "config" from section "name". Returns if configuration was successful
|
||||||
|
* \details \b Warning: all devices, filters and channels removed before configure! */
|
||||||
|
bool configureFromConfig(const PIString & config, const PIString & name);
|
||||||
|
|
||||||
|
//! Returns config file section of current connection configuration
|
||||||
|
PIString makeConfig() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Add device with full path "full_path", open mode "mode" to Device pool and connection
|
||||||
|
* \details Returns pointer to device or null if device can not be created. If "start" is true,
|
||||||
|
* read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead()
|
||||||
|
* or \a startAllThreadedReads(). By default, read thread doesn`t start */
|
||||||
|
PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false);
|
||||||
|
|
||||||
|
/*! \brief Remove device with full path "full_path" from connection
|
||||||
|
* \details Returns if device was removed. If there is no connection bounded to this device,
|
||||||
|
* it will be removed from Device pool */
|
||||||
|
bool removeDevice(const PIString & full_path);
|
||||||
|
|
||||||
|
/*! \brief Remove all device from connection
|
||||||
|
* \details If there is no connection bounded to there devices, they removed from Device pool */
|
||||||
|
void removeAllDevices();
|
||||||
|
|
||||||
|
//! Returns device with full path "full_path" or null if there is no such device
|
||||||
|
PIIODevice * device(const PIString & full_path) const;
|
||||||
|
|
||||||
|
//! Returns all devices bounded to this connection
|
||||||
|
PIVector<PIIODevice * > boundedDevices() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Add filter with name "name" to device with full path "full_path"
|
||||||
|
* \details If there is no filter with name "name", connection create new with split mode "mode" and bound
|
||||||
|
* to it device "full_path". If filter with name "name" already exists, device "full_path" add to this filter.
|
||||||
|
* \b Attention! "mode" is altual olny if new filter was created!
|
||||||
|
* This function returns PIPacketExtractor * assosiated with this filter */
|
||||||
|
PIPacketExtractor * addFilter(const PIString & name, const PIString & full_path, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
|
||||||
|
|
||||||
|
//! Add filter with name "name" to device "dev"
|
||||||
|
PIPacketExtractor * addFilter(const PIString & name, const PIIODevice * dev, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
|
||||||
|
|
||||||
|
/*! \brief Remove from filter with name "name" device with full path "full_path"
|
||||||
|
* \details If there is no devices bounded to this filter, it will be removed. Returns
|
||||||
|
* if device was removed */
|
||||||
|
bool removeFilter(const PIString & name, const PIString & full_path);
|
||||||
|
|
||||||
|
//! Remove from filter with name "name" device "dev"
|
||||||
|
bool removeFilter(const PIString & name, const PIIODevice * dev);
|
||||||
|
|
||||||
|
//! Remove filter with name "name". Returns if filter was removed
|
||||||
|
bool removeFilter(const PIString & name);
|
||||||
|
|
||||||
|
//! Remove all filters from connection
|
||||||
|
void removeAllFilters();
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns all filters of connection
|
||||||
|
PIVector<PIPacketExtractor * > filters() const;
|
||||||
|
|
||||||
|
//! Returns all filter names of connection
|
||||||
|
PIStringList filterNames() const;
|
||||||
|
|
||||||
|
//! Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter
|
||||||
|
PIPacketExtractor * filter(const PIString & name) const;
|
||||||
|
|
||||||
|
//! Returns all devices bounded to filter "name"
|
||||||
|
PIVector<PIIODevice * > filterBoundedDevices(const PIString & name) const;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Add to connection channel from "name_from" to "name_to"
|
||||||
|
* \details "name_from" and "name_to" can be full pathes of devices or filter names.
|
||||||
|
* Returns \b false if there if no such device or filter, else create channel and returns \b true */
|
||||||
|
bool addChannel(const PIString & name_from, const PIString & name_to);
|
||||||
|
|
||||||
|
//! Add to connection channel from "name_from" to "dev_to"
|
||||||
|
bool addChannel(const PIString & name_from, const PIIODevice * dev_to) {return addChannel(name_from, devFPath(dev_to));}
|
||||||
|
|
||||||
|
//! Add to connection channel from "dev_from" to "name_to"
|
||||||
|
bool addChannel(const PIIODevice * dev_from, const PIString & name_to) {return addChannel(devFPath(dev_from), name_to);}
|
||||||
|
|
||||||
|
//! Add to connection channel from "dev_from" to "dev_to"
|
||||||
|
bool addChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {return addChannel(devFPath(dev_from), devFPath(dev_to));}
|
||||||
|
|
||||||
|
/*! \brief Remove from connection channel from "name_from" to "name_to"
|
||||||
|
* \details "name_from" and "name_to" can be full pathes of devices or filter names.
|
||||||
|
* Returns \b false if there if no such device or filter, else remove channel and returns \b true */
|
||||||
|
bool removeChannel(const PIString & name_from, const PIString & name_to);
|
||||||
|
|
||||||
|
//! Remove from connection channel from "name_from" to "dev_to"
|
||||||
|
bool removeChannel(const PIString & name_from, const PIIODevice * dev_to) {return removeChannel(name_from, devFPath(dev_to));}
|
||||||
|
|
||||||
|
//! Remove from connection channel from "dev_from" to "name_to"
|
||||||
|
bool removeChannel(const PIIODevice * dev_from, const PIString & name_to) {return removeChannel(devFPath(dev_from), name_to);}
|
||||||
|
|
||||||
|
//! Remove from connection channel from "dev_from" to "dev_to"
|
||||||
|
bool removeChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {return removeChannel(devFPath(dev_from), devFPath(dev_to));}
|
||||||
|
|
||||||
|
/*! \brief Remove from connection all channels from "name_from"
|
||||||
|
* \details "name_from" can be full path of device or filter name.
|
||||||
|
* Returns \b false if there if no such device or filter, else remove channels and returns \b true */
|
||||||
|
bool removeChannel(const PIString & name_from);
|
||||||
|
|
||||||
|
//! Remove from connection all channels from "dev_from"
|
||||||
|
bool removeChannel(const PIIODevice * dev_from) {return removeChannel(devFPath(dev_from));}
|
||||||
|
|
||||||
|
//! Remove from connection all channels
|
||||||
|
void removeAllChannels();
|
||||||
|
|
||||||
|
//! Returns all channels of this connection as full pathes or filter names pair array (from, to)
|
||||||
|
PIVector<PIPair<PIString, PIString> > channels() const;
|
||||||
|
|
||||||
|
|
||||||
|
//! Start read thread of device with full path "full_path"
|
||||||
|
void startThreadedRead(const PIString & full_path);
|
||||||
|
|
||||||
|
//! Start read thread of device "dev"
|
||||||
|
void startThreadedRead(const PIIODevice * dev) {startThreadedRead(devFPath(dev));}
|
||||||
|
|
||||||
|
//! Start read threads of all Device pool device
|
||||||
|
void startAllThreadedReads();
|
||||||
|
|
||||||
|
//! Stop read thread of device with full path "full_path"
|
||||||
|
void stopThreadedRead(const PIString & full_path);
|
||||||
|
|
||||||
|
//! Stop read thread of device "dev"
|
||||||
|
void stopThreadedRead(const PIIODevice * dev) {stopThreadedRead(devFPath(dev));}
|
||||||
|
|
||||||
|
//! Stop read threads of all Device pool device
|
||||||
|
void stopAllThreadedReads();
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns if there is no devices in this connection
|
||||||
|
bool isEmpty() const {return device_modes.isEmpty();}
|
||||||
|
|
||||||
|
|
||||||
|
//! Write data "data" to device with full path "full_path" and returns result of \a write() function of device
|
||||||
|
int write(const PIString & full_path, const PIByteArray & data);
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns all connections in application
|
||||||
|
static PIVector<PIConnection * > allConnections();
|
||||||
|
|
||||||
|
//! Returns all devices in Device pool
|
||||||
|
static PIVector<PIIODevice * > allDevices();
|
||||||
|
|
||||||
|
class DevicePool: public PIObject {
|
||||||
|
PIOBJECT(DevicePool)
|
||||||
|
friend class PIConnection;
|
||||||
|
public:
|
||||||
|
DevicePool(): PIObject("PIConnection::DevicePool") {}
|
||||||
|
|
||||||
|
PIIODevice * addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = true);
|
||||||
|
bool removeDevice(PIConnection * parent, const PIString & fp);
|
||||||
|
void unboundConnection(PIConnection * parent);
|
||||||
|
PIIODevice * device(const PIString & fp) const;
|
||||||
|
PIVector<PIConnection * > boundedConnections() const;
|
||||||
|
PIVector<PIIODevice * > boundedDevices() const;
|
||||||
|
PIVector<PIIODevice * > boundedDevices(const PIConnection * parent) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct DeviceData {
|
||||||
|
DeviceData(): dev(0), rthread(0), started(false) {}
|
||||||
|
~DeviceData();
|
||||||
|
PIIODevice * dev;
|
||||||
|
PIThread * rthread;
|
||||||
|
bool started;
|
||||||
|
PIVector<PIConnection * > listeners;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void threadReadDP(void * ddp);
|
||||||
|
void deviceReaded(DeviceData * dd, const PIByteArray & data);
|
||||||
|
|
||||||
|
typedef PIMap<PIString, DeviceData * >::value_type DDPair;
|
||||||
|
PIMap<PIString, DeviceData * > devices;
|
||||||
|
};
|
||||||
|
|
||||||
|
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data)
|
||||||
|
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data)
|
||||||
|
|
||||||
|
//! \events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn void dataReceivedEvent(const PIString & from, const PIByteArray & data)
|
||||||
|
//! \brief Raise on data received from device with full path "from"
|
||||||
|
|
||||||
|
//! \fn void packetReceivedEvent(const PIString & from, const PIByteArray & data)
|
||||||
|
//! \brief Raise on packet received from filter with name "from"
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Executes on data received from device with full path "from"
|
||||||
|
virtual void dataReceived(const PIString & from, const PIByteArray & data) {}
|
||||||
|
|
||||||
|
//! Executes on packet received from filter with name "from"
|
||||||
|
virtual void packetReceived(const PIString & from, const PIByteArray & data) {}
|
||||||
|
|
||||||
|
//! Validate header "rec" with source header "src" and size "size", executes from filter "filter_name"
|
||||||
|
virtual bool filterValidateHeader(const PIString & filter_name, uchar * src, uchar * rec, int size);
|
||||||
|
|
||||||
|
//! Validate footer "rec" with source footer "src" and size "size", executes from filter "filter_name"
|
||||||
|
virtual bool filterValidateFooter(const PIString & filter_name, uchar * src, uchar * rec, int size);
|
||||||
|
|
||||||
|
//! Validate payload "rec" with size "size", executes from filter "filter_name"
|
||||||
|
virtual bool filterValidatePayload(const PIString & filter_name, uchar * rec, int size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool filterValidateHeaderS(void * c, uchar * src, uchar * rec, int size);
|
||||||
|
static bool filterValidateFooterS(void * c, uchar * src, uchar * rec, int size);
|
||||||
|
static bool filterValidatePayloadS(void * c, uchar * rec, int size);
|
||||||
|
void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data);
|
||||||
|
void unboundExtractor(PIPacketExtractor * pe);
|
||||||
|
EVENT_HANDLER2(void, packetExtractorReceived, uchar * , data, int, size);
|
||||||
|
|
||||||
|
PIString devPath(const PIIODevice * d) const;
|
||||||
|
PIString devFPath(const PIIODevice * d) const;
|
||||||
|
|
||||||
|
struct Extractor {
|
||||||
|
Extractor(): extractor(0) {}
|
||||||
|
~Extractor();
|
||||||
|
PIPacketExtractor * extractor;
|
||||||
|
PIVector<PIIODevice * > devices;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef PIMap<PIString, Extractor * >::value_type PEPair;
|
||||||
|
typedef PIMap<PIIODevice * , PIVector<PIPacketExtractor * > >::value_type BEPair;
|
||||||
|
typedef PIMap<PIIODevice * , PIVector<PIIODevice * > >::value_type CPair;
|
||||||
|
PIMap<PIString, Extractor * > extractors;
|
||||||
|
PIMap<PIIODevice * , PIIODevice::DeviceMode> device_modes;
|
||||||
|
PIMap<PIIODevice * , PIVector<PIPacketExtractor * > > bounded_extractors;
|
||||||
|
PIMap<PIIODevice * , PIVector<PIIODevice * > > channels_;
|
||||||
|
|
||||||
|
static PIVector<PIConnection * > _connections;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern PIConnection::DevicePool * __device_pool__;
|
||||||
|
|
||||||
|
class __DevicePoolContainer__ {
|
||||||
|
public:
|
||||||
|
__DevicePoolContainer__();
|
||||||
|
static bool inited_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static __DevicePoolContainer__ __device_pool_container__;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PICONNECTION_H
|
||||||
@@ -692,7 +692,7 @@ void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr,
|
|||||||
addVariable("priority", &(ptr->statistic().priority), col, format);
|
addVariable("priority", &(ptr->statistic().priority), col, format);
|
||||||
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
|
addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format);
|
||||||
addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format);
|
addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format);
|
||||||
addVariable("cpu load", &(ptr->statistic().cpu_load_system), col, format);
|
addVariable("cpu load", &(ptr->statistic().cpu_load_user), col, format);
|
||||||
}
|
}
|
||||||
void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
|
void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, PIFlags<PIConsole::Format> format) {
|
||||||
vid++; tv.id = vid; tv.size = sizeof(ullong); tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
|
vid++; tv.id = vid; tv.size = sizeof(ullong); tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
|
||||||
@@ -812,8 +812,8 @@ void PIConsole::listenServers() {
|
|||||||
stopPeer();
|
stopPeer();
|
||||||
server_mode = false;
|
server_mode = false;
|
||||||
server_name.clear();
|
server_name.clear();
|
||||||
srand(currentSystemTime().nanoseconds);
|
srand(PISystemTime::current().nanoseconds);
|
||||||
peer = new PIPeer("_rcc_:" + currentDateTime().toString("hhmmssddMMyy_") + PIString::fromNumber(rand()));
|
peer = new PIPeer("_rcc_:" + PIDateTime::current().toString("hhmmssddMMyy_") + PIString::fromNumber(rand()));
|
||||||
CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived);
|
CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived);
|
||||||
peer_timer.start(100.);
|
peer_timer.start(100.);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#ifndef PICONTAINERS_H
|
#ifndef PICONTAINERS_H
|
||||||
#define PICONTAINERS_H
|
#define PICONTAINERS_H
|
||||||
|
|
||||||
#include "pivector.h"
|
#include "piincludes.h"
|
||||||
|
|
||||||
template<typename Type0, typename Type1>
|
template<typename Type0, typename Type1>
|
||||||
class PIP_EXPORT PIPair {
|
class PIP_EXPORT PIPair {
|
||||||
@@ -47,8 +47,10 @@ inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> &
|
|||||||
template<typename Type0, typename Type1>
|
template<typename Type0, typename Type1>
|
||||||
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
|
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
#include "pivector.h"
|
||||||
#include "pistack.h"
|
#include "pistack.h"
|
||||||
#include "piqueue.h"
|
#include "piqueue.h"
|
||||||
|
#include "pideque.h"
|
||||||
#include "pimap.h"
|
#include "pimap.h"
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
@@ -295,25 +297,28 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PIP_CONTAINERS_STL
|
||||||
|
|
||||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
# define __PICONTAINERS_SIMPLE_TYPE__(T) \
|
||||||
class PIP_EXPORT PIDeque: public deque<Type, Allocator> {
|
__PIDEQUE_SIMPLE_TYPE__(T)\
|
||||||
typedef PIDeque<Type, Allocator> _CDeque;
|
__PIVECTOR_SIMPLE_TYPE__(T)
|
||||||
typedef deque<Type, Allocator> _stlc;
|
|
||||||
public:
|
__PICONTAINERS_SIMPLE_TYPE__(bool)
|
||||||
PIDeque() {piMonitor.containers++;}
|
__PICONTAINERS_SIMPLE_TYPE__(char)
|
||||||
PIDeque(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);}
|
__PICONTAINERS_SIMPLE_TYPE__(uchar)
|
||||||
PIDeque(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
|
__PICONTAINERS_SIMPLE_TYPE__(short)
|
||||||
PIDeque(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
__PICONTAINERS_SIMPLE_TYPE__(ushort)
|
||||||
PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
__PICONTAINERS_SIMPLE_TYPE__(int)
|
||||||
~PIDeque() {piMonitor.containers--;}
|
__PICONTAINERS_SIMPLE_TYPE__(uint)
|
||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
__PICONTAINERS_SIMPLE_TYPE__(long)
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
__PICONTAINERS_SIMPLE_TYPE__(ulong)
|
||||||
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
|
__PICONTAINERS_SIMPLE_TYPE__(llong)
|
||||||
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
|
__PICONTAINERS_SIMPLE_TYPE__(ullong)
|
||||||
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
__PICONTAINERS_SIMPLE_TYPE__(float)
|
||||||
PIVector<Type> toVector() {PIVector<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
__PICONTAINERS_SIMPLE_TYPE__(double)
|
||||||
};
|
__PICONTAINERS_SIMPLE_TYPE__(ldouble)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // PICONTAINERS_H
|
#endif // PICONTAINERS_H
|
||||||
|
|||||||
477
pideque.h
Normal file
477
pideque.h
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
/*! \file pideque.h
|
||||||
|
* \brief Dynamic array of any type
|
||||||
|
*
|
||||||
|
* This file declares PIDeque
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Dynamic array of any type
|
||||||
|
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 PIDEQUE_H
|
||||||
|
#define PIDEQUE_H
|
||||||
|
|
||||||
|
#include "piincludes.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class PIDeque {
|
||||||
|
public:
|
||||||
|
PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
|
//printf("new vector 1 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
|
//printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
|
||||||
|
}
|
||||||
|
PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
|
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
|
alloc(other.pid_size, true);
|
||||||
|
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
||||||
|
//printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
|
||||||
|
}
|
||||||
|
PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
|
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
|
alloc(size, true);
|
||||||
|
newT(pid_data + pid_start, data, pid_size);
|
||||||
|
//printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
|
||||||
|
}
|
||||||
|
PIDeque(size_t pid_size, const T & f = T()): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
|
//printf("new vector 3 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
|
resize(pid_size, f);
|
||||||
|
//printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
|
||||||
|
}
|
||||||
|
~PIDeque() {
|
||||||
|
//printf("delete deque %p (%s) (s=%d, rs=%d, st=%d, d=%p) ... ~{\n", this, typeid(T).name(), int(pid_size), int(pid_rsize), int(pid_start), pid_data);
|
||||||
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
|
dealloc();
|
||||||
|
//deleteRaw(pid_tdata);
|
||||||
|
_reset();
|
||||||
|
//printf("}~\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
PIDeque<T> & operator =(const PIDeque<T> & other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
|
alloc(other.pid_size, true);
|
||||||
|
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
class iterator {
|
||||||
|
friend class PIDeque<T>;
|
||||||
|
private:
|
||||||
|
iterator(PIDeque<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
|
PIDeque<T> * parent;
|
||||||
|
size_t pos;
|
||||||
|
public:
|
||||||
|
iterator(): parent(0) {}
|
||||||
|
T & operator *() {return (*parent)[pos];}
|
||||||
|
const T & operator *() const {return (*parent)[pos];}
|
||||||
|
void operator ++() {++pos;}
|
||||||
|
void operator ++(int) {++pos;}
|
||||||
|
void operator --() {--pos;}
|
||||||
|
void operator --(int) {--pos;}
|
||||||
|
bool operator ==(const iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_iterator {
|
||||||
|
friend class PIDeque<T>;
|
||||||
|
private:
|
||||||
|
const_iterator(const PIDeque<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
|
const PIDeque<T> * parent;
|
||||||
|
size_t pos;
|
||||||
|
public:
|
||||||
|
const_iterator(): parent(0) {}
|
||||||
|
//T & operator *() {return (*parent)[pos];}
|
||||||
|
const T & operator *() const {return (*parent)[pos];}
|
||||||
|
void operator ++() {++pos;}
|
||||||
|
void operator ++(int) {++pos;}
|
||||||
|
void operator --() {--pos;}
|
||||||
|
void operator --(int) {--pos;}
|
||||||
|
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class reverse_iterator {
|
||||||
|
friend class PIDeque<T>;
|
||||||
|
private:
|
||||||
|
reverse_iterator(PIDeque<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
|
PIDeque<T> * parent;
|
||||||
|
size_t pos;
|
||||||
|
public:
|
||||||
|
reverse_iterator(): parent(0) {}
|
||||||
|
T & operator *() {return (*parent)[pos];}
|
||||||
|
const T & operator *() const {return (*parent)[pos];}
|
||||||
|
void operator ++() {--pos;}
|
||||||
|
void operator ++(int) {--pos;}
|
||||||
|
void operator --() {++pos;}
|
||||||
|
void operator --(int) {++pos;}
|
||||||
|
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_reverse_iterator {
|
||||||
|
friend class PIDeque<T>;
|
||||||
|
private:
|
||||||
|
const_reverse_iterator(const PIDeque<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
|
const PIDeque<T> * parent;
|
||||||
|
size_t pos;
|
||||||
|
public:
|
||||||
|
const_reverse_iterator(): parent(0) {}
|
||||||
|
//T & operator *() {return (*parent)[pos];}
|
||||||
|
const T & operator *() const {return (*parent)[pos];}
|
||||||
|
void operator ++() {--pos;}
|
||||||
|
void operator ++(int) {--pos;}
|
||||||
|
void operator --() {++pos;}
|
||||||
|
void operator --(int) {++pos;}
|
||||||
|
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator begin() {return iterator(this, 0);}
|
||||||
|
iterator end() {return iterator(this, pid_size);}
|
||||||
|
const_iterator begin() const {return const_iterator(this, 0);}
|
||||||
|
const_iterator end() const {return const_iterator(this, pid_size);}
|
||||||
|
reverse_iterator rbegin() {return reverse_iterator(this, pid_size - 1);}
|
||||||
|
reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||||
|
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, pid_size - 1);}
|
||||||
|
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||||
|
|
||||||
|
size_t size() const {return pid_size;}
|
||||||
|
ssize_t size_s() const {return pid_size;}
|
||||||
|
size_t length() const {return pid_size;}
|
||||||
|
size_t capacity() const {return pid_rsize;}
|
||||||
|
bool isEmpty() const {return (pid_size == 0);}
|
||||||
|
|
||||||
|
T & operator [](size_t index) {return pid_data[pid_start + index];}
|
||||||
|
T & at(size_t index) {return pid_data[pid_start + index];}
|
||||||
|
const T & operator [](size_t index) const {return pid_data[pid_start + index];}
|
||||||
|
const T & at(size_t index) const {return pid_data[pid_start + index];}
|
||||||
|
T & back() {return pid_data[pid_start + pid_size - 1];}
|
||||||
|
const T & back() const {return pid_data[pid_start + pid_size - 1];}
|
||||||
|
T & front() {return pid_data[pid_start];}
|
||||||
|
const T & front() const {return pid_data[pid_start];}
|
||||||
|
bool operator ==(const PIDeque<T> & t) const {if (pid_size != t.pid_size) return false; for (size_t i = 0; i < pid_size; ++i) if (t[i] != pid_data[pid_start + i]) return false; return true;}
|
||||||
|
bool operator !=(const PIDeque<T> & t) const {if (pid_size != t.pid_size) return true; for (size_t i = 0; i < pid_size; ++i) if (t[i] != pid_data[pid_start + i]) return true; return false;}
|
||||||
|
bool contains(const T & v) const {for (size_t i = pid_start; i < pid_start + pid_size; ++i) if (v == pid_data[i]) return true; return false;}
|
||||||
|
int etries(const T & v) const {int ec = 0; for (size_t i = pid_start; i < pid_start + pid_size; ++i) if (v == pid_data[i]) ++ec; return ec;}
|
||||||
|
|
||||||
|
T * data(size_t index = 0) {return &(pid_data[pid_start + index]);}
|
||||||
|
const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);}
|
||||||
|
PIDeque<T> & clear() {resize(0); return *this;}
|
||||||
|
PIDeque<T> & fill(const T & f = T()) {
|
||||||
|
//if (sizeof(T) == 1) memset(pid_data, f, pid_size);
|
||||||
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
|
//zeroRaw(pid_data, pid_size);
|
||||||
|
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
|
||||||
|
elementNew(pid_data + i, f);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PIDeque<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
|
PIDeque<T> & assign(size_t new_size, const T & f) {resize(new_size); return fill(f);}
|
||||||
|
PIDeque<T> & resize(size_t new_size, const T & f = T()) {
|
||||||
|
if (new_size < pid_size) {
|
||||||
|
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
|
||||||
|
pid_size = new_size;
|
||||||
|
}
|
||||||
|
if (new_size > pid_size) {
|
||||||
|
size_t os = pid_size;
|
||||||
|
alloc(new_size, true);
|
||||||
|
//if (sizeof(T) == 1) memset(&(pid_data[os]), f, ds);
|
||||||
|
//zeroRaw(&(pid_data[os]), new_size - os);
|
||||||
|
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) elementNew(pid_data + i, f);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PIDeque<T> & reserve(size_t new_size) {if (new_size <= pid_rsize) return *this; size_t os = pid_size; alloc(new_size, true); pid_size = os; return *this;}
|
||||||
|
|
||||||
|
PIDeque<T> & insert(size_t index, const T & v = T()) {
|
||||||
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
|
//piCout << "insert" << dir << index << pid_size << pid_rsize << pid_start << "!<";
|
||||||
|
if (dir) {
|
||||||
|
alloc(pid_size + 1, true);
|
||||||
|
if (index < pid_size - 1) {
|
||||||
|
size_t os = pid_size - index - 1;
|
||||||
|
memmove(&(pid_data[index + pid_start + 1]), &(pid_data[index + pid_start]), os * sizeof(T));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pid_start--;
|
||||||
|
alloc(pid_size + 1, false);
|
||||||
|
//piCout << "insert front" << pid_size << pid_rsize << pid_start << "!<";
|
||||||
|
if (index > 0)
|
||||||
|
memmove(&(pid_data[pid_start]), &(pid_data[pid_start + 1]), index * sizeof(T));
|
||||||
|
}
|
||||||
|
//piCout << "insert" << pid_start << index << (pid_start + ssize_t(index)) << pid_size << ">!";
|
||||||
|
elementNew(pid_data + pid_start + index, v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PIDeque<T> & insert(size_t index, const PIDeque<T> & other) {
|
||||||
|
if (other.isEmpty()) return *this;
|
||||||
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
|
//piCout << "insert" << dir << index << pid_size << pid_rsize << pid_start << "!<";
|
||||||
|
if (dir) {
|
||||||
|
ssize_t os = pid_size - index;
|
||||||
|
alloc(pid_size + other.pid_size, true);
|
||||||
|
if (os > 0)
|
||||||
|
memmove(&(pid_data[index + pid_start + other.pid_size]), &(pid_data[index + pid_start]), os * sizeof(T));
|
||||||
|
} else {
|
||||||
|
pid_start -= other.pid_size;
|
||||||
|
alloc(pid_size + other.pid_size, false);
|
||||||
|
//piCout << "insert front" << pid_size << pid_rsize << pid_start << "!<";
|
||||||
|
if (index > 0)
|
||||||
|
memmove(&(pid_data[pid_start]), &(pid_data[pid_start + other.pid_size]), index * sizeof(T));
|
||||||
|
}
|
||||||
|
//piCout << "insert" << pid_start << index << (pid_start + ssize_t(index)) << pid_size << ">!";
|
||||||
|
newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PIDeque<T> & remove(size_t index, size_t count = 1) {
|
||||||
|
if (count == 0) return *this;
|
||||||
|
if (index + count >= pid_size) {
|
||||||
|
resize(index);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
size_t os = pid_size - index - count;
|
||||||
|
deleteT(&(pid_data[index + pid_start]), count);
|
||||||
|
if (os <= index) {
|
||||||
|
//if (true) {
|
||||||
|
if (os > 0) memmove(&(pid_data[index + pid_start]), &(pid_data[index + pid_start + count]), os * sizeof(T));
|
||||||
|
} else {
|
||||||
|
if (index > 0) memmove(&(pid_data[pid_start + count]), &(pid_data[pid_start]), index * sizeof(T));
|
||||||
|
pid_start += count;
|
||||||
|
}
|
||||||
|
pid_size -= count;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(PIDeque<T> & other) {
|
||||||
|
piSwap<T*>(pid_data, other.pid_data);
|
||||||
|
piSwap<size_t>(pid_size, other.pid_size);
|
||||||
|
piSwap<size_t>(pid_rsize, other.pid_rsize);
|
||||||
|
piSwap<size_t>(pid_start, other.pid_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int (*CompareFunc)(const T * , const T * );
|
||||||
|
static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);}
|
||||||
|
PIDeque<T> & sort(CompareFunc compare = compare_func) {qsort(pid_data + pid_start, pid_size, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
|
||||||
|
|
||||||
|
PIDeque<T> & enlarge(llong pid_size) {llong ns = size_s() + pid_size; if (ns <= 0) clear(); else resize(size_t(ns)); return *this;}
|
||||||
|
|
||||||
|
PIDeque<T> & removeOne(const T & v) {for (size_t i = 0; i < pid_size; ++i) if (pid_data[i + pid_start] == v) {remove(i); return *this;} return *this;}
|
||||||
|
PIDeque<T> & removeAll(const T & v) {for (llong i = 0; i < pid_size; ++i) if (pid_data[i + pid_start] == v) {remove(i); --i;} return *this;}
|
||||||
|
|
||||||
|
PIDeque<T> & push_back(const T & v) {alloc(pid_size + 1, true); elementNew(pid_data + pid_start + pid_size - 1, v); return *this;}
|
||||||
|
PIDeque<T> & append(const T & v) {return push_back(v);}
|
||||||
|
PIDeque<T> & operator <<(const T & v) {return push_back(v);}
|
||||||
|
PIDeque<T> & operator <<(const PIDeque<T> & t) {
|
||||||
|
size_t ps = pid_size;
|
||||||
|
alloc(pid_size + t.pid_size, true);
|
||||||
|
newT(pid_data + ps + pid_start, t.pid_data + t.pid_start, t.pid_size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PIDeque<T> & push_front(const T & v) {insert(0, v); return *this;}
|
||||||
|
PIDeque<T> & prepend(const T & v) {return push_front(v);}
|
||||||
|
|
||||||
|
PIDeque<T> & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;}
|
||||||
|
PIDeque<T> & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;}
|
||||||
|
|
||||||
|
T take_back() {T t(back()); pop_back(); return t;}
|
||||||
|
T take_front() {T t(front()); pop_front(); return t;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
|
||||||
|
/*void * qmemmove(void * dst, void * src, size_t size) {
|
||||||
|
if (piAbs<ssize_t>(ssize_t(dst) - ssize_t(src)) >= size)
|
||||||
|
memcpy(dst, src, size);
|
||||||
|
else {
|
||||||
|
char * tb = new char[size];
|
||||||
|
memcpy(tb, src, size);
|
||||||
|
memcpy(dst, tb, size);
|
||||||
|
delete tb;
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}*/
|
||||||
|
inline size_t asize(ssize_t s) {
|
||||||
|
if (s <= 0) return 0;
|
||||||
|
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s))
|
||||||
|
return pid_rsize + pid_rsize;
|
||||||
|
size_t t = 0, s_ = size_t(s) - 1;
|
||||||
|
while (s_ >> t) ++t;
|
||||||
|
return (1 << t);
|
||||||
|
}
|
||||||
|
inline void newT(T * dst, const T * src, size_t s) {
|
||||||
|
for (size_t i = 0; i < s; ++i)
|
||||||
|
elementNew(dst + i, src[i]);
|
||||||
|
}
|
||||||
|
inline T * newRaw(size_t s) {
|
||||||
|
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
|
||||||
|
//uchar * ret = new uchar[s * sizeof(T)];
|
||||||
|
uchar * ret = (uchar*)(malloc(s * sizeof(T)));//new uchar[];
|
||||||
|
//zeroRaw((T*)ret, s);
|
||||||
|
//cout << std::hex << " > (new 0x" << (llong)ret << ") ok]!" << endl;
|
||||||
|
return (T*)ret;
|
||||||
|
}
|
||||||
|
/*void reallocRawTemp(size_t s) {
|
||||||
|
if (pid_tdata == 0) pid_tdata = (T*)(malloc(s * sizeof(T)));
|
||||||
|
else pid_tdata = (T*)(realloc(pid_tdata, s * sizeof(T)));
|
||||||
|
}*/
|
||||||
|
inline void deleteT(T * d, size_t sz) {
|
||||||
|
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
|
if ((uchar*)d != 0) {
|
||||||
|
for (size_t i = 0; i < sz; ++i)
|
||||||
|
elementDelete(d[i]);
|
||||||
|
//zeroRaw(d, sz);
|
||||||
|
}
|
||||||
|
//cout << " > ok]~" << endl;
|
||||||
|
}
|
||||||
|
inline void deleteRaw(T *& d) {
|
||||||
|
//cout << " ~[("<<this<<")deleteRaw " << std::dec << pid_rsize << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
|
if ((uchar*)d != 0) free((uchar*)d);
|
||||||
|
d = 0;
|
||||||
|
//cout << " > ok]~" << endl;
|
||||||
|
}
|
||||||
|
void zeroRaw(T * d, size_t s) {
|
||||||
|
//cout << " ~[("<<this<<")zeroRaw " << std::dec << s << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
|
if ((uchar*)d != 0) memset(d, 0, s*sizeof(T));
|
||||||
|
//cout << " > ok]~" << endl;
|
||||||
|
}
|
||||||
|
inline void elementNew(T * to, const T & from) {new(to)T(from);}
|
||||||
|
inline void elementDelete(T & from) {from.~T();}
|
||||||
|
void dealloc() {deleteRaw(pid_data);}
|
||||||
|
inline void checkMove(bool direction) {
|
||||||
|
if (pid_size >= 4 && pid_size < pid_rsize / 4) {
|
||||||
|
/*if (direction) {
|
||||||
|
if (pid_start >= 4 && pid_start > pid_size + pid_size && pid_start > pid_rsize / 2) {
|
||||||
|
piCout << (int)this << "checkMove" << direction << pid_start << (int)pid_data << pid_rsize << pid_size;
|
||||||
|
piCout << (int)this << "move from" << pid_start << "to" << pid_size << "," << (int)pid_data << pid_rsize << pid_size;
|
||||||
|
memmove(pid_data + pid_size, pid_data + pid_start, pid_size * sizeof(T));
|
||||||
|
pid_start = pid_size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ssize_t(pid_start) < ssize_t(pid_rsize) - pid_size - pid_size && ssize_t(pid_start) < ssize_t(pid_rsize / 2) - pid_size) {
|
||||||
|
piCout << (int)this << "checkMove" << direction << pid_start << (int)pid_data << pid_rsize << pid_size;
|
||||||
|
piCout << (int)this << "move from" << pid_start << "to" << (ssize_t(pid_rsize) - pid_size) << "," << (int)pid_data << pid_rsize << pid_size;
|
||||||
|
memmove(pid_data + ssize_t(pid_rsize) - pid_size - pid_size, pid_data + pid_start, pid_size * sizeof(T));
|
||||||
|
pid_start = ssize_t(pid_rsize) - pid_size - pid_size;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
if (pid_start < pid_size + pid_size || pid_start > pid_rsize - pid_size - pid_size) {
|
||||||
|
size_t ns = (pid_rsize - pid_size) / 2;
|
||||||
|
if (pid_start != ns) {
|
||||||
|
memmove(pid_data + ns, pid_data + pid_start, pid_size * sizeof(T));
|
||||||
|
pid_start = ns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void alloc(size_t new_size, bool direction) { // direction == true -> alloc forward
|
||||||
|
if (direction) {
|
||||||
|
if (pid_start + new_size <= pid_rsize) {
|
||||||
|
pid_size = new_size;
|
||||||
|
checkMove(direction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pid_size = new_size;
|
||||||
|
size_t as = asize(pid_start + new_size);
|
||||||
|
if (as != pid_rsize) {
|
||||||
|
pid_data = (T*)(realloc(pid_data, as*sizeof(T)));
|
||||||
|
pid_rsize = as;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t as = asize(piMax<ssize_t>(new_size, pid_rsize) - pid_start);
|
||||||
|
//piCout << "alloc" << new_size << pid_size << pid_rsize << as << pid_start;
|
||||||
|
if (pid_start >= 0 && as <= pid_rsize) {
|
||||||
|
pid_size = new_size;
|
||||||
|
checkMove(direction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t os = pid_size;
|
||||||
|
pid_size = new_size;
|
||||||
|
if (as > pid_rsize) {
|
||||||
|
//piCout << "alloc new size" << as;
|
||||||
|
//cout << std::hex << " ![("<<this<<")realloc " << pid_data << " data ... <\n" << endl;
|
||||||
|
T * td = newRaw(as);
|
||||||
|
//piCout << "pid_start" << pid_start << (pid_start + ssize_t(as) - os);
|
||||||
|
ssize_t ost = pid_start, ns = 0;
|
||||||
|
if (ost < 0) {ns -= ost; ost = 0;}
|
||||||
|
pid_start += ssize_t(as) - os;
|
||||||
|
if (os > 0 && pid_data != 0) {
|
||||||
|
memcpy(td + pid_start + ns, pid_data + ost, os * sizeof(T));
|
||||||
|
deleteRaw(pid_data);
|
||||||
|
}
|
||||||
|
pid_data = td;
|
||||||
|
pid_rsize = as;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//checkMove(direction);
|
||||||
|
//piCout << "alloc new start" << pid_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * pid_data;
|
||||||
|
size_t pid_size, pid_rsize;
|
||||||
|
size_t pid_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __PIDEQUE_SIMPLE_TYPE__(T) \
|
||||||
|
template<> inline void PIDeque<T>::newT(T * dst, const T * src, size_t s) {memcpy(dst, src, s * sizeof(T));} \
|
||||||
|
template<> inline void PIDeque<T>::deleteT(T * d, size_t sz) {;} \
|
||||||
|
template<> inline void PIDeque<T>::elementNew(T * to, const T & from) {(*to) = from;} \
|
||||||
|
template<> inline void PIDeque<T>::elementDelete(T & from) {;}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
|
class PIP_EXPORT PIDeque: public deque<Type, Allocator> {
|
||||||
|
typedef PIDeque<Type, Allocator> _CDeque;
|
||||||
|
typedef deque<Type, Allocator> _stlc;
|
||||||
|
public:
|
||||||
|
PIDeque() {piMonitor.containers++;}
|
||||||
|
PIDeque(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);}
|
||||||
|
PIDeque(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
|
||||||
|
PIDeque(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||||
|
PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||||
|
~PIDeque() {piMonitor.containers--;}
|
||||||
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
|
||||||
|
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
|
||||||
|
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
||||||
|
PIDeque<Type> toVector() {PIDeque<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define __PIDEQUE_SIMPLE_FUNCTIONS__(T)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline PICout operator <<(PICout s, const PIDeque<T> & v) {s.space(); s.setControl(0, true); s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PIDEQUE_H
|
||||||
238
pidir.cpp
238
pidir.cpp
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "pidir.h"
|
#include "pidir.h"
|
||||||
|
|
||||||
#if !defined(WINDOWS) && !defined(ANDROID)
|
#if !defined(ANDROID)
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
const PIChar PIDir::separator = '\\';
|
const PIChar PIDir::separator = '\\';
|
||||||
#else
|
#else
|
||||||
@@ -27,47 +27,40 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PIDir::PIDir() {
|
PIDir::PIDir(const PIString & dir) {
|
||||||
path_ = PIDir::current().path_;
|
path_ = dir;
|
||||||
dir_ = 0;
|
|
||||||
open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDir::PIDir(const PIString & dir) {
|
PIDir::PIDir(const PIFile & file) {
|
||||||
path_ = dir;
|
path_ = file.path();
|
||||||
dir_ = 0;
|
if (isExists()) return;
|
||||||
open();
|
int pos = path_.findLast(separator);
|
||||||
|
path_.cutRight(path_.size_s() - pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::operator ==(const PIDir & d) const {
|
bool PIDir::operator ==(const PIDir & d) const {
|
||||||
return true;
|
return d.absolutePath() == absolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::open() {
|
bool PIDir::isAbsolute() const {
|
||||||
if (dir_ != 0)
|
if (path_.size() == 0) return false;
|
||||||
if (!close())
|
#ifdef WINDOWS
|
||||||
return false;
|
if (path_.size() < 3) return false;
|
||||||
dir_ = opendir(path_.data());
|
return (path_[1] == ":");
|
||||||
return (dir_ != 0);
|
#else
|
||||||
|
return (path_[0] == separator);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::close() {
|
PIString PIDir::absolutePath() const {
|
||||||
if (dir_ == 0) return true;
|
if (isAbsolute()) return path_;
|
||||||
if (closedir(dir_) == 0) {
|
PIDir d(path_);
|
||||||
dir_ = 0;
|
d.setDir(PIDir::current().path_ + separator + path_);
|
||||||
return true;
|
return d.path_;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIDir::absolutePath() {
|
|
||||||
//di;
|
|
||||||
return PIString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -75,12 +68,15 @@ PIDir & PIDir::cleanPath() {
|
|||||||
PIString p(path_);
|
PIString p(path_);
|
||||||
if (p.size() == 0) {
|
if (p.size() == 0) {
|
||||||
path_ = ".";
|
path_ = ".";
|
||||||
open();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
path_.replaceAll(PIString(separator) + PIString(separator), PIString(separator));
|
path_.replaceAll(PIString(separator) + PIString(separator), PIString(separator));
|
||||||
bool isAbs = isAbsolute();
|
bool is_abs = isAbsolute();
|
||||||
PIStringList l = PIString(p).split(separator);
|
PIStringList l = PIString(p).split(separator);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
PIString letter;
|
||||||
|
if (is_abs) letter = l.take_front();
|
||||||
|
#endif
|
||||||
l.removeAll(".");
|
l.removeAll(".");
|
||||||
l.removeAll("");
|
l.removeAll("");
|
||||||
bool found = true;
|
bool found = true;
|
||||||
@@ -102,112 +98,216 @@ PIDir & PIDir::cleanPath() {
|
|||||||
if (l.size() > 0) if (l[0] == "..")
|
if (l.size() > 0) if (l[0] == "..")
|
||||||
{l.pop_front(); found = true;}
|
{l.pop_front(); found = true;}
|
||||||
}
|
}
|
||||||
path_ = separator + l.join(separator);
|
path_ = separator + l.join(separator); /// TODO think about windows
|
||||||
if (!isAbs) path_.insert(0, ".");
|
if (!is_abs) path_.prepend(".");
|
||||||
if (path_.size() == 0) path_ = "./";
|
#ifdef WINDOWS
|
||||||
open();
|
else path_.prepend(letter);
|
||||||
|
#endif
|
||||||
|
if (path_.size() == 0) path_ = ".";
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDir & PIDir::setDir(const PIString & path) {
|
||||||
|
path_ = path;
|
||||||
|
cleanPath();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDir & PIDir::cd(const PIString & path) {
|
PIDir & PIDir::cd(const PIString & path) {
|
||||||
if (path_.size() == 0) return *this;
|
if (path_.size() == 0) return *this;
|
||||||
if (path_[path_.size() - 1] != separator) path_ << separator;
|
if (path_[path_.size() - 1] != separator) path_ += separator;
|
||||||
path_ << path;
|
path_ += path;
|
||||||
return cleanPath();
|
return cleanPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::mkDir(bool withParents) {
|
bool PIDir::make(bool withParents) {
|
||||||
PIDir d = cleanedPath();
|
PIDir d = cleanedPath();
|
||||||
PIString tp;
|
PIString tp;
|
||||||
int ret;
|
bool is_abs = isAbsolute();
|
||||||
bool isAbs = isAbsolute();
|
|
||||||
if (withParents) {
|
if (withParents) {
|
||||||
PIStringList l = d.path_.split(separator);
|
PIStringList l = d.path_.split(separator);
|
||||||
for (int i = l.size_s() - 1; i >= 0; --i) {
|
for (int i = l.size_s() - 1; i >= 0; --i) {
|
||||||
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
|
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
|
||||||
else {
|
else {
|
||||||
tp = separator;
|
tp = separator;
|
||||||
if (!isAbs) tp.push_front('.');
|
if (!is_abs) tp.push_front('.');
|
||||||
}
|
}
|
||||||
//cout << tp << endl;
|
//cout << tp << endl;
|
||||||
if (isExists(tp)) {
|
if (isExists(tp)) {
|
||||||
for (int j = i + 1; j <= l.size_s(); ++j) {
|
for (int j = i + 1; j <= l.size_s(); ++j) {
|
||||||
tp = PIStringList(l).remove(j, l.size_s() - j).join(separator);
|
tp = PIStringList(l).remove(j, l.size_s() - j).join(separator);
|
||||||
//cout << tp << endl;
|
//cout << tp << endl;
|
||||||
ret = mkdir(tp.data(), 16877);
|
if (makeDir(tp)) continue;
|
||||||
if (ret == 0) continue;
|
else return false;
|
||||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
ret = mkdir(d.path_.data(), 16877);
|
if (makeDir(d.path_)) return true;
|
||||||
if (ret == 0) return true;
|
|
||||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno));
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIVector<PIDir::DirEntry> PIDir::entries() {
|
PIVector<PIDir::DirEntry> PIDir::entries() {
|
||||||
PIDir d = cleanedPath();
|
|
||||||
PIString p = d.path_;
|
|
||||||
dirent ** list;
|
|
||||||
#ifndef QNX
|
|
||||||
int cnt = scandir(const_cast<char*>(p.data()), &list, 0, alphasort);
|
|
||||||
#else
|
|
||||||
int cnt = scandir(const_cast<char*>(p.data()), 0, 0, alphasort);
|
|
||||||
#endif
|
|
||||||
struct stat fs;
|
|
||||||
PIVector<DirEntry> l;
|
PIVector<DirEntry> l;
|
||||||
|
PIString p(cleanedPath().path_);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
WIN32_FIND_DATA fd; memset(&fd, 0, sizeof(fd));
|
||||||
|
p += "\\*";
|
||||||
|
void * hf = FindFirstFile((LPCTSTR)(p.data()), &fd);
|
||||||
|
if (!hf) return l;
|
||||||
|
LARGE_INTEGER filesize;
|
||||||
|
do {
|
||||||
|
int m = 0;
|
||||||
|
filesize.LowPart = filesize.HighPart = 0;
|
||||||
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) m |= S_IFHDN;
|
||||||
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) m |= S_IFBLK;
|
||||||
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) m |= S_IFDIR;
|
||||||
|
else {
|
||||||
|
m |= S_IFREG;
|
||||||
|
filesize.LowPart = fd.nFileSizeLow;
|
||||||
|
filesize.HighPart = fd.nFileSizeHigh;
|
||||||
|
}
|
||||||
|
l << DirEntry(fd.cFileName, m, filesize.QuadPart);
|
||||||
|
memset(&fd, 0, sizeof(fd));
|
||||||
|
} while (FindNextFile(hf, &fd) != 0);
|
||||||
|
FindClose(hf);
|
||||||
|
#else
|
||||||
|
dirent ** list;
|
||||||
|
# ifndef QNX
|
||||||
|
int cnt = scandir(p.data(), &list, 0, versionsort);
|
||||||
|
# else
|
||||||
|
int cnt = scandir(const_cast<char*>(p.data()), 0, 0, versionsort);
|
||||||
|
# endif
|
||||||
|
struct stat fs;
|
||||||
for (int i = 0; i < cnt; ++i) {
|
for (int i = 0; i < cnt; ++i) {
|
||||||
stat((p + separator + PIString(list[i]->d_name)).data(), &fs);
|
stat((p + separator + PIString(list[i]->d_name)).data(), &fs);
|
||||||
l.push_back(DirEntry(list[i]->d_name, fs.st_mode, fs.st_size));
|
l << DirEntry(list[i]->d_name, fs.st_mode, fs.st_size);
|
||||||
|
if (list[i]->d_name[0] == '.') l.back().mode |= S_IFHDN;
|
||||||
delete list[i];
|
delete list[i];
|
||||||
}
|
}
|
||||||
delete list;
|
delete list;
|
||||||
|
#endif
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool PIDir::isExists(const PIString & path) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
return (GetFileAttributes((LPCTSTR)(path.data())) & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
#else
|
||||||
|
DIR * dir_ = opendir(path.data());
|
||||||
|
if (dir_ == 0) return false;
|
||||||
|
closedir(dir_);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDir PIDir::current() {
|
PIDir PIDir::current() {
|
||||||
char rc[1024];
|
char rc[1024];
|
||||||
|
#ifdef WINDOWS
|
||||||
|
memset(rc, 0, 1024);
|
||||||
|
if (GetCurrentDirectory(1024, (LPTSTR)rc) == 0) return PIString();
|
||||||
|
#else
|
||||||
if (getcwd(rc, 1024) == 0) return PIString();
|
if (getcwd(rc, 1024) == 0) return PIString();
|
||||||
|
#endif
|
||||||
return PIDir(rc);
|
return PIDir(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDir PIDir::home() {
|
PIDir PIDir::home() {
|
||||||
return PIDir(getenv("HOME"));
|
char * rc = 0;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
rc = new char[1024];
|
||||||
|
memset(rc, 0, 1024);
|
||||||
|
if (ExpandEnvironmentStrings((LPCTSTR)"%HOMEPATH%", (LPTSTR)rc, 1024) == 0) {
|
||||||
|
delete[] rc;
|
||||||
|
return PIDir();
|
||||||
|
}
|
||||||
|
PIString s(rc);
|
||||||
|
delete[] rc;
|
||||||
|
return PIDir(s);
|
||||||
|
#else
|
||||||
|
rc = getenv("HOME");
|
||||||
|
if (rc == 0) return PIDir();
|
||||||
|
return PIDir(rc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDir PIDir::temporary() {
|
PIDir PIDir::temporary() {
|
||||||
char * rc;
|
char * rc = 0;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
rc = new char[1024];
|
||||||
|
memset(rc, 0, 1024);
|
||||||
|
int ret = GetTempPath(1024, (LPTSTR)rc);
|
||||||
|
if (ret == 0) {
|
||||||
|
delete[] rc;
|
||||||
|
return PIDir();
|
||||||
|
}
|
||||||
|
PIString s(rc);
|
||||||
|
delete[] rc;
|
||||||
|
return PIDir(s);
|
||||||
|
#else
|
||||||
rc = tmpnam(0);
|
rc = tmpnam(0);
|
||||||
|
if (rc == 0) return PIDir();
|
||||||
PIString s(rc);
|
PIString s(rc);
|
||||||
return PIDir(s.left(s.findLast(PIDir::separator)));
|
return PIDir(s.left(s.findLast(PIDir::separator)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::mkDir(const PIString & path, bool withParents) {
|
bool PIDir::make(const PIString & path, bool withParents) {
|
||||||
PIDir d(path);
|
PIDir d(path);
|
||||||
if (d.isExists()) return true;
|
if (d.isExists()) return true;
|
||||||
return d.mkDir(withParents);
|
return d.make(withParents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::rmDir(const PIString & path) {
|
bool PIDir::setCurrent(const PIString & path) {
|
||||||
string s = path.stdString();
|
#ifdef WINDOWS
|
||||||
int ret = rmdir(s.c_str());
|
if (SetCurrentDirectory((LPCTSTR)(path.data())) != 0) return true;
|
||||||
if (ret == 0) return true;
|
#else
|
||||||
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
if (chdir(path.data()) == 0) return true;
|
||||||
|
#endif
|
||||||
|
printf("[PIDir] setCurrent(\"%s\") error: %s\n", path.data(), errorString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIDir::makeDir(const PIString & path) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (CreateDirectory((LPCTSTR)(path.data()), NULL) != 0) return true;
|
||||||
|
#else
|
||||||
|
if (mkdir(path.data(), 16877) == 0) return true;
|
||||||
|
#endif
|
||||||
|
printf("[PIDir] makeDir(\"%s\") error: %s\n", path.data(), errorString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIDir::removeDir(const PIString & path) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (RemoveDirectory((LPCTSTR)(path.data())) != 0) return true;
|
||||||
|
#else
|
||||||
|
if (rmdir(path.data()) == 0) return true;
|
||||||
|
#endif
|
||||||
|
printf("[PIDir] removeDir(\"%s\") error: %s\n", path.data(), errorString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIDir::renameDir(const PIString & path, const PIString & new_name) {
|
||||||
|
if (::rename(path.data(), new_name.data()) == 0) return true;
|
||||||
|
printf("[PIDir] renameDir(\"%s\", \"%s\") error: %s\n", path.data(), new_name.data(), errorString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
83
pidir.h
83
pidir.h
@@ -21,26 +21,40 @@
|
|||||||
#define PIDIR_H
|
#define PIDIR_H
|
||||||
|
|
||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
#include "pistring.h"
|
#if !defined(ANDROID)
|
||||||
#if !defined(WINDOWS) && !defined(ANDROID)
|
#ifdef WINDOWS
|
||||||
#ifdef ANDROID
|
# undef S_IFDIR
|
||||||
# include <sys/dirent.h>
|
# undef S_IFREG
|
||||||
|
# undef S_IFLNK
|
||||||
|
# undef S_IFBLK
|
||||||
|
# undef S_IFCHR
|
||||||
|
# undef S_IFSOCK
|
||||||
|
# define S_IFDIR 0x01
|
||||||
|
# define S_IFREG 0x02
|
||||||
|
# define S_IFLNK 0x04
|
||||||
|
# define S_IFBLK 0x08
|
||||||
|
# define S_IFCHR 0x10
|
||||||
|
# define S_IFSOCK 0x20
|
||||||
#else
|
#else
|
||||||
|
# ifdef ANDROID
|
||||||
|
# include <sys/dirent.h>
|
||||||
|
# else
|
||||||
# include <sys/dir.h>
|
# include <sys/dir.h>
|
||||||
|
# endif
|
||||||
|
# include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/stat.h>
|
#define S_IFHDN 0x40
|
||||||
|
|
||||||
class PIP_EXPORT PIDir
|
class PIP_EXPORT PIDir
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIDir();
|
PIDir(const PIString & dir = PIString());
|
||||||
PIDir(const PIString & dir);
|
PIDir(const PIFile & file);
|
||||||
~PIDir() {close();}
|
|
||||||
|
|
||||||
struct DirEntry {
|
struct DirEntry {
|
||||||
DirEntry() {;}
|
DirEntry(const PIString & name_ = PIString(), int mode_ = 0, int size_ = 0) {
|
||||||
DirEntry(const PIString & name_, const int & mode_, const int & size_) {
|
name = name_; mode = mode_; size = size_;
|
||||||
name = name_; mode = mode_; size = size_;}
|
}
|
||||||
|
|
||||||
PIString name;
|
PIString name;
|
||||||
int mode;
|
int mode;
|
||||||
@@ -52,41 +66,62 @@ public:
|
|||||||
bool isBlockDevice() const {return (mode & S_IFBLK);}
|
bool isBlockDevice() const {return (mode & S_IFBLK);}
|
||||||
bool isCharacterDevice() const {return (mode & S_IFCHR);}
|
bool isCharacterDevice() const {return (mode & S_IFCHR);}
|
||||||
bool isSocket() const {return (mode & S_IFSOCK);}
|
bool isSocket() const {return (mode & S_IFSOCK);}
|
||||||
|
bool isHidden() const {return (mode & S_IFHDN);}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isExists() const {return (dir_ != 0);}
|
bool isExists() const {return PIDir::isExists(path_);}
|
||||||
bool isAbsolute() const {if (path_.size() == 0) return false; return (path_[0] == separator);}
|
bool isAbsolute() const;
|
||||||
|
bool isRelative() const {return !isAbsolute();}
|
||||||
|
|
||||||
const PIString & path() const {return path_;}
|
const PIString & path() const {return path_;}
|
||||||
|
PIString absolutePath() const;
|
||||||
PIDir & cleanPath();
|
PIDir & cleanPath();
|
||||||
PIDir cleanedPath() {PIDir d(path_); d.cleanPath(); return d;}
|
PIDir cleanedPath() const {PIDir d(path_); d.cleanPath(); return d;}
|
||||||
PIString absolutePath();
|
PIDir & setDir(const PIString & path);
|
||||||
bool mkDir(bool withParents = true);
|
bool setCurrent() {return PIDir::setCurrent(path_);}
|
||||||
|
|
||||||
PIVector<DirEntry> entries();
|
PIVector<DirEntry> entries();
|
||||||
|
|
||||||
|
bool make(bool withParents = true);
|
||||||
|
bool remove() {return PIDir::remove(path_);}
|
||||||
|
bool rename(const PIString & new_name) {if (!PIDir::rename(path_, new_name)) return false; path_ = new_name; return true;}
|
||||||
PIDir & cd(const PIString & path);
|
PIDir & cd(const PIString & path);
|
||||||
PIDir & up() {return cd("..");}
|
PIDir & up() {return cd("..");}
|
||||||
|
|
||||||
bool operator ==(const PIDir & d) const;
|
bool operator ==(const PIDir & d) const;
|
||||||
|
bool operator !=(const PIDir & d) const {return !((*this) == d);}
|
||||||
|
|
||||||
|
|
||||||
static const PIChar separator;
|
static const PIChar separator;
|
||||||
|
|
||||||
static PIDir current();
|
static PIDir current();
|
||||||
static PIDir home();
|
static PIDir home();
|
||||||
static PIDir temporary();
|
static PIDir temporary();
|
||||||
static bool mkDir(const PIString & path, bool withParents = true);
|
static bool isExists(const PIString & path);
|
||||||
static bool rmDir(const PIString & path);
|
static bool make(const PIString & path, bool withParents = true);
|
||||||
static bool isExists(const PIString & path) {return PIDir(path).isExists();}
|
static bool remove(const PIString & path) {return removeDir(path);}
|
||||||
//static bool rmDir(const PIString & path);
|
static bool rename(const PIString & path, const PIString & new_name) {return PIDir::renameDir(path, new_name);}
|
||||||
|
static bool setCurrent(const PIString & path);
|
||||||
|
static bool setCurrent(const PIDir & dir) {return setCurrent(dir.path_);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open();
|
static bool makeDir(const PIString & path);
|
||||||
bool close();
|
static bool removeDir(const PIString & path);
|
||||||
|
static bool renameDir(const PIString & path, const PIString & new_name);
|
||||||
|
|
||||||
PIString path_;
|
PIString path_;
|
||||||
|
|
||||||
DIR * dir_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool operator <(const PIDir::DirEntry & v0, const PIDir::DirEntry & v1) {return (v0.name < v1.name);}
|
||||||
|
inline bool operator >(const PIDir::DirEntry & v0, const PIDir::DirEntry & v1) {return (v0.name > v1.name);}
|
||||||
|
inline bool operator ==(const PIDir::DirEntry & v0, const PIDir::DirEntry & v1) {return (v0.name == v1.name);}
|
||||||
|
inline bool operator !=(const PIDir::DirEntry & v0, const PIDir::DirEntry & v1) {return (v0.name != v1.name);}
|
||||||
|
|
||||||
|
inline PICout operator <<(PICout s, const PIDir & v) {s.setControl(0, true); s << "PIDir(\"" << v.path() << "\")"; s.restoreControl(); return s;}
|
||||||
|
inline PICout operator <<(PICout s, const PIDir::DirEntry & v) {s.setControl(0, true); s << "DirEntry(\"" << v.name << "\", " << v.size << " b, " << PIString::fromNumber(v.mode, 16) << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif // PIDIR_H
|
#endif // PIDIR_H
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
|||||||
setParameters(PIEthernet::ReuseAddress);
|
setParameters(PIEthernet::ReuseAddress);
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
setPriority(piHigh);
|
setPriority(piHigh);
|
||||||
setType(TCP_Client);
|
setType(TCP_Client, false);
|
||||||
setPath(ip_port);
|
setPath(ip_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ bool PIEthernet::openDevice() {
|
|||||||
init();
|
init();
|
||||||
if (sock == -1 || path().isEmpty()) return false;
|
if (sock == -1 || path().isEmpty()) return false;
|
||||||
parseAddress(path(), &ip_, &port_);
|
parseAddress(path(), &ip_, &port_);
|
||||||
if (type() != UDP)
|
if (type() != UDP && mode() == PIIODevice::WriteOnly)
|
||||||
return true;
|
return true;
|
||||||
//piCout << "bind to" << (params[PIEthernet::Broadcast] ? "bc" : ip_) << ":" << port_ << " ...";
|
//piCout << "bind to" << (params[PIEthernet::Broadcast] ? "bc" : ip_) << ":" << port_ << " ...";
|
||||||
memset(&addr_, 0, sizeof(addr_));
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
@@ -563,6 +563,17 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIEthernet::constructFullPath() const {
|
||||||
|
PIString ret(fullPathPrefix() + "://");
|
||||||
|
ret << (type() == PIEthernet::UDP ? "UDP" : "TCP") << ":" << readIP() << ":" << readPort();
|
||||||
|
if (type() == PIEthernet::UDP) {
|
||||||
|
piForeachC (PIString & m, multicastGroups())
|
||||||
|
ret << ":mcast:" << m;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::configureFromFullPath(const PIString & full_path) {
|
void PIEthernet::configureFromFullPath(const PIString & full_path) {
|
||||||
PIStringList pl = full_path.split(":");
|
PIStringList pl = full_path.split(":");
|
||||||
bool mcast = false;
|
bool mcast = false;
|
||||||
@@ -574,8 +585,8 @@ void PIEthernet::configureFromFullPath(const PIString & full_path) {
|
|||||||
if (p == "udp") setType(UDP);
|
if (p == "udp") setType(UDP);
|
||||||
if (p == "tcp") setType(TCP_Client);
|
if (p == "tcp") setType(TCP_Client);
|
||||||
break;
|
break;
|
||||||
case 1: setReadIP(p); break;
|
case 1: setReadIP(p); setSendIP(p); break;
|
||||||
case 2: setReadPort(p.toInt()); break;
|
case 2: setReadPort(p.toInt()); setSendPort(p.toInt()); break;
|
||||||
}
|
}
|
||||||
if (i <= 2) continue;
|
if (i <= 2) continue;
|
||||||
if (i % 2 == 1) {if (p.toLowerCase() == "mcast") mcast = true;}
|
if (i % 2 == 1) {if (p.toLowerCase() == "mcast") mcast = true;}
|
||||||
|
|||||||
21
piethernet.h
21
piethernet.h
@@ -83,23 +83,23 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Returns read address in format "i.i.i.i:p"
|
//! Returns read address in format "i.i.i.i:p"
|
||||||
PIString readAddress() {return path();}
|
PIString readAddress() const {return path();}
|
||||||
|
|
||||||
//! Returns read IP
|
//! Returns read IP
|
||||||
PIString readIP() {parseAddress(path(), &ip_, &port_); return ip_;}
|
PIString readIP() const {parseAddress(path(), &ip_, &port_); return ip_;}
|
||||||
|
|
||||||
//! Returns read port
|
//! Returns read port
|
||||||
int readPort() {parseAddress(path(), &ip_, &port_); return port_;}
|
int readPort() const {parseAddress(path(), &ip_, &port_); return port_;}
|
||||||
|
|
||||||
|
|
||||||
//! Returns send address in format "i.i.i.i:p"
|
//! Returns send address in format "i.i.i.i:p"
|
||||||
PIString sendAddress() {return ip_s + ":" + PIString::fromNumber(port_s);}
|
PIString sendAddress() const {return ip_s + ":" + PIString::fromNumber(port_s);}
|
||||||
|
|
||||||
//! Returns send IP
|
//! Returns send IP
|
||||||
PIString sendIP() {return ip_s;}
|
PIString sendIP() const {return ip_s;}
|
||||||
|
|
||||||
//! Returns send port
|
//! Returns send port
|
||||||
int sendPort() {return port_s;}
|
int sendPort() const {return port_s;}
|
||||||
|
|
||||||
|
|
||||||
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
|
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
|
||||||
@@ -179,6 +179,8 @@ public:
|
|||||||
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
|
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
|
||||||
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
|
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
EVENT1(newConnection, PIEthernet * , client)
|
EVENT1(newConnection, PIEthernet * , client)
|
||||||
EVENT0(connected)
|
EVENT0(connected)
|
||||||
EVENT1(disconnected, bool, withError)
|
EVENT1(disconnected, bool, withError)
|
||||||
@@ -327,10 +329,11 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int sock, sock_s, port_, port_s, port_c, wrote;
|
int sock, sock_s, wrote;
|
||||||
|
mutable int port_, port_s, port_c;
|
||||||
bool connected_, connecting_;
|
bool connected_, connecting_;
|
||||||
sockaddr_in addr_, saddr_;
|
sockaddr_in addr_, saddr_;
|
||||||
PIString ip_, ip_s, ip_c;
|
mutable PIString ip_, ip_s, ip_c;
|
||||||
PIThread server_thread_;
|
PIThread server_thread_;
|
||||||
PIVector<PIEthernet * > clients_;
|
PIVector<PIEthernet * > clients_;
|
||||||
PIQueue<PIString> mcast_queue;
|
PIQueue<PIString> mcast_queue;
|
||||||
@@ -341,7 +344,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void server_func(void * eth);
|
static void server_func(void * eth);
|
||||||
void setType(Type t) {setProperty("type", (int)t); if (isOpened()) {closeDevice(); init(); openDevice();}}
|
void setType(Type t, bool reopen = true) {setProperty("type", (int)t); if (reopen && isOpened()) {closeDevice(); init(); openDevice();}}
|
||||||
|
|
||||||
static std::string ethErrorString() {
|
static std::string ethErrorString() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
|||||||
@@ -148,6 +148,11 @@ bool PIFile::isExists(const PIString & path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIFile::constructFullPath() const {
|
||||||
|
return fullPathPrefix() + "://" + path();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIFile::configureFromFullPath(const PIString & full_path) {
|
void PIFile::configureFromFullPath(const PIString & full_path) {
|
||||||
setPath(full_path);
|
setPath(full_path);
|
||||||
}
|
}
|
||||||
|
|||||||
5
pifile.h
5
pifile.h
@@ -92,10 +92,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Read from file to "read_to" no more than "max_size" and return readed bytes count
|
//! Read from file to "read_to" no more than "max_size" and return readed bytes count
|
||||||
int read(void * read_to, int max_size) {if (!canRead() || fd == 0) return -1; return fread(read_to, max_size, 1, fd);}
|
int read(void * read_to, int max_size) {if (!canRead() || fd == 0) return -1; return fread(read_to, 1, max_size, fd);}
|
||||||
|
|
||||||
//! Write to file "data" with size "max_size" and return written bytes count
|
//! Write to file "data" with size "max_size" and return written bytes count
|
||||||
int write(const void * data, int max_size) {if (!canWrite() || fd == 0) return -1; return fwrite(data, max_size, 1, fd);}
|
int write(const void * data, int max_size) {if (!canWrite() || fd == 0) return -1; return fwrite(data, 1, max_size, fd);}
|
||||||
|
|
||||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable() || fd == 0) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
PIFile & writeToBinLog(ushort id, const void * data, int size) {if (!isWriteable() || fd == 0) return *this; writeBinary(id).writeBinary((ushort)size); write(data, size); flush(); return *this;}
|
||||||
|
|
||||||
@@ -183,6 +183,7 @@ public:
|
|||||||
//! Read from file text representation of "v"
|
//! Read from file text representation of "v"
|
||||||
PIFile & operator >>(double & v) {if (canRead() && fd != 0) ret = fscanf(fd, "%lf", &v); return *this;}
|
PIFile & operator >>(double & v) {if (canRead() && fd != 0) ret = fscanf(fd, "%lf", &v); return *this;}
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
EVENT_HANDLER(void, clear) {close(); fd = fopen(path().data(), "w"); if (fd != 0) fclose(fd); fd = 0; opened_ = false; open();}
|
EVENT_HANDLER(void, clear) {close(); fd = fopen(path().data(), "w"); if (fd != 0) fclose(fd); fd = 0; opened_ = false; open();}
|
||||||
EVENT_HANDLER0(void, remove) {close(); std::remove(path().data());}
|
EVENT_HANDLER0(void, remove) {close(); std::remove(path().data());}
|
||||||
|
|||||||
147
piincludes.cpp
147
piincludes.cpp
@@ -40,6 +40,7 @@ clock_serv_t __pi_mac_clock;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
PIMutex __PICout_mutex__;
|
PIMutex __PICout_mutex__;
|
||||||
|
PIString __PICout_string__;
|
||||||
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -127,6 +128,9 @@ DWORD PICout::smode = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool PICout::buffer_ = false;
|
||||||
|
|
||||||
|
|
||||||
PICout::PICout(PIFlags<PICoutControl> controls): fo_(true), cc_(false), fc_(false), cnb_(10), co_(controls) {
|
PICout::PICout(PIFlags<PICoutControl> controls): fo_(true), cc_(false), fc_(false), cnb_(10), co_(controls) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (hOut == 0) {
|
if (hOut == 0) {
|
||||||
@@ -149,15 +153,19 @@ PICout::~PICout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PICout PICout::operator<<(const PICoutAction v) {
|
PICout PICout::operator <<(const PICoutAction v) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
CONSOLE_SCREEN_BUFFER_INFO sbi;
|
CONSOLE_SCREEN_BUFFER_INFO sbi;
|
||||||
COORD coord;
|
COORD coord;
|
||||||
CONSOLE_CURSOR_INFO curinfo;
|
CONSOLE_CURSOR_INFO curinfo;
|
||||||
#endif
|
#endif
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case PICoutManipulators::Flush: std::cout << std::flush; break;
|
case PICoutManipulators::Flush:
|
||||||
|
if (!PICout::buffer_)
|
||||||
|
std::cout << std::flush;
|
||||||
|
break;
|
||||||
case PICoutManipulators::Backspace:
|
case PICoutManipulators::Backspace:
|
||||||
|
if (!PICout::buffer_) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||||
coord = sbi.dwCursorPosition;
|
coord = sbi.dwCursorPosition;
|
||||||
@@ -168,8 +176,10 @@ PICout PICout::operator<<(const PICoutAction v) {
|
|||||||
#else
|
#else
|
||||||
printf("\e[1D \e[1D");
|
printf("\e[1D \e[1D");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PICoutManipulators::ShowCursor:
|
case PICoutManipulators::ShowCursor:
|
||||||
|
if (!PICout::buffer_) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleCursorInfo(hOut, &curinfo);
|
GetConsoleCursorInfo(hOut, &curinfo);
|
||||||
curinfo.bVisible = true;
|
curinfo.bVisible = true;
|
||||||
@@ -177,8 +187,10 @@ PICout PICout::operator<<(const PICoutAction v) {
|
|||||||
#else
|
#else
|
||||||
printf("\e[?25h");
|
printf("\e[?25h");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PICoutManipulators::HideCursor:
|
case PICoutManipulators::HideCursor:
|
||||||
|
if (!PICout::buffer_) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleCursorInfo(hOut, &curinfo);
|
GetConsoleCursorInfo(hOut, &curinfo);
|
||||||
curinfo.bVisible = false;
|
curinfo.bVisible = false;
|
||||||
@@ -186,8 +198,10 @@ PICout PICout::operator<<(const PICoutAction v) {
|
|||||||
#else
|
#else
|
||||||
printf("\e[?25l");
|
printf("\e[?25l");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PICoutManipulators::ClearScreen:
|
case PICoutManipulators::ClearScreen:
|
||||||
|
if (!PICout::buffer_) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/// TODO !!!
|
/// TODO !!!
|
||||||
/*GetConsoleCursorInfo(hOut, &curinfo);
|
/*GetConsoleCursorInfo(hOut, &curinfo);
|
||||||
@@ -200,6 +214,7 @@ PICout PICout::operator<<(const PICoutAction v) {
|
|||||||
#else
|
#else
|
||||||
printf("\e[H\e[J");
|
printf("\e[H\e[J");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PICoutManipulators::SaveContol: saveControl(); break;
|
case PICoutManipulators::SaveContol: saveControl(); break;
|
||||||
case PICoutManipulators::RestoreControl: restoreControl(); break;
|
case PICoutManipulators::RestoreControl: restoreControl(); break;
|
||||||
@@ -209,9 +224,19 @@ PICout PICout::operator<<(const PICoutAction v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define PINUMERICCOUT if (cnb_ == 10) std::cout << v; else std::cout << PIString::fromNumber(v, cnb_);
|
#define PICOUTTOTARGET(v) {if (PICout::buffer_) __PICout_string__ << (v); else std::cout << (v);}
|
||||||
|
#define PINUMERICCOUT if (cnb_ == 10) PICOUTTOTARGET(v) else PICOUTTOTARGET(PIString::fromNumber(v, cnb_))
|
||||||
|
|
||||||
PICout PICout::operator <<(const uchar v) {space(); if (cnb_ == 10) std::cout << ushort(v); else std::cout << PIString::fromNumber(v, cnb_); return *this;}
|
|
||||||
|
PICout PICout::operator <<(const char * v) {space(); quote(); PICOUTTOTARGET(v) quote(); return *this;}
|
||||||
|
|
||||||
|
PICout PICout::operator <<(const string & v) {space(); quote(); PICOUTTOTARGET(v) quote(); return *this;}
|
||||||
|
|
||||||
|
PICout PICout::operator <<(const bool v) {space(); if (v) PICOUTTOTARGET("true") else PICOUTTOTARGET("false") return *this;}
|
||||||
|
|
||||||
|
PICout PICout::operator <<(const char v) {space(); PICOUTTOTARGET(v) return *this;}
|
||||||
|
|
||||||
|
PICout PICout::operator <<(const uchar v) {space(); if (cnb_ == 10) PICOUTTOTARGET(ushort(v)) else PICOUTTOTARGET(PIString::fromNumber(v, cnb_)) return *this;}
|
||||||
|
|
||||||
PICout PICout::operator <<(const short int v) {space(); PINUMERICCOUT return *this;}
|
PICout PICout::operator <<(const short int v) {space(); PINUMERICCOUT return *this;}
|
||||||
|
|
||||||
@@ -229,18 +254,91 @@ PICout PICout::operator <<(const llong v) {space(); PINUMERICCOUT return *this;}
|
|||||||
|
|
||||||
PICout PICout::operator <<(const ullong v) {space(); PINUMERICCOUT return *this;}
|
PICout PICout::operator <<(const ullong v) {space(); PINUMERICCOUT return *this;}
|
||||||
|
|
||||||
PICout PICout::operator <<(const float v) {space(); std::cout << v; return *this;}
|
PICout PICout::operator <<(const float v) {space(); PICOUTTOTARGET(v) return *this;}
|
||||||
|
|
||||||
PICout PICout::operator <<(const double v) {space(); std::cout << v; return *this;}
|
PICout PICout::operator <<(const double v) {space(); PICOUTTOTARGET(v) return *this;}
|
||||||
|
|
||||||
PICout PICout::operator <<(const void * v) {space(); std::cout << "0x" << PIString::fromNumber(ullong(v), 16); return *this;}
|
PICout PICout::operator <<(const void * v) {space(); PICOUTTOTARGET("0x") PICOUTTOTARGET(PIString::fromNumber(ullong(v), 16)) 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;}
|
PICout PICout::operator <<(const PIObject * v) {
|
||||||
|
space();
|
||||||
|
if (v == 0) PICOUTTOTARGET("PIObject*(0x0)")
|
||||||
|
else {
|
||||||
|
PICOUTTOTARGET(v->className())
|
||||||
|
PICOUTTOTARGET("*(0x")
|
||||||
|
PICOUTTOTARGET(PIString::fromNumber(ullong(v), 16))
|
||||||
|
PICOUTTOTARGET(", \"")
|
||||||
|
PICOUTTOTARGET(v->name())
|
||||||
|
PICOUTTOTARGET("\")")
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PICout PICout::operator <<(const PICoutSpecialChar v) {
|
||||||
|
switch (v) {
|
||||||
|
case Null:
|
||||||
|
if (PICout::buffer_) __PICout_string__ << PIChar(0);
|
||||||
|
else std::cout << char(0);
|
||||||
|
break;
|
||||||
|
case NewLine:
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\n";
|
||||||
|
else std::cout << '\n';
|
||||||
|
fo_ = true;
|
||||||
|
break;
|
||||||
|
case Tab:
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\t";
|
||||||
|
else std::cout << '\t';
|
||||||
|
break;
|
||||||
|
case Esc:
|
||||||
|
#ifdef CC_VC
|
||||||
|
if (PICout::buffer_) __PICout_string__ << PIChar(27);
|
||||||
|
else std::cout << char(27);
|
||||||
|
#else
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\e";
|
||||||
|
else std::cout << '\e';
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case Quote:
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\"";
|
||||||
|
else std::cout << '"';
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef PICOUTTOTARGET
|
||||||
#undef PINUMERICCOUT
|
#undef PINUMERICCOUT
|
||||||
|
|
||||||
|
PICout & PICout::space() {
|
||||||
|
if (!fo_ && co_[AddSpaces]) {
|
||||||
|
if (PICout::buffer_) __PICout_string__ << " ";
|
||||||
|
else std::cout << ' ';
|
||||||
|
}
|
||||||
|
fo_ = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PICout & PICout::quote() {
|
||||||
|
if (co_[AddQuotes]) {
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\"";
|
||||||
|
else std::cout << '"';
|
||||||
|
}
|
||||||
|
fo_ = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PICout & PICout::newLine() {
|
||||||
|
if (co_[AddNewLine]) {
|
||||||
|
if (PICout::buffer_) __PICout_string__ << "\n";
|
||||||
|
else std::cout << std::endl;
|
||||||
|
}
|
||||||
|
fo_ = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PICout::applyFormat(PICoutFormat f) {
|
void PICout::applyFormat(PICoutFormat f) {
|
||||||
|
if (PICout::buffer_) return;
|
||||||
fc_ = true;
|
fc_ = true;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||||
@@ -300,6 +398,34 @@ void PICout::applyFormat(PICoutFormat f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PICout::setBufferActive(bool on, bool clear) {
|
||||||
|
PIMutexLocker ml(__PICout_mutex__);
|
||||||
|
bool ret = PICout::buffer_;
|
||||||
|
if (clear) __PICout_string__.clear();
|
||||||
|
PICout::buffer_ = on;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PICout::isBufferActive() {
|
||||||
|
return PICout::buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PICout::buffer(bool clear) {
|
||||||
|
PIMutexLocker ml(__PICout_mutex__);
|
||||||
|
PIString ret = __PICout_string__;
|
||||||
|
if (clear) __PICout_string__.clear();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICout::clearBuffer() {
|
||||||
|
PIMutexLocker ml(__PICout_mutex__);
|
||||||
|
__PICout_string__.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \class PICout
|
/*! \class PICout
|
||||||
* \brief Class for formatted output similar std::cout
|
* \brief Class for formatted output similar std::cout
|
||||||
*
|
*
|
||||||
@@ -326,11 +452,12 @@ void PICout::applyFormat(PICoutFormat f) {
|
|||||||
* PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
|
* PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
|
||||||
* It is wrap around STL and pure C++. This library can help developers write non-GUI
|
* It is wrap around STL and pure C++. This library can help developers write non-GUI
|
||||||
* projects much more quickly, efficiently and customizable than on pure C++.
|
* projects much more quickly, efficiently and customizable than on pure C++.
|
||||||
* Library contains more classes, some of them are pure abstract, some classes
|
* Library contains many classes, some of them are pure abstract, some classes
|
||||||
* can be used as they are, some classes should be inherited to new classes.
|
* can be used as they are, some classes should be inherited to new classes.
|
||||||
* PIP provide classes:
|
* PIP provide classes:
|
||||||
* * direct output to console (\a PICout)
|
* * direct output to console (\a PICout)
|
||||||
* * containers (\a PIVector, \a PIList, \a PIMap, \a PIStack)
|
* * containers (\a PIVector, \a PIList, \a PIMap, \a PIStack)
|
||||||
|
* * byte array (\a PIByteArray)
|
||||||
* * string (\a PIString, \a PIStringList)
|
* * string (\a PIString, \a PIStringList)
|
||||||
* * base object (events and handlers) (\a PIObject)
|
* * base object (events and handlers) (\a PIObject)
|
||||||
* * thread (\a PIThread)
|
* * thread (\a PIThread)
|
||||||
@@ -346,6 +473,8 @@ void PICout::applyFormat(PICoutFormat f) {
|
|||||||
* * ethernet (\a PIEthernet)
|
* * ethernet (\a PIEthernet)
|
||||||
* * USB (\a PIUSB)
|
* * USB (\a PIUSB)
|
||||||
* * packets extractor (\a PIPacketExtractor)
|
* * packets extractor (\a PIPacketExtractor)
|
||||||
|
* * binary log (\a PIBinaryLog)
|
||||||
|
* * connection quality diagnotic (\a PIDiagnostics)
|
||||||
* * command-line arguments parser (\a PICLI)
|
* * command-line arguments parser (\a PICLI)
|
||||||
* * math evaluator (\a PIEvaluator)
|
* * math evaluator (\a PIEvaluator)
|
||||||
* * peering net node (\a PIPeer)
|
* * peering net node (\a PIPeer)
|
||||||
|
|||||||
43
piincludes.h
43
piincludes.h
@@ -39,7 +39,7 @@
|
|||||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||||
|
|
||||||
//! Suffix of PIP version
|
//! Suffix of PIP version
|
||||||
#define PIP_VERSION_SUFFIX "_prealpha"
|
#define PIP_VERSION_SUFFIX "_beta2"
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
|
|
||||||
@@ -747,7 +747,10 @@ private:
|
|||||||
|
|
||||||
class PIObject;
|
class PIObject;
|
||||||
class PIMutex;
|
class PIMutex;
|
||||||
|
class PIString;
|
||||||
|
|
||||||
extern PIMutex __PICout_mutex__;
|
extern PIMutex __PICout_mutex__;
|
||||||
|
extern PIString __PICout_string__;
|
||||||
|
|
||||||
//! \brief Namespace contains enums controlled PICout
|
//! \brief Namespace contains enums controlled PICout
|
||||||
namespace PICoutManipulators {
|
namespace PICoutManipulators {
|
||||||
@@ -825,16 +828,16 @@ public:
|
|||||||
~PICout();
|
~PICout();
|
||||||
|
|
||||||
//! Output operator for strings with <tt>"const char * "</tt> type
|
//! Output operator for strings with <tt>"const char * "</tt> type
|
||||||
PICout operator <<(const char * v) {space(); quote(); std::cout << v; quote(); return *this;}
|
PICout operator <<(const char * v);
|
||||||
|
|
||||||
//! Output operator for strings with <tt>"std::string"</tt> type
|
//! Output operator for strings with <tt>"std::string"</tt> type
|
||||||
PICout operator <<(const string & v) {space(); quote(); std::cout << v; quote(); return *this;}
|
PICout operator <<(const string & v);
|
||||||
|
|
||||||
//! Output operator for boolean values
|
//! Output operator for boolean values
|
||||||
PICout operator <<(const bool v) {space(); std::cout << (v ? "true" : "false"); return *this;}
|
PICout operator <<(const bool v);
|
||||||
|
|
||||||
//! Output operator for <tt>"char"</tt> values
|
//! Output operator for <tt>"char"</tt> values
|
||||||
PICout operator <<(const char v) {space(); std::cout << v; return *this;}
|
PICout operator <<(const char v);
|
||||||
|
|
||||||
//! Output operator for <tt>"unsigned char"</tt> values
|
//! Output operator for <tt>"unsigned char"</tt> values
|
||||||
PICout operator <<(const uchar v);
|
PICout operator <<(const uchar v);
|
||||||
@@ -876,23 +879,7 @@ public:
|
|||||||
PICout operator <<(const PIObject * v);
|
PICout operator <<(const PIObject * v);
|
||||||
|
|
||||||
//! Output operator for \a PICoutSpecialChar values
|
//! Output operator for \a PICoutSpecialChar values
|
||||||
PICout operator <<(const PICoutSpecialChar v) {
|
PICout operator <<(const PICoutSpecialChar v);
|
||||||
switch (v) {
|
|
||||||
case Null: std::cout << char(0); break;
|
|
||||||
case NewLine: std::cout << '\n'; fo_ = true; break;
|
|
||||||
case Tab: std::cout << '\t'; break;
|
|
||||||
case Esc:
|
|
||||||
#ifdef CC_VC
|
|
||||||
std::cout << char(27);
|
|
||||||
#else
|
|
||||||
std::cout << '\e';
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case Quote: std::cout << '"'; break;
|
|
||||||
};
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Output operator for \a PIFlags<PICoutFormat> values
|
//! Output operator for \a PIFlags<PICoutFormat> values
|
||||||
PICout operator <<(const PIFlags<PICoutFormat> v) {
|
PICout operator <<(const PIFlags<PICoutFormat> v) {
|
||||||
@@ -955,21 +942,27 @@ public:
|
|||||||
/*! \brief Conditional put space character to output
|
/*! \brief Conditional put space character to output
|
||||||
* \details If it is not a first output and control \a AddSpaces is set
|
* \details If it is not a first output and control \a AddSpaces is set
|
||||||
* space character is put \sa \a quote(), \a newLine() */
|
* space character is put \sa \a quote(), \a newLine() */
|
||||||
inline PICout & space() {if (!fo_ && co_[AddSpaces]) std::cout << ' '; fo_ = false; return *this;}
|
PICout & space();
|
||||||
|
|
||||||
/*! \brief Conditional put quote character to output
|
/*! \brief Conditional put quote character to output
|
||||||
* \details If control \a AddQuotes is set
|
* \details If control \a AddQuotes is set
|
||||||
* quote character is put \sa \a space(), \a newLine() */
|
* quote character is put \sa \a space(), \a newLine() */
|
||||||
inline PICout & quote() {if (co_[AddQuotes]) std::cout << '"'; fo_ = false; return *this;}
|
PICout & quote();
|
||||||
|
|
||||||
/*! \brief Conditional put new line character to output
|
/*! \brief Conditional put new line character to output
|
||||||
* \details If control \a AddNewLine is set
|
* \details If control \a AddNewLine is set
|
||||||
* new line character is put \sa \a space(), \a quote() */
|
* new line character is put \sa \a space(), \a quote() */
|
||||||
inline PICout & newLine() {if (co_[AddNewLine]) std::cout << std::endl; fo_ = false; return *this;}
|
PICout & newLine();
|
||||||
|
|
||||||
|
static bool setBufferActive(bool on, bool clear = false);
|
||||||
|
static bool isBufferActive();
|
||||||
|
static PIString buffer(bool clear = false);
|
||||||
|
static void clearBuffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void applyFormat(PICoutFormat f);
|
void applyFormat(PICoutFormat f);
|
||||||
|
|
||||||
|
static bool buffer_;
|
||||||
bool fo_, cc_, fc_;
|
bool fo_, cc_, fc_;
|
||||||
int cnb_, attr_;
|
int cnb_, attr_;
|
||||||
PICoutControls co_;
|
PICoutControls co_;
|
||||||
|
|||||||
11
piiodevice.h
11
piiodevice.h
@@ -127,6 +127,9 @@ public:
|
|||||||
//! Return content of threaded read buffer
|
//! Return content of threaded read buffer
|
||||||
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
const uchar * threadedReadBuffer() const {return buffer_tr.data();}
|
||||||
|
|
||||||
|
//! Return custom data that will be passed to "threaded read slot"
|
||||||
|
void * threadedReadData() const {return ret_data_;}
|
||||||
|
|
||||||
|
|
||||||
//! Return \b true if threaded read is started
|
//! Return \b true if threaded read is started
|
||||||
bool isThreadedRead() const {return isRunning();}
|
bool isThreadedRead() const {return isRunning();}
|
||||||
@@ -189,6 +192,9 @@ public:
|
|||||||
bool configure(const PIString & config_file, const PIString & section, bool parent_section = false);
|
bool configure(const PIString & config_file, const PIString & section, bool parent_section = false);
|
||||||
|
|
||||||
|
|
||||||
|
//! Reimplement to construct full unambiguous string, describes this device, default returns \a path()
|
||||||
|
virtual PIString constructFullPath() const {return path();}
|
||||||
|
|
||||||
//! \brief Try to determine suitable device, create new one, configure it with \a configureFromFullPath() and returns it.
|
//! \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() + "://".
|
//! \details To function \a configureFromFullPath() "full_path" passed without \a fullPathPrefix() + "://".
|
||||||
//! See \ref PIIODevice_sec7
|
//! See \ref PIIODevice_sec7
|
||||||
@@ -197,7 +203,7 @@ public:
|
|||||||
|
|
||||||
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
EVENT_HANDLER1(bool, open, const DeviceMode &, _type) {mode_ = _type; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
EVENT_HANDLER1(bool, open, const DeviceMode &, _mode) {mode_ = _mode; 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_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _mode) {setPath(_path); mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
|
||||||
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
|
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
|
||||||
EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;}
|
EVENT_HANDLER(bool, initialize) {init_ = init(); return init_;}
|
||||||
@@ -289,9 +295,6 @@ protected:
|
|||||||
//! Reimplement to construct full unambiguous string prefix. \ref PIIODevice_sec7
|
//! Reimplement to construct full unambiguous string prefix. \ref PIIODevice_sec7
|
||||||
virtual PIString fullPathPrefix() const {return PIString();}
|
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
|
//! Reimplement to configure your device with parameters of full unambiguous string. Default implementation does nothing
|
||||||
virtual void configureFromFullPath(const PIString & full_path) {;}
|
virtual void configureFromFullPath(const PIString & full_path) {;}
|
||||||
|
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ void PIKbdListener::run() {
|
|||||||
case 40: ret = 1; lc = (ctrl ? CtrlDownArrow : DownArrow); break;
|
case 40: ret = 1; lc = (ctrl ? CtrlDownArrow : DownArrow); break;
|
||||||
default: ret = 1; lc = (shift ? char(toupper(ker.uChar.AsciiChar)) : ker.uChar.AsciiChar); break;
|
default: ret = 1; lc = (shift ? char(toupper(ker.uChar.AsciiChar)) : ker.uChar.AsciiChar); break;
|
||||||
}
|
}
|
||||||
if (lc == 0) return;
|
if (lc == 0) {piMSleep(10); return;}
|
||||||
} else return;
|
} else {piMSleep(10); return;}
|
||||||
} else return;
|
} else {piMSleep(10); return;}
|
||||||
/*if (lc == 0) {
|
/*if (lc == 0) {
|
||||||
ReadConsole(hIn, &rc, 1, &ret, 0);
|
ReadConsole(hIn, &rc, 1, &ret, 0);
|
||||||
//cout << "read console" << endl;
|
//cout << "read console" << endl;
|
||||||
@@ -105,7 +105,7 @@ void PIKbdListener::run() {
|
|||||||
cout << endl << std::hex << rc << endl;*/
|
cout << endl << std::hex << rc << endl;*/
|
||||||
#else
|
#else
|
||||||
ret = read(0, &rc, 4);
|
ret = read(0, &rc, 4);
|
||||||
if (ret < 0 || ret > 3) return;
|
if (ret < 0 || ret > 3) {piMSleep(10); return;}
|
||||||
lc = char(((uchar * )&rc)[ret - 1]);
|
lc = char(((uchar * )&rc)[ret - 1]);
|
||||||
//for (int i = 0; i < ret; ++i)
|
//for (int i = 0; i < ret; ++i)
|
||||||
// cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
// cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
||||||
|
|||||||
103
pimap.h
103
pimap.h
@@ -26,9 +26,10 @@
|
|||||||
#define PIMAP_H
|
#define PIMAP_H
|
||||||
|
|
||||||
#include "pivector.h"
|
#include "pivector.h"
|
||||||
|
#include "pideque.h"
|
||||||
|
|
||||||
|
|
||||||
#if 0 // !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
|
#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void piQuickSort(T * a, ssize_t N) {
|
void piQuickSort(T * a, ssize_t N) {
|
||||||
@@ -54,7 +55,7 @@ template <typename Key, typename T>
|
|||||||
class PIMap {
|
class PIMap {
|
||||||
public:
|
public:
|
||||||
PIMap() {;}
|
PIMap() {;}
|
||||||
PIMap(const PIMap<Key, T> & other) {;}
|
PIMap(const PIMap<Key, T> & other) {*this = other;}
|
||||||
~PIMap() {;}
|
~PIMap() {;}
|
||||||
|
|
||||||
PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
|
PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
|
||||||
@@ -69,6 +70,42 @@ public:
|
|||||||
typedef Key key_type;
|
typedef Key key_type;
|
||||||
typedef PIPair<Key, T> value_type;
|
typedef PIPair<Key, T> value_type;
|
||||||
|
|
||||||
|
class iterator {
|
||||||
|
friend class PIMap<Key, T>;
|
||||||
|
private:
|
||||||
|
iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||||
|
const PIMap<Key, T> * parent;
|
||||||
|
ssize_t pos;
|
||||||
|
public:
|
||||||
|
iterator(): parent(0) {}
|
||||||
|
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
||||||
|
T & value() const {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
||||||
|
void operator ++() {++pos;}
|
||||||
|
void operator ++(int) {++pos;}
|
||||||
|
void operator --() {--pos;}
|
||||||
|
void operator --(int) {--pos;}
|
||||||
|
bool operator ==(const iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class reverse_iterator {
|
||||||
|
friend class PIMap<Key, T>;
|
||||||
|
private:
|
||||||
|
reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||||
|
const PIMap<Key, T> * parent;
|
||||||
|
ssize_t pos;
|
||||||
|
public:
|
||||||
|
reverse_iterator(): parent(0) {}
|
||||||
|
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
||||||
|
T & value() const {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
||||||
|
void operator ++() {--pos;}
|
||||||
|
void operator ++(int) {--pos;}
|
||||||
|
void operator --() {++pos;}
|
||||||
|
void operator --(int) {++pos;}
|
||||||
|
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
class const_iterator {
|
class const_iterator {
|
||||||
friend class PIMap<Key, T>;
|
friend class PIMap<Key, T>;
|
||||||
private:
|
private:
|
||||||
@@ -78,12 +115,14 @@ public:
|
|||||||
public:
|
public:
|
||||||
const_iterator(): parent(0) {}
|
const_iterator(): parent(0) {}
|
||||||
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
||||||
|
const PIMap<Key, T>::value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
|
||||||
void operator ++() {++pos;}
|
void operator ++() {++pos;}
|
||||||
void operator ++(int) {++pos;}
|
void operator ++(int) {++pos;}
|
||||||
void operator --() {--pos;}
|
void operator --() {--pos;}
|
||||||
void operator --(int) {--pos;}
|
void operator --(int) {--pos;}
|
||||||
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
||||||
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
||||||
|
mutable value_type cval;
|
||||||
};
|
};
|
||||||
|
|
||||||
class const_reverse_iterator {
|
class const_reverse_iterator {
|
||||||
@@ -95,20 +134,22 @@ public:
|
|||||||
public:
|
public:
|
||||||
const_reverse_iterator(): parent(0) {}
|
const_reverse_iterator(): parent(0) {}
|
||||||
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
||||||
|
const PIMap<Key, T>::value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
|
||||||
void operator ++() {--pos;}
|
void operator ++() {--pos;}
|
||||||
void operator ++(int) {--pos;}
|
void operator ++(int) {--pos;}
|
||||||
void operator --() {++pos;}
|
void operator --() {++pos;}
|
||||||
void operator --(int) {++pos;}
|
void operator --(int) {++pos;}
|
||||||
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
||||||
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
||||||
|
mutable value_type cval;
|
||||||
};
|
};
|
||||||
|
|
||||||
// iterator begin() {return iterator(this, 0);}
|
iterator begin() {return iterator(this, 0);}
|
||||||
// iterator end() {return iterator(this, size());}
|
iterator end() {return iterator(this, size());}
|
||||||
const_iterator begin() const {return const_iterator(this, 0);}
|
const_iterator begin() const {return const_iterator(this, 0);}
|
||||||
const_iterator end() const {return const_iterator(this, size());}
|
const_iterator end() const {return const_iterator(this, size());}
|
||||||
// reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
|
reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
|
||||||
// reverse_iterator rend() {return reverse_iterator(this, -1);}
|
reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||||
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
|
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
|
||||||
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||||
|
|
||||||
@@ -126,6 +167,20 @@ public:
|
|||||||
return pim_content.back();
|
return pim_content.back();
|
||||||
}
|
}
|
||||||
const T operator [](const Key & key) const {bool f(false); ssize_t i = _find(key, f); if (f) return pim_content[pim_index[i].index]; return T();}
|
const T operator [](const Key & key) const {bool f(false); ssize_t i = _find(key, f); if (f) return pim_content[pim_index[i].index]; return T();}
|
||||||
|
T & at(const Key & key) {return (*this)[key];}
|
||||||
|
const T at(const Key & key) const {return (*this)[key];}
|
||||||
|
|
||||||
|
PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
|
||||||
|
if (other.isEmpty()) return *this;
|
||||||
|
if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
|
||||||
|
if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
|
||||||
|
pim_content << other.pim_content;
|
||||||
|
size_t si = pim_index.size();
|
||||||
|
for (int i = 0; i < other.pim_content.size_s(); ++i)
|
||||||
|
pim_index << MapIndex(other.pim_index[i].key, other.pim_index[i].index + si);
|
||||||
|
_sort();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
|
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
|
||||||
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
|
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
|
||||||
@@ -136,6 +191,8 @@ public:
|
|||||||
|
|
||||||
//PIMap<Key, T> & removeAll(const T & v) {for (llong i = 0; i < pim_size; ++i) if (pim_data[i] == v) {remove(i); --i;} return *this;}
|
//PIMap<Key, T> & removeAll(const T & v) {for (llong i = 0; i < pim_size; ++i) if (pim_data[i] == v) {remove(i); --i;} return *this;}
|
||||||
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
|
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
|
||||||
|
PIMap<Key, T> & remove(const Key & key) {return removeOne(key);}
|
||||||
|
PIMap<Key, T> & erase(const Key & key) {return removeOne(key);}
|
||||||
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
|
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
|
||||||
|
|
||||||
void swap(PIMap<Key, T> & other) {
|
void swap(PIMap<Key, T> & other) {
|
||||||
@@ -159,6 +216,13 @@ public:
|
|||||||
}
|
}
|
||||||
//const T value(const Key & key, const T & default_ = T()) const {MapIndex * i = _find(key); if (i == 0) return default_; return pim_content[i->index];}
|
//const T value(const Key & key, const T & default_ = T()) const {MapIndex * i = _find(key); if (i == 0) return default_; return pim_content[i->index];}
|
||||||
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
|
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
|
||||||
|
Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;}
|
||||||
|
PIVector<Key> keys() const {
|
||||||
|
PIVector<Key> ret;
|
||||||
|
for (int i = 0; i < pim_index.size_s(); ++i)
|
||||||
|
ret << pim_index[i].key;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void dump() {
|
void dump() {
|
||||||
piCout << "PIMap" << size() << "entries" << NewLine << "content:";
|
piCout << "PIMap" << size() << "entries" << NewLine << "content:";
|
||||||
@@ -174,8 +238,10 @@ private:
|
|||||||
MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
|
MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
|
||||||
Key key;
|
Key key;
|
||||||
size_t index;
|
size_t index;
|
||||||
//bool operator <(const MapIndex & s) const {return key < s.key;}
|
bool operator ==(const MapIndex & s) const {return key == s.key;}
|
||||||
//bool operator >(const MapIndex & s) const {return key > s.key;}
|
bool operator !=(const MapIndex & s) const {return key != s.key;}
|
||||||
|
bool operator <(const MapIndex & s) const {return key < s.key;}
|
||||||
|
bool operator >(const MapIndex & s) const {return key > s.key;}
|
||||||
};
|
};
|
||||||
|
|
||||||
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
||||||
@@ -184,10 +250,7 @@ private:
|
|||||||
mid = (first + last) / 2;
|
mid = (first + last) / 2;
|
||||||
if (key > pim_index[mid].key) first = mid + 1;
|
if (key > pim_index[mid].key) first = mid + 1;
|
||||||
else if (key < pim_index[mid].key) last = mid - 1;
|
else if (key < pim_index[mid].key) last = mid - 1;
|
||||||
else {
|
else {found = true; return mid;}
|
||||||
found = true;
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
found = false;
|
found = false;
|
||||||
return first;
|
return first;
|
||||||
@@ -225,16 +288,18 @@ private:
|
|||||||
//piCout << "_pair" << index << pim_index[index].index;
|
//piCout << "_pair" << index << pim_index[index].index;
|
||||||
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
|
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
|
||||||
}
|
}
|
||||||
|
Key & _key(ssize_t index) {return pim_index[index].key;}
|
||||||
|
T & _value(ssize_t index) {return pim_content[pim_index[index].index];}
|
||||||
|
|
||||||
PIVector<T> pim_content;
|
PIVector<T> pim_content;
|
||||||
PIVector<MapIndex> pim_index;
|
PIDeque<MapIndex> pim_index;
|
||||||
};
|
};
|
||||||
//template <typename Key, typename T> bool operator <(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key < s.key;}
|
//template <typename Key, typename T> bool operator <(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key < s.key;}
|
||||||
//template <typename Key, typename T> bool operator >(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key > s.key;}
|
//template <typename Key, typename T> bool operator >(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key > s.key;}
|
||||||
|
|
||||||
|
|
||||||
#define __PIMAP_SIMPLE_FUNCTIONS__(T)
|
/*#define __PIMAP_SIMPLE_FUNCTIONS__(T)
|
||||||
/* template<> inline PIMap<Key, T>::~PIMap() {dealloc(); _reset();} \
|
template<> inline PIMap<Key, T>::~PIMap() {dealloc(); _reset();} \
|
||||||
template<> inline PIMap<Key, T> & PIMap<Key, T>::push_back(const T & v) {alloc(pim_size + 1); pim_data[pim_size - 1] = v; return *this;} \
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::push_back(const T & v) {alloc(pim_size + 1); pim_data[pim_size - 1] = v; return *this;} \
|
||||||
template<> inline PIMap<Key, T> & PIMap<Key, T>::fill(const T & f) { \
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::fill(const T & f) { \
|
||||||
for (size_t i = 0; i < pim_size; ++i) \
|
for (size_t i = 0; i < pim_size; ++i) \
|
||||||
@@ -269,7 +334,7 @@ private:
|
|||||||
memmove(&(pim_data[index]), &(pim_data[index + count]), os * sizeof(T)); \
|
memmove(&(pim_data[index]), &(pim_data[index + count]), os * sizeof(T)); \
|
||||||
pim_size -= count; \
|
pim_size -= count; \
|
||||||
return *this; \
|
return *this; \
|
||||||
}*/
|
}
|
||||||
|
|
||||||
__PIMAP_SIMPLE_FUNCTIONS__(char)
|
__PIMAP_SIMPLE_FUNCTIONS__(char)
|
||||||
__PIMAP_SIMPLE_FUNCTIONS__(uchar)
|
__PIMAP_SIMPLE_FUNCTIONS__(uchar)
|
||||||
@@ -283,7 +348,7 @@ __PIMAP_SIMPLE_FUNCTIONS__(llong)
|
|||||||
__PIMAP_SIMPLE_FUNCTIONS__(ullong)
|
__PIMAP_SIMPLE_FUNCTIONS__(ullong)
|
||||||
__PIMAP_SIMPLE_FUNCTIONS__(float)
|
__PIMAP_SIMPLE_FUNCTIONS__(float)
|
||||||
__PIMAP_SIMPLE_FUNCTIONS__(double)
|
__PIMAP_SIMPLE_FUNCTIONS__(double)
|
||||||
__PIMAP_SIMPLE_FUNCTIONS__(ldouble)
|
__PIMAP_SIMPLE_FUNCTIONS__(ldouble)*/
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -301,7 +366,7 @@ public:
|
|||||||
int size_s() const {return static_cast<int>(_stlc::size());}
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
||||||
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
Key key(Type value_, const Key & default_ = Key()) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return default_;}
|
||||||
PIVector<Key> keys() const {
|
PIVector<Key> keys() const {
|
||||||
PIVector<Key> ret;
|
PIVector<Key> ret;
|
||||||
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
||||||
@@ -325,7 +390,7 @@ public:
|
|||||||
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
||||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
Key key(Type value_, const Key & default_ = Key()) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return default_;}
|
||||||
PIVector<Key> keys(Type value_) const {
|
PIVector<Key> keys(Type value_) const {
|
||||||
PIVector<Key> ret;
|
PIVector<Key> ret;
|
||||||
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
||||||
|
|||||||
32
pimath.h
32
pimath.h
@@ -23,7 +23,7 @@
|
|||||||
#ifndef PIMATH_H
|
#ifndef PIMATH_H
|
||||||
#define PIMATH_H
|
#define PIMATH_H
|
||||||
|
|
||||||
#include "picontainers.h"
|
#include "pibytearray.h"
|
||||||
#ifndef QNX
|
#ifndef QNX
|
||||||
# include <complex>
|
# include <complex>
|
||||||
# include <cmath>
|
# include <cmath>
|
||||||
@@ -94,10 +94,10 @@ const complexd complexd_i(0., 1.);
|
|||||||
const complexd complexd_0(0.);
|
const complexd complexd_0(0.);
|
||||||
const complexd complexd_1(1.);
|
const complexd complexd_1(1.);
|
||||||
|
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(complexi)
|
__PICONTAINERS_SIMPLE_TYPE__(complexi)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(complexf)
|
__PICONTAINERS_SIMPLE_TYPE__(complexf)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(complexd)
|
__PICONTAINERS_SIMPLE_TYPE__(complexd)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(complexld)
|
__PICONTAINERS_SIMPLE_TYPE__(complexld)
|
||||||
|
|
||||||
const double deg2rad = M_PI_180;
|
const double deg2rad = M_PI_180;
|
||||||
const double rad2deg = M_180_PI;
|
const double rad2deg = M_180_PI;
|
||||||
@@ -165,6 +165,7 @@ class PIMathMatrixT;
|
|||||||
|
|
||||||
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
|
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
template<uint Size, typename Type = double>
|
template<uint Size, typename Type = double>
|
||||||
class PIP_EXPORT PIMathVectorT {
|
class PIP_EXPORT PIMathVectorT {
|
||||||
typedef PIMathVectorT<Size, Type> _CVector;
|
typedef PIMathVectorT<Size, Type> _CVector;
|
||||||
@@ -190,7 +191,7 @@ public:
|
|||||||
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
||||||
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
||||||
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
||||||
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs<Type>(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
||||||
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
||||||
bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
|
bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
|
||||||
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
|
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
|
||||||
@@ -199,7 +200,7 @@ public:
|
|||||||
Type at(uint index) const {return c[index];}
|
Type at(uint index) const {return c[index];}
|
||||||
Type & operator [](uint index) {return c[index];}
|
Type & operator [](uint index) {return c[index];}
|
||||||
Type operator [](uint index) const {return c[index];}
|
Type operator [](uint index) const {return c[index];}
|
||||||
_CVector & operator =(const _CVector & v) {memcpy(&c, &(v.c), sizeof(Type) * Size); return *this;}
|
_CVector & operator =(const _CVector & v) {memcpy(c, v.c, sizeof(Type) * Size); return *this;}
|
||||||
bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;}
|
bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;}
|
||||||
bool operator !=(const _CVector & v) const {return !(*this == c);}
|
bool operator !=(const _CVector & v) const {return !(*this == c);}
|
||||||
void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
|
void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
|
||||||
@@ -233,6 +234,7 @@ private:
|
|||||||
Type c[Size];
|
Type c[Size];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
template<uint Size, typename Type>
|
template<uint Size, typename Type>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
|
||||||
@@ -245,6 +247,11 @@ inline PIMathVectorT<Size, Type> sqrt(const PIMathVectorT<Size, Type> & v) {PIMa
|
|||||||
template<uint Size, typename Type>
|
template<uint Size, typename Type>
|
||||||
inline PIMathVectorT<Size, Type> sqr(const PIMathVectorT<Size, Type> & v) {PIMathVectorT<Size, Type> ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;}
|
inline PIMathVectorT<Size, Type> sqr(const PIMathVectorT<Size, Type> & v) {PIMathVectorT<Size, Type> ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;}
|
||||||
|
|
||||||
|
template<uint Size, typename Type>
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT<Size, Type> & v) {for (int i = 0; i < Size; ++i) s << v[i]; return s;}
|
||||||
|
template<uint Size, typename Type>
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT<Size, Type> & v) {for (int i = 0; i < Size; ++i) s >> v[i]; return s;}
|
||||||
|
|
||||||
//template<uint Size0, typename Type0 = double, uint Size1 = Size0, typename Type1 = Type0> /// vector {Size0, Type0} to vector {Size1, Type1}
|
//template<uint Size0, typename Type0 = double, uint Size1 = Size0, typename Type1 = Type0> /// vector {Size0, Type0} to vector {Size1, Type1}
|
||||||
//inline operator PIMathVectorT<Size1, Type1>(const PIMathVectorT<Size0, Type0> & v) {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;}
|
//inline operator PIMathVectorT<Size1, Type1>(const PIMathVectorT<Size0, Type0> & v) {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;}
|
||||||
|
|
||||||
@@ -264,6 +271,7 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d;
|
|||||||
#define PIMM_FOR_C(v) for (uint v = 0; v < Cols; ++v)
|
#define PIMM_FOR_C(v) for (uint v = 0; v < Cols; ++v)
|
||||||
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
|
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
template<uint Cols, uint Rows = Cols, typename Type = double>
|
template<uint Cols, uint Rows = Cols, typename Type = double>
|
||||||
class PIP_EXPORT PIMathMatrixT {
|
class PIP_EXPORT PIMathMatrixT {
|
||||||
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
|
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
|
||||||
@@ -299,7 +307,8 @@ public:
|
|||||||
Type & at(uint col, uint row) {return m[col][row];}
|
Type & at(uint col, uint row) {return m[col][row];}
|
||||||
Type at(uint col, uint row) const {return m[col][row];}
|
Type at(uint col, uint row) const {return m[col][row];}
|
||||||
Type * operator [](uint col) {return m[col];}
|
Type * operator [](uint col) {return m[col];}
|
||||||
void operator =(const _CMatrix & sm) {memcpy(&m, &(sm.m), sizeof(Type) * Cols * Rows);}
|
const Type * operator [](uint col) const {return m[col];}
|
||||||
|
void operator =(const _CMatrix & sm) {memcpy(m, sm.m, sizeof(Type) * Cols * Rows);}
|
||||||
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;}
|
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;}
|
||||||
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
|
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
|
||||||
void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];}
|
void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];}
|
||||||
@@ -350,7 +359,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ok != 0) *ok = true;
|
if (ok != 0) *ok = true;
|
||||||
m = smat.m;
|
memcpy(m, smat.m, sizeof(Type) * Cols * Rows);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +416,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ok != 0) *ok = true;
|
if (ok != 0) *ok = true;
|
||||||
m = mtmp.m;
|
memcpy(m, mtmp.m, sizeof(Type) * Cols * Rows);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
_CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;}
|
_CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;}
|
||||||
@@ -419,6 +428,7 @@ private:
|
|||||||
Type m[Cols][Rows];
|
Type m[Cols][Rows];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
template<> inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::rotation(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<2u, 2u> tm; tm[0][0] = tm[1][1] = c; tm[0][1] = -s; tm[1][0] = s; return tm;}
|
template<> inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::rotation(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<2u, 2u> tm; tm[0][0] = tm[1][1] = c; tm[0][1] = -s; tm[1][0] = s; return tm;}
|
||||||
@@ -512,7 +522,7 @@ public:
|
|||||||
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
|
||||||
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));}
|
||||||
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
_CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
|
||||||
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs<Type>(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;}
|
||||||
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
||||||
bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
|
bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
|
||||||
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
|
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ handler A: event to event
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
PIObject::PIObject(const PIString & name) {
|
PIObject::PIObject(const PIString & name): emitter_(0) {
|
||||||
piMonitor.objects++;
|
piMonitor.objects++;
|
||||||
setName(name);
|
setName(name);
|
||||||
setDebug(true);
|
setDebug(true);
|
||||||
|
|||||||
33
piobject.h
33
piobject.h
@@ -26,6 +26,7 @@
|
|||||||
#define PIOBJECT_H
|
#define PIOBJECT_H
|
||||||
|
|
||||||
#include "pivariant.h"
|
#include "pivariant.h"
|
||||||
|
#include "pimutex.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
@@ -258,7 +259,7 @@ public:
|
|||||||
PIVariant property(const PIString & name) const {if (!properties_.contains(name)) return PIVariant(); return properties_.value(name);}
|
PIVariant property(const PIString & name) const {if (!properties_.contains(name)) return PIVariant(); return properties_.value(name);}
|
||||||
|
|
||||||
//! Set property with name "name" to "value". If there is no such property in object it will be added
|
//! Set property with name "name" to "value". If there is no such property in object it will be added
|
||||||
void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value;}
|
void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value; propertyChanged(name);}
|
||||||
|
|
||||||
//! Returns if property with name "name" exists
|
//! Returns if property with name "name" exists
|
||||||
bool isPropertyExists(const PIString & name) const {return properties_.contains(name);}
|
bool isPropertyExists(const PIString & name) const {return properties_.contains(name);}
|
||||||
@@ -373,7 +374,11 @@ public:
|
|||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
if (i.event != event) continue;
|
if (i.event != event) continue;
|
||||||
|
((PIObject*)(i.dest))->mutex_.lock();
|
||||||
|
((PIObject*)(i.dest))->emitter_ = sender;
|
||||||
((void(*)(void * ))i.slot)(i.dest);
|
((void(*)(void * ))i.slot)(i.dest);
|
||||||
|
((PIObject*)(i.dest))->emitter_ = 0;
|
||||||
|
((PIObject*)(i.dest))->mutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename T0>
|
template <typename T0>
|
||||||
@@ -381,7 +386,11 @@ public:
|
|||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
if (i.event != event) continue;
|
if (i.event != event) continue;
|
||||||
|
((PIObject*)(i.dest))->mutex_.lock();
|
||||||
|
((PIObject*)(i.dest))->emitter_ = sender;
|
||||||
((void(*)(void * , T0))i.slot)(i.dest, v0);
|
((void(*)(void * , T0))i.slot)(i.dest, v0);
|
||||||
|
((PIObject*)(i.dest))->emitter_ = 0;
|
||||||
|
((PIObject*)(i.dest))->mutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
@@ -389,7 +398,11 @@ public:
|
|||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
if (i.event != event) continue;
|
if (i.event != event) continue;
|
||||||
|
((PIObject*)(i.dest))->mutex_.lock();
|
||||||
|
((PIObject*)(i.dest))->emitter_ = sender;
|
||||||
((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1);
|
((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1);
|
||||||
|
((PIObject*)(i.dest))->emitter_ = 0;
|
||||||
|
((PIObject*)(i.dest))->mutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
@@ -397,7 +410,11 @@ public:
|
|||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
if (i.event != event) continue;
|
if (i.event != event) continue;
|
||||||
|
((PIObject*)(i.dest))->mutex_.lock();
|
||||||
|
((PIObject*)(i.dest))->emitter_ = sender;
|
||||||
((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2);
|
((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2);
|
||||||
|
((PIObject*)(i.dest))->emitter_ = 0;
|
||||||
|
((PIObject*)(i.dest))->mutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename T0, typename T1, typename T2, typename T3>
|
template <typename T0, typename T1, typename T2, typename T3>
|
||||||
@@ -405,7 +422,11 @@ public:
|
|||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
Connection & i(sender->connections[j]);
|
Connection & i(sender->connections[j]);
|
||||||
if (i.event != event) continue;
|
if (i.event != event) continue;
|
||||||
|
((PIObject*)(i.dest))->mutex_.lock();
|
||||||
|
((PIObject*)(i.dest))->emitter_ = sender;
|
||||||
((void(*)(void * , T0, T1, T2, T3))i.slot)(i.dest, v0, v1, v2, v3);
|
((void(*)(void * , T0, T1, T2, T3))i.slot)(i.dest, v0, v1, v2, v3);
|
||||||
|
((PIObject*)(i.dest))->emitter_ = 0;
|
||||||
|
((PIObject*)(i.dest))->mutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -476,7 +497,7 @@ public:
|
|||||||
raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3);
|
raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns PIObject* with name "name" or 0, if there is no objects found
|
//! Returns PIObject* with name "name" or 0, if there is no object found
|
||||||
static PIObject * findByName(const PIString & name) {
|
static PIObject * findByName(const PIString & name) {
|
||||||
piForeach (PIObject * i, PIObject::objects) {
|
piForeach (PIObject * i, PIObject::objects) {
|
||||||
if (i->name() != name) continue;
|
if (i->name() != name) continue;
|
||||||
@@ -487,6 +508,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//! Returns PIObject* which has raised an event. This value is correct only in definition of some event handler
|
||||||
|
PIObject * emitter() const {return emitter_;}
|
||||||
|
|
||||||
|
//! Virtual function executes after property with name "name" has been changed
|
||||||
|
virtual void propertyChanged(const PIString & name) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Connection {
|
struct Connection {
|
||||||
Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), void * o = 0) {slot = sl; signal = si; event = e; dest = o;}
|
Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), void * o = 0) {slot = sl; signal = si; event = e; dest = o;}
|
||||||
@@ -500,6 +527,8 @@ private:
|
|||||||
PIMap<PIString, PIVariant> properties_;
|
PIMap<PIString, PIVariant> properties_;
|
||||||
|
|
||||||
static PIVector<PIObject * > objects;
|
static PIVector<PIObject * > objects;
|
||||||
|
PIMutex mutex_;
|
||||||
|
PIObject * emitter_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
8
pip.pro
8
pip.pro
@@ -52,7 +52,9 @@ HEADERS += \
|
|||||||
pidiagnostics.h \
|
pidiagnostics.h \
|
||||||
pibinarylog.h \
|
pibinarylog.h \
|
||||||
picodeparser.h \
|
picodeparser.h \
|
||||||
piusb.h
|
picodeinfo.h \
|
||||||
|
piusb.h \
|
||||||
|
piconnection.h
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
pivariant.cpp \
|
pivariant.cpp \
|
||||||
pitimer.cpp \
|
pitimer.cpp \
|
||||||
@@ -85,7 +87,9 @@ SOURCES += main.cpp \
|
|||||||
pidiagnostics.cpp \
|
pidiagnostics.cpp \
|
||||||
pibinarylog.cpp \
|
pibinarylog.cpp \
|
||||||
picodeparser.cpp \
|
picodeparser.cpp \
|
||||||
piusb.cpp
|
picodeinfo.cpp \
|
||||||
|
piusb.cpp \
|
||||||
|
piconnection.cpp
|
||||||
win32 {
|
win32 {
|
||||||
LIBS += -lws2_32 -lIphlpapi
|
LIBS += -lws2_32 -lIphlpapi
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ VS_VERSION_INFO VERSIONINFO
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Peri4\0"
|
VALUE "CompanyName", "Peri4\0"
|
||||||
VALUE "FileDescription", "Platform-Independent Primitives\0"
|
VALUE "FileDescription", "Platform-Independent Primitives\0"
|
||||||
VALUE "FileVersion", "0.4.0_prealpha\0"
|
VALUE "FileVersion", "0.4.0_beta2\0"
|
||||||
VALUE "LegalCopyright", "\0"
|
VALUE "LegalCopyright", "\0"
|
||||||
VALUE "OriginalFilename", "libpip.dll\0"
|
VALUE "OriginalFilename", "libpip.dll\0"
|
||||||
VALUE "ProductName", "PIP\0"
|
VALUE "ProductName", "PIP\0"
|
||||||
|
|||||||
@@ -60,13 +60,34 @@
|
|||||||
REGISTER_DEVICE(PIPacketExtractor);
|
REGISTER_DEVICE(PIPacketExtractor);
|
||||||
|
|
||||||
|
|
||||||
PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, void * recHeaderPtr, int recHeaderSize, int recDataSize) {
|
PIPacketExtractor::PIPacketExtractor(PIIODevice * device_, PIPacketExtractor::SplitMode mode) {
|
||||||
ret_func_header = 0;
|
init_();
|
||||||
setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
setDevice(device_);
|
||||||
|
setSplitMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIPacketExtractor::init_() {
|
||||||
|
ret_func_header = ret_func_footer = 0;
|
||||||
|
setPayloadSize(0);
|
||||||
|
setTimeout(100);
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
setBufferSize(65536);
|
setBufferSize(65536);
|
||||||
setDevice(device_);
|
setDevice(0);
|
||||||
allReaded = addSize = curInd = missed = 0;
|
setPacketSize(0);
|
||||||
|
setSplitMode(None);
|
||||||
|
allReaded = addSize = curInd = missed = footerInd = 0;
|
||||||
|
header_found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIPacketExtractor::propertyChanged(const PIString &) {
|
||||||
|
packetSize_ = property("packetSize").toInt();
|
||||||
|
mode_ = (SplitMode)(property("splitMode").toInt());
|
||||||
|
dataSize = property("payloadSize").toInt();
|
||||||
|
src_header = property("header").toByteArray();
|
||||||
|
src_footer = property("footer").toByteArray();
|
||||||
|
packetSize_hf = src_header.size_s() + src_footer.size_s() + payloadSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -76,55 +97,181 @@ void PIPacketExtractor::setDevice(PIIODevice * device_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIPacketExtractor::setPayloadSize(int size) {
|
||||||
|
setProperty("payloadSize", size);
|
||||||
|
dataSize = size;
|
||||||
|
packetSize_hf = src_header.size_s() + src_footer.size_s() + payloadSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIPacketExtractor::setHeader(const PIByteArray & data) {
|
||||||
|
setProperty("header", data);
|
||||||
|
src_header = data;
|
||||||
|
packetSize_hf = src_header.size_s() + src_footer.size_s() + payloadSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIPacketExtractor::setFooter(const PIByteArray & data) {
|
||||||
|
setProperty("footer", data);
|
||||||
|
src_footer = data;
|
||||||
|
packetSize_hf = src_header.size_s() + src_footer.size_s() + payloadSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
|
bool PIPacketExtractor::threadedRead(uchar * readed, int size_) {
|
||||||
memcpy(buffer.data(allReaded), readed, size_);
|
//piCout << "readed" << size_;
|
||||||
|
int ss;
|
||||||
|
switch (mode_) {
|
||||||
|
case PIPacketExtractor::None:
|
||||||
|
packetReceived(readed, size_);
|
||||||
|
break;
|
||||||
|
case PIPacketExtractor::Header:
|
||||||
|
tmpbuf.append(readed, size_);
|
||||||
|
ss = src_header.size_s() + dataSize;
|
||||||
|
while (tmpbuf.size_s() >= ss) {
|
||||||
|
while (!validateHeader(src_header.data(), tmpbuf.data(), src_header.size_s())) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
|
}
|
||||||
|
while (!validatePayload(tmpbuf.data(src_header.size_s()), dataSize)) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
|
}
|
||||||
|
packetReceived(tmpbuf.data(), ss);
|
||||||
|
tmpbuf.remove(0, ss);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIPacketExtractor::Footer:
|
||||||
|
/*memcpy(buffer.data(allReaded), readed, size_);
|
||||||
allReaded += size_;
|
allReaded += size_;
|
||||||
while (allReaded >= packetSize + addSize && allReaded > 0) {
|
footer_ = (mode_ == PIPacketExtractor::Footer);
|
||||||
if (headerSize > 0) {
|
while (allReaded >= packetSize_hf + addSize && allReaded > 0) {
|
||||||
|
if (!src_header.isEmpty()) {
|
||||||
if (allReaded + curInd >= buffer_size) {
|
if (allReaded + curInd >= buffer_size) {
|
||||||
memcpy(sbuffer.data(), buffer.data(), buffer_size);
|
memcpy(sbuffer.data(), buffer.data(), buffer_size);
|
||||||
memcpy(buffer.data(), sbuffer.data(buffer_size - packetSize), allReaded);
|
memcpy(buffer.data(), sbuffer.data(buffer_size - packetSize_hf), allReaded);
|
||||||
allReaded = packetSize;
|
allReaded = packetSize_hf;
|
||||||
addSize = curInd = 0;
|
addSize = curInd = 0;
|
||||||
}
|
}
|
||||||
bool brk = false;
|
bool brk = false;
|
||||||
while (!packetHeaderValidate((uchar * )headerPtr, buffer.data(curInd), headerSize)) {
|
while (!validateHeader((uchar * )(footer_ ? src_footer.data() : src_header.data()), buffer.data(curInd + (footer_ ? dataSize : 0)), footer_ ? src_footer.size_s() : src_header.size_s())) {
|
||||||
curInd++; missed++;
|
++curInd; ++missed;
|
||||||
if (packetSize > 0) missed_packets = missed / packetSize;
|
if (packetSize_hf > 0) missed_packets = missed / packetSize_hf;
|
||||||
if (curInd > addSize) {
|
if (curInd > addSize) {
|
||||||
addSize += packetSize;
|
addSize += packetSize_hf;
|
||||||
brk = true;
|
brk = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (brk) continue;
|
if (brk) continue;
|
||||||
memcpy(mheader.data(), buffer.data(curInd), headerSize);
|
//memcpy(mheader.data(), buffer.data(curInd + (footer_ ? dataSize : 0)), src_header.size_s());
|
||||||
if (headerPtr != 0) memcpy(headerPtr, buffer.data(curInd), headerSize);
|
if (!src_header.isEmpty()) memcpy(src_header.data(), buffer.data(curInd), src_header.size_s());
|
||||||
if (!packetValidate(buffer.data(curInd + headerSize), dataSize)) {
|
if (!validatePayload(buffer.data(curInd + src_header.size_s()), dataSize)) {
|
||||||
curInd++; missed++;
|
++curInd; ++missed;
|
||||||
if (packetSize > 0) missed_packets = missed / packetSize;
|
if (packetSize_hf > 0) missed_packets = missed / packetSize_hf;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
packetReceived(buffer.data(curInd), packetSize);
|
packetReceived(buffer.data(curInd), packetSize_hf);
|
||||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||||
memcpy(buffer.data(), sbuffer.data(packetSize + curInd), allReaded);
|
memcpy(buffer.data(), sbuffer.data(packetSize_hf + curInd), allReaded);
|
||||||
allReaded -= packetSize + curInd;
|
allReaded -= packetSize_hf + curInd;
|
||||||
curInd = addSize = 0;
|
curInd = addSize = 0;
|
||||||
} else {
|
} else {
|
||||||
if (dataSize == 0) {
|
if (dataSize == 0) {
|
||||||
if (packetValidate(buffer.data(), size_))
|
if (validatePayload(buffer.data(), size_))
|
||||||
packetReceived(buffer.data(), size_);
|
packetReceived(buffer.data(), size_);
|
||||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||||
memcpy(buffer.data(), sbuffer.data(size_), allReaded);
|
memcpy(buffer.data(), sbuffer.data(size_), allReaded);
|
||||||
allReaded -= size_;
|
allReaded -= size_;
|
||||||
} else {
|
} else {
|
||||||
if (packetValidate(buffer.data(), dataSize))
|
if (validatePayload(buffer.data(), dataSize))
|
||||||
packetReceived(buffer.data(), dataSize);
|
packetReceived(buffer.data(), dataSize);
|
||||||
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
memcpy(sbuffer.data(), buffer.data(), allReaded);
|
||||||
memcpy(buffer.data(), sbuffer.data(packetSize), allReaded);
|
memcpy(buffer.data(), sbuffer.data(packetSize_hf), allReaded);
|
||||||
allReaded -= packetSize;
|
allReaded -= packetSize_hf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
tmpbuf.append(readed, size_);
|
||||||
|
ss = src_footer.size_s() + dataSize;
|
||||||
|
while (tmpbuf.size_s() >= ss) {
|
||||||
|
while (!validateFooter(src_footer.data(), tmpbuf.data(dataSize), src_footer.size_s())) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
}
|
}
|
||||||
|
while (!validatePayload(tmpbuf.data(), dataSize)) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
|
}
|
||||||
|
packetReceived(tmpbuf.data(), ss);
|
||||||
|
tmpbuf.remove(0, ss);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIPacketExtractor::HeaderAndFooter:
|
||||||
|
tmpbuf.append(readed, size_);
|
||||||
|
ss = src_header.size_s() + src_footer.size_s();
|
||||||
|
while (tmpbuf.size_s() >= ss) {
|
||||||
|
if (!header_found) {
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
|
while (!validateHeader(src_header.data(), tmpbuf.data(), src_header.size_s())) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
if (tmpbuf.size_s() < ss) return true;
|
||||||
|
}
|
||||||
|
header_found = true;
|
||||||
|
footerInd = src_header.size_s();
|
||||||
|
} else {
|
||||||
|
if (tmpbuf.size_s() < footerInd + src_footer.size_s()) return true;
|
||||||
|
while (!validateFooter(src_footer.data(), tmpbuf.data(footerInd), src_footer.size_s())) {
|
||||||
|
++footerInd;
|
||||||
|
if (tmpbuf.size_s() < footerInd + src_footer.size_s()) return true;
|
||||||
|
}
|
||||||
|
//piCout << "footer found at" << footerInd;
|
||||||
|
header_found = false;
|
||||||
|
if (!validatePayload(tmpbuf.data(src_header.size_s()), footerInd - src_header.size_s())) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
packetReceived(tmpbuf.data(), footerInd + src_footer.size_s());
|
||||||
|
tmpbuf.remove(0, footerInd + src_footer.size_s());
|
||||||
|
footerInd = src_header.size_s();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIPacketExtractor::Timeout:
|
||||||
|
memcpy(buffer.data(), readed, size_);
|
||||||
|
trbuf = dev->readForTime(time_);
|
||||||
|
memcpy(buffer.data(size_), trbuf.data(), trbuf.size());
|
||||||
|
if (size_ + trbuf.size() > 0)
|
||||||
|
packetReceived(buffer.data(), size_ + trbuf.size());
|
||||||
|
break;
|
||||||
|
case PIPacketExtractor::Size:
|
||||||
|
tmpbuf.append(readed, size_);
|
||||||
|
if (packetSize_ <= 0) {
|
||||||
|
tmpbuf.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
while (tmpbuf.size_s() >= packetSize_) {
|
||||||
|
if (!validatePayload(tmpbuf.data(), packetSize_)) {
|
||||||
|
tmpbuf.pop_front();
|
||||||
|
++missed;
|
||||||
|
missed_packets = missed / packetSize_;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
packetReceived(tmpbuf.data(), packetSize_);
|
||||||
|
tmpbuf.remove(0, packetSize_);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIPacketExtractor::constructFullPath() const {
|
||||||
|
return fullPathPrefix() + "://";
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,15 +27,25 @@
|
|||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
|
|
||||||
// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false.
|
// Pass data, recHeaderPtr, received_data, recHeaderSize. Return true if packet is correct nor return false.
|
||||||
typedef bool (*HeaderCheckFunc)(void * , uchar * , uchar * , int );
|
typedef bool (*PacketExtractorCheckFunc)(void * , uchar * , uchar * , int );
|
||||||
|
|
||||||
class PIP_EXPORT PIPacketExtractor: public PIIODevice
|
class PIP_EXPORT PIPacketExtractor: public PIIODevice
|
||||||
{
|
{
|
||||||
PIIODEVICE(PIPacketExtractor)
|
PIIODEVICE(PIPacketExtractor)
|
||||||
|
friend class PIConnection;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum SplitMode {
|
||||||
|
None,
|
||||||
|
Header,
|
||||||
|
Footer,
|
||||||
|
HeaderAndFooter,
|
||||||
|
Size,
|
||||||
|
Timeout
|
||||||
|
};
|
||||||
|
|
||||||
//! Contructs extractor with child device "device_", header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize"
|
//! Contructs extractor with child device "device_", header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize"
|
||||||
PIPacketExtractor(PIIODevice * device_ = 0, void * recHeaderPtr = 0, int recHeaderSize = 0, int recDataSize = 0);
|
PIPacketExtractor(PIIODevice * device_ = 0, SplitMode mode = None);
|
||||||
|
|
||||||
virtual ~PIPacketExtractor() {stop();}
|
virtual ~PIPacketExtractor() {stop();}
|
||||||
|
|
||||||
@@ -53,17 +63,30 @@ public:
|
|||||||
//! Set buffer size to "new_size" bytes, should be at least greater than whole packet size
|
//! Set buffer size to "new_size" bytes, should be at least greater than whole packet size
|
||||||
void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size); memset(buffer.data(), 0, buffer.size()); memset(sbuffer.data(), 0, sbuffer.size());}
|
void setBufferSize(int new_size) {buffer_size = new_size; buffer.resize(buffer_size); sbuffer.resize(buffer_size); memset(buffer.data(), 0, buffer.size()); memset(sbuffer.data(), 0, sbuffer.size());}
|
||||||
|
|
||||||
void setHeaderCheckSlot(HeaderCheckFunc f) {ret_func_header = f;}
|
void setHeaderCheckSlot(PacketExtractorCheckFunc f) {ret_func_header = f;}
|
||||||
|
void setFooterCheckSlot(PacketExtractorCheckFunc f) {ret_func_footer = f;}
|
||||||
|
void setPayloadCheckSlot(ReadRetFunc f) {ret_func_ = f;}
|
||||||
|
|
||||||
//! Set header content pointer "recHeaderPtr", header size "recHeaderSize" and payload size "recDataSize"
|
void setSplitMode(SplitMode mode) {setProperty("splitMode", int(mode)); mode_ = mode;}
|
||||||
void setPacketData(void * recHeaderPtr, int recHeaderSize, int recDataSize) {headerPtr = recHeaderPtr; headerSize = recHeaderSize; dataSize = recDataSize; packetSize = headerSize + dataSize; if (headerSize > 0) mheader.resize(headerSize);}
|
void setPayloadSize(int size);
|
||||||
|
void setHeader(const PIByteArray & data);
|
||||||
|
void setFooter(const PIByteArray & data);
|
||||||
|
void setTimeout(double msecs) {setProperty("timeout", msecs); time_ = msecs;}
|
||||||
|
void setPacketSize(int size) {setProperty("packetSize", size); packetSize_ = size;}
|
||||||
|
|
||||||
|
SplitMode splitMode() const {return (SplitMode)(property("splitMode").toInt());}
|
||||||
|
int payloadSize() const {return property("payloadSize").toInt();}
|
||||||
|
PIByteArray header() const {return src_header;}
|
||||||
|
PIByteArray footer() const {return src_footer;}
|
||||||
|
double timeout() const {return property("timeout").toDouble();}
|
||||||
|
int packetSize() const {return property("packetSize").toInt();}
|
||||||
|
|
||||||
|
|
||||||
//! Returns missed by validating functions bytes count
|
//! Returns missed by validating functions bytes count
|
||||||
ullong missedBytes() const {return missed;}
|
ullong missedBytes() const {return missed;}
|
||||||
|
|
||||||
//! Returns missed by validating functions packets count, = missedBytes() / packetSize
|
//! Returns missed by validating functions packets count, = missedBytes() / packetSize
|
||||||
ullong missedPackets() const {if (packetSize == 0) return missed; return missed / packetSize;}
|
ullong missedPackets() const {/*if (packetSize_hf == 0) return missed; return missed / packetSize_hf*/; return missed_packets;}
|
||||||
|
|
||||||
//! Returns pointer to \a missedBytes() count. Useful for output to PIConsole
|
//! Returns pointer to \a missedBytes() count. Useful for output to PIConsole
|
||||||
const ullong * missedBytes_ptr() const {return &missed;}
|
const ullong * missedBytes_ptr() const {return &missed;}
|
||||||
@@ -82,6 +105,8 @@ public:
|
|||||||
//! Directly call \a write() function of child %device
|
//! Directly call \a write() function of child %device
|
||||||
int write(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
|
int write(const void * data, int max_size) {if (dev == 0) return -1; return dev->write(data, max_size);}
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
EVENT2(packetReceived, uchar * , data, int, size)
|
EVENT2(packetReceived, uchar * , data, int, size)
|
||||||
|
|
||||||
//! \events
|
//! \events
|
||||||
@@ -95,25 +120,40 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** \brief Function to validate header
|
/** \brief Function to validate header
|
||||||
* \param src Your header content passed from constructor or with function \a setPacketData()
|
* \param src Your header content
|
||||||
* \param rec Received header
|
* \param rec Received header
|
||||||
* \param size Header size
|
* \param size Header size
|
||||||
* \details Default implementation returns by-byte "src" with "rec" compare result */
|
* \details Default implementation returns by-byte "src" with "rec" compare result */
|
||||||
virtual bool packetHeaderValidate(uchar * src, uchar * rec, int size) {if (ret_func_header != 0) return ret_func_header(ret_data_, src, rec, size); for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
virtual bool validateHeader(uchar * src, uchar * rec, int size) {if (ret_func_header != 0) return ret_func_header(ret_data_, src, rec, size); for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
||||||
|
|
||||||
//! Function to validate packet paylod after successfully header validate. Default implementation returns \b true
|
/** \brief Function to validate footer
|
||||||
virtual bool packetValidate(uchar * rec, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, rec, size); return true;}
|
* \param src Your footer content
|
||||||
|
* \param rec Received footer
|
||||||
|
* \param size Footer size
|
||||||
|
* \details Default implementation returns by-byte "src" with "rec" compare result */
|
||||||
|
virtual bool validateFooter(uchar * src, uchar * rec, int size) {if (ret_func_footer != 0) return ret_func_footer(ret_data_, src, rec, size); for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;}
|
||||||
|
|
||||||
|
/** \brief Function to validate payload
|
||||||
|
* \param rec Received payload
|
||||||
|
* \param size payload size
|
||||||
|
* \details Default implementation returns \b true */
|
||||||
|
virtual bool validatePayload(uchar * rec, int size) {if (ret_func_ != 0) return ret_func_(ret_data_, rec, size); return true;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init_();
|
||||||
|
void propertyChanged(const PIString & );
|
||||||
bool threadedRead(uchar * readed, int size);
|
bool threadedRead(uchar * readed, int size);
|
||||||
PIString fullPathPrefix() const {return "pckext";}
|
PIString fullPathPrefix() const {return "pckext";}
|
||||||
bool openDevice() {if (dev == 0) return false; return dev->open();}
|
bool openDevice() {if (dev == 0) return false; return dev->open();}
|
||||||
|
|
||||||
PIIODevice * dev;
|
PIIODevice * dev;
|
||||||
PIByteArray mheader, buffer, sbuffer;
|
PIByteArray mheader, buffer, sbuffer, tmpbuf, src_header, src_footer, trbuf;
|
||||||
HeaderCheckFunc ret_func_header;
|
PacketExtractorCheckFunc ret_func_header, ret_func_footer;
|
||||||
void * headerPtr, * data;
|
SplitMode mode_;
|
||||||
int buffer_size, dataSize, headerSize, packetSize, allReaded, addSize, curInd;
|
void * data;
|
||||||
|
int buffer_size, dataSize, packetSize_hf, allReaded, addSize, curInd, footerInd, packetSize_;
|
||||||
|
double time_;
|
||||||
|
bool header_found;
|
||||||
ullong missed, missed_packets;
|
ullong missed, missed_packets;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name_, void * r
|
|||||||
dataSize = recDataSize;
|
dataSize = recDataSize;
|
||||||
sendDataPtr = (uchar * )sendDataPtr_;
|
sendDataPtr = (uchar * )sendDataPtr_;
|
||||||
sendDataSize = sendDataSize_;
|
sendDataSize = sendDataSize_;
|
||||||
packet_ext->setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
|
packet_ext->setHeader(PIByteArray(recHeaderPtr, recHeaderSize));
|
||||||
|
packet_ext->setPayloadSize(recDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ PIProtocol::~PIProtocol() {
|
|||||||
|
|
||||||
|
|
||||||
void PIProtocol::init() {
|
void PIProtocol::init() {
|
||||||
packet_ext = new PIPacketExtractor();
|
packet_ext = new PIPacketExtractor(0, PIPacketExtractor::Header);
|
||||||
packet_ext->setThreadedReadData(this);
|
packet_ext->setThreadedReadData(this);
|
||||||
packet_ext->setThreadedReadSlot(receiveEvent);
|
packet_ext->setThreadedReadSlot(receiveEvent);
|
||||||
packet_ext->setHeaderCheckSlot(headerValidateEvent);
|
packet_ext->setHeaderCheckSlot(headerValidateEvent);
|
||||||
@@ -94,6 +95,7 @@ void PIProtocol::init() {
|
|||||||
mp_owner = 0;
|
mp_owner = 0;
|
||||||
net_diag = PIProtocol::Unknown;
|
net_diag = PIProtocol::Unknown;
|
||||||
cur_pckt = 0;
|
cur_pckt = 0;
|
||||||
|
packets[0] = packets[1] = pckt_cnt = pckt_cnt_max = 0;
|
||||||
diagTimer = 0;
|
diagTimer = 0;
|
||||||
timeout_ = 3.f;
|
timeout_ = 3.f;
|
||||||
sendTimer = new PITimer(sendEvent, this);
|
sendTimer = new PITimer(sendEvent, this);
|
||||||
@@ -259,11 +261,11 @@ void PIProtocol::init_sender(PIConfig::Entry & b, PIConfig::Entry & sb, const PI
|
|||||||
}
|
}
|
||||||
if (history_write_send) {
|
if (history_write_send) {
|
||||||
history_path_send = sb.getValue("historyFile", "./history_" + protName + "_send_" +
|
history_path_send = sb.getValue("historyFile", "./history_" + protName + "_send_" +
|
||||||
date2string(currentDate(), "__dd_mm_yyyy_") +
|
PIDate::current().toString("__dd_mm_yyyy_") +
|
||||||
time2string(currentTime(), "_hh_mm_ss_")).value();
|
PITime::current().toString("_hh_mm_ss_")).value();
|
||||||
history_id_send = sb.getValue("historyID", 0, &ok);
|
history_id_send = sb.getValue("historyID", 0, &ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
history_id_send = protName.toByteArray().checksumCRC16() + 1;
|
history_id_send = ushort(protName.toByteArray().checksumPlain32()) + 1;
|
||||||
piCoutObj << "Warning: no sender history ID defined, write with ID = " << history_id_send;
|
piCoutObj << "Warning: no sender history ID defined, write with ID = " << history_id_send;
|
||||||
}
|
}
|
||||||
history_file_send.open(history_path_send, PIIODevice::WriteOnly);
|
history_file_send.open(history_path_send, PIIODevice::WriteOnly);
|
||||||
@@ -432,11 +434,11 @@ void PIProtocol::init_receiver(PIConfig::Entry & b, PIConfig::Entry & rb, const
|
|||||||
}
|
}
|
||||||
if (history_write_rec) {
|
if (history_write_rec) {
|
||||||
history_path_rec = rb.getValue("historyFile", "./history_" + protName + "_rec_" +
|
history_path_rec = rb.getValue("historyFile", "./history_" + protName + "_rec_" +
|
||||||
date2string(currentDate(), "__dd_mm_yyyy_") +
|
PIDate::current().toString("__dd_mm_yyyy_") +
|
||||||
time2string(currentTime(), "_hh_mm_ss_")).value();
|
PITime::current().toString("_hh_mm_ss_")).value();
|
||||||
history_id_rec = rb.getValue("historyID", 0, &ok);
|
history_id_rec = rb.getValue("historyID", 0, &ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
history_id_rec = protName.toByteArray().checksumCRC16();
|
history_id_rec = ushort(protName.toByteArray().checksumPlain32());
|
||||||
piCoutObj << "Warning: no receiver history ID defined, write with ID = " << history_id_rec;
|
piCoutObj << "Warning: no receiver history ID defined, write with ID = " << history_id_rec;
|
||||||
}
|
}
|
||||||
history_file_rec.open(history_path_rec, PIIODevice::WriteOnly);
|
history_file_rec.open(history_path_rec, PIIODevice::WriteOnly);
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ public:
|
|||||||
EVENT_HANDLER0(void, stopReceive);
|
EVENT_HANDLER0(void, stopReceive);
|
||||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
|
||||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize);}
|
||||||
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
|
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setHeader(PIByteArray(headerPtr, headerSize)); packet_ext->setPayloadSize(dataSize);}
|
||||||
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
|
||||||
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||||
|
|||||||
22
piserial.cpp
22
piserial.cpp
@@ -344,7 +344,7 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
|||||||
|
|
||||||
|
|
||||||
bool PISerial::openDevice() {
|
bool PISerial::openDevice() {
|
||||||
piCout << "ser open" << path();
|
//piCout << "ser open" << path();
|
||||||
if (path().isEmpty()) return false;
|
if (path().isEmpty()) return false;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
DWORD ds = 0, sm = 0;
|
DWORD ds = 0, sm = 0;
|
||||||
@@ -519,6 +519,19 @@ bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PISerial::constructFullPath() const {
|
||||||
|
PIString ret(fullPathPrefix() + "://");
|
||||||
|
ret << path() << ":" << int(inSpeed()) << ":" << dataBitsCount();
|
||||||
|
if (parameters()[ParityControl]) {
|
||||||
|
if (parameters()[ParityOdd]) ret << ":O";
|
||||||
|
else ret << ":E";
|
||||||
|
} else ret << ":N";
|
||||||
|
if (parameters()[TwoStopBits]) ret << ":2";
|
||||||
|
else ret << ":1";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PISerial::configureFromFullPath(const PIString & full_path) {
|
void PISerial::configureFromFullPath(const PIString & full_path) {
|
||||||
PIStringList pl = full_path.split(":");
|
PIStringList pl = full_path.split(":");
|
||||||
for (int i = 0; i < pl.size_s(); ++i) {
|
for (int i = 0; i < pl.size_s(); ++i) {
|
||||||
@@ -553,9 +566,10 @@ PIStringList PISerial::availableDevices(bool test) {
|
|||||||
HKEY key = 0;
|
HKEY key = 0;
|
||||||
RegOpenKey(HKEY_LOCAL_MACHINE, (LPCTSTR)"HARDWARE\\DEVICEMAP\\SERIALCOMM", &key);
|
RegOpenKey(HKEY_LOCAL_MACHINE, (LPCTSTR)"HARDWARE\\DEVICEMAP\\SERIALCOMM", &key);
|
||||||
if (key != 0) {
|
if (key != 0) {
|
||||||
char name[256], data[1024];
|
char name[1024], data[1024];
|
||||||
DWORD name_len = 256, data_len = 1024, type = 0, index = 0;
|
DWORD name_len = 1024, data_len = 1024, type = 0, index = 0;
|
||||||
while (RegEnumValue(key, index, (LPTSTR)name, &name_len, NULL, &type, (uchar * )data, &data_len) == ERROR_SUCCESS) {
|
LONG ret;
|
||||||
|
while ((ret = RegEnumValue(key, index, (LPTSTR)name, &name_len, NULL, &type, (uchar * )data, &data_len)) != ERROR_NO_MORE_ITEMS) {
|
||||||
dl << PIString(data);
|
dl << PIString(data);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,6 +242,8 @@ public:
|
|||||||
//! \returns \b true if sended bytes count = size of string
|
//! \returns \b true if sended bytes count = size of string
|
||||||
bool send(const PIByteArray & data, bool wait = false) {return (write(data.data(), data.size_s(), wait) == data.size_s());}
|
bool send(const PIByteArray & data, bool wait = false) {return (write(data.data(), data.size_s(), wait) == data.size_s());}
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
|
|
||||||
//! \brief Returns all available speeds for serial devices
|
//! \brief Returns all available speeds for serial devices
|
||||||
static PIVector<int> availableSpeeds();
|
static PIVector<int> availableSpeeds();
|
||||||
|
|||||||
34
pistring.cpp
34
pistring.cpp
@@ -155,8 +155,8 @@ PIString & PIString::operator +=(const wstring & str) {
|
|||||||
|
|
||||||
|
|
||||||
PIString & PIString::operator +=(const PIString & str) {
|
PIString & PIString::operator +=(const PIString & str) {
|
||||||
uint l = str.size();
|
//uint l = str.size();
|
||||||
for (uint i = 0; i < l; ++i) push_back(str[i]);
|
*((PIDeque<PIChar>*)this) << *((PIDeque<PIChar>*)&str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,23 +208,25 @@ bool PIString::operator >(const PIString & str) const {
|
|||||||
|
|
||||||
|
|
||||||
PIString PIString::mid(const int start, const int len) const {
|
PIString PIString::mid(const int start, const int len) const {
|
||||||
PIString str;
|
//PIString str;
|
||||||
int s = start, l = len;
|
int s = start, l = len;
|
||||||
if (l == 0) return str;
|
if (l == 0) return PIString();
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
l += s;
|
l += s;
|
||||||
s = 0;
|
s = 0;
|
||||||
}
|
}
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
for (uint i = s; i < size(); ++i)
|
//for (uint i = s; i < size(); ++i)
|
||||||
str += at(i);
|
// str += at(i);
|
||||||
|
return PIString(&(at(s)), size() - s);
|
||||||
} else {
|
} else {
|
||||||
if (l > length() - s)
|
if (l > length() - s)
|
||||||
l = length() - s;
|
l = length() - s;
|
||||||
for (int i = s; i < s + l; ++i)
|
//for (int i = s; i < s + l; ++i)
|
||||||
str += at(i);
|
// str += at(i);
|
||||||
|
return PIString(&(at(s)), l);
|
||||||
}
|
}
|
||||||
return str;
|
return PIString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -254,7 +256,9 @@ PIString & PIString::trim() {
|
|||||||
for (int i = length() - 1; i >= 0; --i)
|
for (int i = length() - 1; i >= 0; --i)
|
||||||
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
if (at(i) != ' ' && at(i) != '\t' && at(i) != '\n' && at(i) != '\r' && at(i) != char(12))
|
||||||
{fn = i; break;}
|
{fn = i; break;}
|
||||||
*this = mid(st, fn - st + 1);
|
//*this = mid(st, fn - st + 1);
|
||||||
|
if (fn < size_s() - 1) cutRight(size_s() - fn - 1);
|
||||||
|
if (st > 0) cutLeft(st);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +285,7 @@ PIString & PIString::replace(int from, int count, const PIString & with) {
|
|||||||
|
|
||||||
|
|
||||||
PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) {
|
PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) {
|
||||||
|
//piCout << "replace" << what << with;
|
||||||
if (what.isEmpty()) {
|
if (what.isEmpty()) {
|
||||||
if (ok != 0) *ok = false;
|
if (ok != 0) *ok = false;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -301,8 +306,9 @@ PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
|
|||||||
|
|
||||||
|
|
||||||
PIString & PIString::insert(int index, const PIString & str) {
|
PIString & PIString::insert(int index, const PIString & str) {
|
||||||
uint c = str.length();
|
//uint c = str.length();
|
||||||
for (uint i = 0; i < c; ++i) insert(index + i, str[i]);
|
//for (uint i = 0; i < c; ++i) insert(index + i, str[i]);
|
||||||
|
PIDeque<PIChar>::insert(index, *((const PIDeque<PIChar>*)&str));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,10 +746,10 @@ PIStringList& PIStringList::removeDuplicates() {
|
|||||||
PIStringList l;
|
PIStringList l;
|
||||||
PIString s;
|
PIString s;
|
||||||
bool ae;
|
bool ae;
|
||||||
for (uint i = 0; i < size(); ++i) {
|
for (int i = 0; i < size_s(); ++i) {
|
||||||
ae = false;
|
ae = false;
|
||||||
s = at(i);
|
s = at(i);
|
||||||
for (uint j = 0; j < l.size(); ++j) {
|
for (int j = 0; j < l.size_s(); ++j) {
|
||||||
if (s != l[j]) continue;
|
if (s != l[j]) continue;
|
||||||
ae = true; break;
|
ae = true; break;
|
||||||
}
|
}
|
||||||
|
|||||||
88
pistring.h
88
pistring.h
@@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
class PIStringList;
|
class PIStringList;
|
||||||
|
|
||||||
class PIP_EXPORT PIString: public PIVector<PIChar>
|
class PIP_EXPORT PIString: public PIDeque<PIChar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Contructs an empty string
|
//! Contructs an empty string
|
||||||
PIString(): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--;}
|
PIString(): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--;}
|
||||||
|
|
||||||
//inline PIString & operator +=(const char c) {push_back(c); return *this;}
|
//inline PIString & operator +=(const char c) {push_back(c); return *this;}
|
||||||
PIString & operator +=(const PIChar & c) {push_back(c); return *this;}
|
PIString & operator +=(const PIChar & c) {push_back(c); return *this;}
|
||||||
@@ -49,56 +49,59 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//PIString(const char c) {*this += c;}
|
//PIString(const char c) {*this += c;}
|
||||||
PIString(const PIString & o): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += o;}
|
PIString(const PIString & o): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += o;}
|
||||||
|
|
||||||
|
|
||||||
//! Contructs string with single symbol "c"
|
//! Contructs string with single symbol "c"
|
||||||
PIString(const PIChar & c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += c;}
|
PIString(const PIChar & c): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += c;}
|
||||||
PIString(const char c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += PIChar(c);}
|
PIString(const char c): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += PIChar(c);}
|
||||||
|
|
||||||
/*! \brief Contructs string from c-string "str"
|
/*! \brief Contructs string from c-string "str"
|
||||||
* \details "str" should be null-terminated\n
|
* \details "str" should be null-terminated\n
|
||||||
* Example: \snippet pistring.cpp PIString(char * ) */
|
* Example: \snippet pistring.cpp PIString(char * ) */
|
||||||
PIString(const char * str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const char * str): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
/*! \brief Contructs string from \c wchar_t c-string "str"
|
/*! \brief Contructs string from \c wchar_t c-string "str"
|
||||||
* \details "str" should be null-terminated\n
|
* \details "str" should be null-terminated\n
|
||||||
* Example: \snippet pistring.cpp PIString(wchar_t * ) */
|
* Example: \snippet pistring.cpp PIString(wchar_t * ) */
|
||||||
PIString(const wchar_t * str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const wchar_t * str): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
//! Contructs string from std::string "str"
|
//! Contructs string from std::string "str"
|
||||||
PIString(const string & str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const string & str): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
|
|
||||||
#ifdef HAS_LOCALE
|
#ifdef HAS_LOCALE
|
||||||
PIString(const wstring & str): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
PIString(const wstring & str): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += str;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Contructs string from byte array "ba"
|
//! Contructs string from byte array "ba"
|
||||||
PIString(const PIByteArray & ba): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += ba;}
|
PIString(const PIByteArray & ba): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += ba;}
|
||||||
|
|
||||||
|
//! \brief Contructs string from "len" characters of buffer "str"
|
||||||
|
PIString(const PIChar * str, const int len): PIDeque<PIChar>(str, size_t(len)) {/*reserve(256); */piMonitor.strings++; piMonitor.containers--;}
|
||||||
|
|
||||||
/*! \brief Contructs string from "len" characters of buffer "str"
|
/*! \brief Contructs string from "len" characters of buffer "str"
|
||||||
* \details Example: \snippet pistring.cpp PIString(char * , int) */
|
* \details Example: \snippet pistring.cpp PIString(char * , int) */
|
||||||
PIString(const char * str, const int len): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
|
PIString(const char * str, const int len): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this += string(str, len);}
|
||||||
|
|
||||||
/*! \brief Contructs string as sequence of characters "c" of buffer with length "len"
|
/*! \brief Contructs string as sequence of characters "c" of buffer with length "len"
|
||||||
* \details Example: \snippet pistring.cpp PIString(int, char) */
|
* \details Example: \snippet pistring.cpp PIString(int, char) */
|
||||||
PIString(const int len, const char c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
PIString(const int len, const char c): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||||
|
|
||||||
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
|
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
|
||||||
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */
|
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */
|
||||||
PIString(const int len, const PIChar & c): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
PIString(const int len, const PIChar & c): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||||
|
|
||||||
|
|
||||||
PIString(const short & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const short & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const ushort & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const ushort & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const int & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const int & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const uint & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const uint & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const long & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const long & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const ulong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const ulong & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const llong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const llong & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const ullong & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const ullong & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const float & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const float & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
PIString(const double & value): PIVector<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
PIString(const double & value): PIDeque<PIChar>() {/*reserve(256); */piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
|
||||||
|
|
||||||
//~PIString() {piMonitor.strings--; piMonitor.containers++;}
|
//~PIString() {piMonitor.strings--; piMonitor.containers++;}
|
||||||
@@ -119,7 +122,7 @@ public:
|
|||||||
//! Return symbol at index "pos"
|
//! Return symbol at index "pos"
|
||||||
PIChar operator [](const int pos) const {return at(pos);}
|
PIChar operator [](const int pos) const {return at(pos);}
|
||||||
|
|
||||||
//! Return const reference symbol at index "pos"
|
//! Return reference to symbol at index "pos"
|
||||||
PIChar & operator [](const int pos) {return at(pos);}
|
PIChar & operator [](const int pos) {return at(pos);}
|
||||||
|
|
||||||
//! Compare operator
|
//! Compare operator
|
||||||
@@ -241,14 +244,20 @@ public:
|
|||||||
/*! \brief Append string representation of "num" at the end of string
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const uint & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
/*! \brief Append string representation of "num" at the end of string
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const ushort & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
/*! \brief Append string representation of "num" at the end of string
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const ulong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
PIString & operator <<(const llong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
PIString & operator <<(const ullong & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
/*! \brief Append string representation of "num" at the end of string
|
/*! \brief Append string representation of "num" at the end of string
|
||||||
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
* \details Example: \snippet pistring.cpp PIString::<<(int) */
|
||||||
@@ -259,6 +268,13 @@ public:
|
|||||||
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief Insert string "str" at the begin of string
|
||||||
|
PIString & prepend(const PIString & str) {insert(0, str); return *this;}
|
||||||
|
|
||||||
|
//! \brief Insert string "str" at the end of string
|
||||||
|
PIString & append(const PIString & str) {*this += str; return *this;}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Return part of string from symbol at index "start" and maximum length "len"
|
/*! \brief Return part of string from symbol at index "start" and maximum length "len"
|
||||||
* \details All variants demonstrated in example: \snippet pistring.cpp PIString::mid
|
* \details All variants demonstrated in example: \snippet pistring.cpp PIString::mid
|
||||||
* \sa \a left(), \a right() */
|
* \sa \a left(), \a right() */
|
||||||
@@ -330,9 +346,17 @@ public:
|
|||||||
PIString & replaceAll(const PIString & what, const PIString & with);
|
PIString & replaceAll(const PIString & what, const PIString & with);
|
||||||
PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;}
|
||||||
|
|
||||||
|
/*! \brief Repeat content of string "times" times and return this string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::repeat */
|
||||||
|
PIString & repeat(int times) {PIString ss(*this); times--; piForTimes (times) *this += ss; return *this;}
|
||||||
|
|
||||||
|
/*! \brief Returns repeated "times" times string
|
||||||
|
* \details Example: \snippet pistring.cpp PIString::repeated */
|
||||||
|
PIString repeated(int times) const {PIString ss(*this); return ss.repeat(times);}
|
||||||
|
|
||||||
/*! \brief Insert symbol "c" after index "index" and return this string
|
/*! \brief Insert symbol "c" after index "index" and return this string
|
||||||
* \details Example: \snippet pistring.cpp PIString::insert_0 */
|
* \details Example: \snippet pistring.cpp PIString::insert_0 */
|
||||||
PIString & insert(const int index, const PIChar & c) {PIVector<PIChar>::insert(index, c); return *this;}
|
PIString & insert(const int index, const PIChar & c) {PIDeque<PIChar>::insert(index, c); return *this;}
|
||||||
|
|
||||||
/*! \brief Insert symbol "c" after index "index" and return this string
|
/*! \brief Insert symbol "c" after index "index" and return this string
|
||||||
* \details Example: \snippet pistring.cpp PIString::insert_1 */
|
* \details Example: \snippet pistring.cpp PIString::insert_1 */
|
||||||
@@ -494,11 +518,11 @@ public:
|
|||||||
//! \details Example: \snippet pistring.cpp PIString::findLast
|
//! \details Example: \snippet pistring.cpp PIString::findLast
|
||||||
int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);}
|
int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);}
|
||||||
|
|
||||||
//! \brief Search word "word" from symbol at index "start" and return last occur position.
|
//! \brief Search word "word" from symbol at index "start" and return first occur position.
|
||||||
//! \details Example: \snippet pistring.cpp PIString::findWord
|
//! \details Example: \snippet pistring.cpp PIString::findWord
|
||||||
int findWord(const PIString & word, const int start = 0) const;
|
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.
|
//! \brief Search C-style word "word" from symbol at index "start" and return first occur position.
|
||||||
//! \details Example: \snippet pistring.cpp PIString::findCWord
|
//! \details Example: \snippet pistring.cpp PIString::findCWord
|
||||||
int findCWord(const PIString & word, const int start = 0) const;
|
int findCWord(const PIString & word, const int start = 0) const;
|
||||||
|
|
||||||
@@ -801,7 +825,7 @@ inline char chrLwr(char c);
|
|||||||
/*!\brief Strings array class
|
/*!\brief Strings array class
|
||||||
* \details This class is based on \a PIVector<PIString> and
|
* \details This class is based on \a PIVector<PIString> and
|
||||||
* expand it functionality. */
|
* expand it functionality. */
|
||||||
class PIP_EXPORT PIStringList: public PIVector<PIString>
|
class PIP_EXPORT PIStringList: public PIDeque<PIString>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -820,7 +844,7 @@ public:
|
|||||||
//! Contructs empty strings list with strings "s0", "s1", "s2" and "s3"
|
//! Contructs empty strings list with strings "s0", "s1", "s2" and "s3"
|
||||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
|
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);}
|
||||||
|
|
||||||
PIStringList(const PIStringList & o): PIVector<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
|
PIStringList(const PIStringList & o): PIDeque<PIString>() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];}
|
||||||
|
|
||||||
|
|
||||||
//! \brief Join all strings in one with delimiter "delim" and return it
|
//! \brief Join all strings in one with delimiter "delim" and return it
|
||||||
@@ -831,14 +855,14 @@ public:
|
|||||||
//! \details Example: \snippet pistring.cpp PIStringList::removeStrings
|
//! \details Example: \snippet pistring.cpp PIStringList::removeStrings
|
||||||
PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;}
|
PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;}
|
||||||
|
|
||||||
PIStringList & remove(uint num) {PIVector<PIString>::remove(num); return *this;}
|
PIStringList & remove(uint num) {PIDeque<PIString>::remove(num); return *this;}
|
||||||
PIStringList & remove(uint num, uint count) {PIVector<PIString>::remove(num, count); return *this;}
|
PIStringList & remove(uint num, uint count) {PIDeque<PIString>::remove(num, count); return *this;}
|
||||||
|
|
||||||
//! \brief Remove duplicated strings and return this
|
//! \brief Remove duplicated strings and return this
|
||||||
//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
|
//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
|
||||||
PIStringList & removeDuplicates();
|
PIStringList & removeDuplicates();
|
||||||
|
|
||||||
//! \brief
|
//! \brief Trim all strings
|
||||||
//! \details Example: \snippet pistring.cpp PIStringList::trim
|
//! \details Example: \snippet pistring.cpp PIStringList::trim
|
||||||
PIStringList & trim() {for (uint i = 0; i < size(); ++i) at(i).trim(); return *this;}
|
PIStringList & trim() {for (uint i = 0; i < size(); ++i) at(i).trim(); return *this;}
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ bool operator >(const PIDateTime & t0, const PIDateTime & t1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PITime currentTime() {
|
PITime PITime::current() {
|
||||||
time_t rt = time(0);
|
time_t rt = time(0);
|
||||||
tm * pt = localtime(&rt);
|
tm * pt = localtime(&rt);
|
||||||
PITime t;
|
PITime t;
|
||||||
@@ -125,7 +125,7 @@ PITime currentTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDate currentDate() {
|
PIDate PIDate::current() {
|
||||||
time_t rt = time(0);
|
time_t rt = time(0);
|
||||||
tm * pt = localtime(&rt);
|
tm * pt = localtime(&rt);
|
||||||
PIDate d;
|
PIDate d;
|
||||||
@@ -136,7 +136,7 @@ PIDate currentDate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIDateTime currentDateTime() {
|
PIDateTime PIDateTime::current() {
|
||||||
time_t rt = time(0);
|
time_t rt = time(0);
|
||||||
tm * pt = localtime(&rt);
|
tm * pt = localtime(&rt);
|
||||||
PIDateTime dt;
|
PIDateTime dt;
|
||||||
@@ -151,7 +151,7 @@ PIDateTime currentDateTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PISystemTime currentSystemTime() {
|
PISystemTime PISystemTime::current() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
FILETIME ft, sft;
|
FILETIME ft, sft;
|
||||||
GetSystemTimeAsFileTime(&ft);
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
|||||||
20
pitime.h
20
pitime.h
@@ -141,6 +141,9 @@ public:
|
|||||||
//! Contructs system time from nanoseconds "v"
|
//! Contructs system time from nanoseconds "v"
|
||||||
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
||||||
|
|
||||||
|
//! Returns current system time
|
||||||
|
static PISystemTime current();
|
||||||
|
|
||||||
|
|
||||||
//! Seconds of stored system time
|
//! Seconds of stored system time
|
||||||
long seconds;
|
long seconds;
|
||||||
@@ -169,6 +172,7 @@ struct PIP_EXPORT PITime {
|
|||||||
int minutes;
|
int minutes;
|
||||||
int hours;
|
int hours;
|
||||||
PIString toString(const PIString & format = "h:mm:ss") const;
|
PIString toString(const PIString & format = "h:mm:ss") const;
|
||||||
|
static PITime current();
|
||||||
};
|
};
|
||||||
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
||||||
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
||||||
@@ -183,6 +187,7 @@ struct PIP_EXPORT PIDate {
|
|||||||
int month;
|
int month;
|
||||||
int year;
|
int year;
|
||||||
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
||||||
|
static PIDate current();
|
||||||
};
|
};
|
||||||
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
||||||
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
||||||
@@ -212,6 +217,7 @@ struct PIP_EXPORT PIDateTime {
|
|||||||
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
||||||
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
||||||
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
||||||
|
static PIDateTime current();
|
||||||
};
|
};
|
||||||
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
||||||
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
||||||
@@ -222,14 +228,14 @@ inline bool operator !=(const PIDateTime & t0, const PIDateTime & t1) {return !(
|
|||||||
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
||||||
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
PIP_EXPORT PITime currentTime();
|
DEPRECATED inline PITime currentTime() {return PITime::current();} // obsolete, use PITime::current() instead
|
||||||
PIP_EXPORT PIDate currentDate();
|
DEPRECATED inline PIDate currentDate() {return PIDate::current();} // obsolete, use PIDate::current() instead
|
||||||
PIP_EXPORT PIDateTime currentDateTime();
|
DEPRECATED inline PIDateTime currentDateTime() {return PIDateTime::current();} // obsolete, use PIDateTime::current() instead
|
||||||
|
|
||||||
//! \relatesalso PISystemTime \brief Returns current system time
|
//! \relatesalso PISystemTime \brief Returns current system time
|
||||||
PIP_EXPORT PISystemTime currentSystemTime();
|
DEPRECATED inline PISystemTime currentSystemTime() {return PISystemTime::current();} // obsolete, use PISystemTime::current() instead
|
||||||
PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
DEPRECATED PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||||
PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
DEPRECATED PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
||||||
PIP_EXPORT PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
DEPRECATED PIP_EXPORT PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
||||||
|
|
||||||
#endif // PITIME_H
|
#endif // PITIME_H
|
||||||
|
|||||||
12
pitimer.cpp
12
pitimer.cpp
@@ -309,7 +309,7 @@ void PITimer::start(double msecs) {
|
|||||||
if (msecs < 0 || running_) return;
|
if (msecs < 0 || running_) return;
|
||||||
interval_ = msecs;
|
interval_ = msecs;
|
||||||
inc_time = PISystemTime::fromMilliseconds(msecs);
|
inc_time = PISystemTime::fromMilliseconds(msecs);
|
||||||
st_time = currentSystemTime() + inc_time;
|
st_time = PISystemTime::current() + inc_time;
|
||||||
deferred_ = false;
|
deferred_ = false;
|
||||||
running_ = true;
|
running_ = true;
|
||||||
PIThread::start();
|
PIThread::start();
|
||||||
@@ -320,9 +320,9 @@ void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
|||||||
//piCoutObj << "defStart exec with" << delay_msecs << interval_msecs;
|
//piCoutObj << "defStart exec with" << delay_msecs << interval_msecs;
|
||||||
if (interval_msecs < 0 || running_) return;
|
if (interval_msecs < 0 || running_) return;
|
||||||
interval_ = interval_msecs;
|
interval_ = interval_msecs;
|
||||||
PISystemTime cst = currentSystemTime();
|
PISystemTime cst = PISystemTime::current();
|
||||||
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
||||||
st_time = currentSystemTime() + PISystemTime::fromMilliseconds(delay_msecs);
|
st_time = PISystemTime::current() + PISystemTime::fromMilliseconds(delay_msecs);
|
||||||
if (st_time < cst) st_time = cst;
|
if (st_time < cst) st_time = cst;
|
||||||
running_ = deferred_ = true;
|
running_ = deferred_ = true;
|
||||||
PIThread::start();
|
PIThread::start();
|
||||||
@@ -334,7 +334,7 @@ void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_date
|
|||||||
//piCoutObj << "defStart exec to" << start_datetime.toString() << interval_msecs;
|
//piCoutObj << "defStart exec to" << start_datetime.toString() << interval_msecs;
|
||||||
if (interval_msecs < 0 || running_) return;
|
if (interval_msecs < 0 || running_) return;
|
||||||
interval_ = interval_msecs;
|
interval_ = interval_msecs;
|
||||||
PISystemTime cst = currentSystemTime();
|
PISystemTime cst = PISystemTime::current();
|
||||||
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
inc_time = PISystemTime::fromMilliseconds(interval_msecs);
|
||||||
st_time = start_datetime.toSystemTime();
|
st_time = start_datetime.toSystemTime();
|
||||||
if (st_time < cst) st_time = cst;
|
if (st_time < cst) st_time = cst;
|
||||||
@@ -347,7 +347,7 @@ void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_date
|
|||||||
void PITimer::run() {
|
void PITimer::run() {
|
||||||
if (!running_) return;
|
if (!running_) return;
|
||||||
while (deferred_) {
|
while (deferred_) {
|
||||||
PISystemTime tst = st_time - currentSystemTime();
|
PISystemTime tst = st_time - PISystemTime::current();
|
||||||
if (tst.seconds > 0) {
|
if (tst.seconds > 0) {
|
||||||
piMSleep(100);
|
piMSleep(100);
|
||||||
if (!running_) return;
|
if (!running_) return;
|
||||||
@@ -365,7 +365,7 @@ void PITimer::run() {
|
|||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
tt_st = __PIQueryPerformanceCounter();
|
tt_st = __PIQueryPerformanceCounter();
|
||||||
#else
|
#else
|
||||||
(st_time - currentSystemTime()).sleep();
|
(st_time - PISystemTime::current()).sleep();
|
||||||
st_time += inc_time;
|
st_time += inc_time;
|
||||||
#endif
|
#endif
|
||||||
//if (lockRun) lock();
|
//if (lockRun) lock();
|
||||||
|
|||||||
@@ -388,6 +388,13 @@ PICout operator<<(PICout s, const PIUSB::Endpoint & v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIUSB::constructFullPath() const {
|
||||||
|
PIString ret(fullPathPrefix() + "://");
|
||||||
|
ret << PIString::fromNumber(vendorID(), 16).toLowerCase() << ":" << PIString::fromNumber(productID(), 16).toLowerCase() << ":" << deviceNumber() << ":" << endpointRead().address << ":" << endpointWrite().address;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIUSB::configureFromFullPath(const PIString & full_path) {
|
void PIUSB::configureFromFullPath(const PIString & full_path) {
|
||||||
PIStringList pl = full_path.split(":");
|
PIStringList pl = full_path.split(":");
|
||||||
for (int i = 0; i < pl.size_s(); ++i) {
|
for (int i = 0; i < pl.size_s(); ++i) {
|
||||||
|
|||||||
6
piusb.h
6
piusb.h
@@ -100,8 +100,8 @@ public:
|
|||||||
int deviceNumber() const {return property("deviceNumber").toInt();}
|
int deviceNumber() const {return property("deviceNumber").toInt();}
|
||||||
int timeoutRead() const {return property("timeoutRead").toInt();}
|
int timeoutRead() const {return property("timeoutRead").toInt();}
|
||||||
int timeoutWrite() const {return property("timeoutWrite").toInt();}
|
int timeoutWrite() const {return property("timeoutWrite").toInt();}
|
||||||
const PIUSB::Endpoint & endpointRead() {return ep_read;}
|
const PIUSB::Endpoint & endpointRead() const {return ep_read;}
|
||||||
const PIUSB::Endpoint & endpointWrite() {return ep_write;}
|
const PIUSB::Endpoint & endpointWrite() const {return ep_write;}
|
||||||
|
|
||||||
const PIVector<PIUSB::Endpoint> & endpoints() const {return eps;}
|
const PIVector<PIUSB::Endpoint> & endpoints() const {return eps;}
|
||||||
PIVector<PIUSB::Endpoint> endpointsRead();
|
PIVector<PIUSB::Endpoint> endpointsRead();
|
||||||
@@ -126,6 +126,8 @@ public:
|
|||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
|
PIString constructFullPath() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PIString fullPathPrefix() const {return "usb";}
|
PIString fullPathPrefix() const {return "usb";}
|
||||||
void configureFromFullPath(const PIString & full_path);
|
void configureFromFullPath(const PIString & full_path);
|
||||||
|
|||||||
132
pivariant.cpp
132
pivariant.cpp
@@ -20,13 +20,42 @@
|
|||||||
#include "pivariant.h"
|
#include "pivariant.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** \class PIVariant
|
||||||
|
* \brief Variant type
|
||||||
|
* \details
|
||||||
|
* \section PIVariant_sec0 Synopsis
|
||||||
|
* This class provides general type that can contains all standard types, some
|
||||||
|
* PIP types or custom type. In case of standard types this class also provides
|
||||||
|
* convertions between them.
|
||||||
|
*
|
||||||
|
* \section PIVariant_sec1 Usage
|
||||||
|
* %PIVariant useful if you want pass many variables with different types in
|
||||||
|
* single array, e.g.:
|
||||||
|
* \code{cpp}
|
||||||
|
* PIVector<PIVariant> array;
|
||||||
|
* array << PIVariant(10) << PIVariant(1.61) << PIVariant(true) << PIVariant("0xFF");
|
||||||
|
* piCout << array;
|
||||||
|
* piForeachC (PIVariant & i, array)
|
||||||
|
* piCout << i.toInt();
|
||||||
|
* \endcode
|
||||||
|
* Result:
|
||||||
|
* \code{cpp}
|
||||||
|
* {PIVariant(Int, 10), PIVariant(Double, 1,61), PIVariant(Bool, true), PIVariant(String, 0xFF)}
|
||||||
|
* 10
|
||||||
|
* 1
|
||||||
|
* 1
|
||||||
|
* 255
|
||||||
|
* \endcode
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
PIVariant::PIVariant() {
|
PIVariant::PIVariant() {
|
||||||
type_ = PIVariant::Invalid;
|
type_ = PIVariant::Invalid;
|
||||||
memset(_vraw, 0, __PIVARIANT_UNION_SIZE__);
|
memset(_vraw, 0, __PIVARIANT_UNION_SIZE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIVariant::operator =(const PIVariant & v) {
|
PIVariant & PIVariant::operator =(const PIVariant & v) {
|
||||||
type_ = v.type_;
|
type_ = v.type_;
|
||||||
memcpy(_vraw, v._vraw, __PIVARIANT_UNION_SIZE__);
|
memcpy(_vraw, v._vraw, __PIVARIANT_UNION_SIZE__);
|
||||||
_vbytearray = v._vbytearray;
|
_vbytearray = v._vbytearray;
|
||||||
@@ -34,6 +63,7 @@ void PIVariant::operator =(const PIVariant & v) {
|
|||||||
_vstring = v._vstring;
|
_vstring = v._vstring;
|
||||||
_vstringlist = v._vstringlist;
|
_vstringlist = v._vstringlist;
|
||||||
_vcustom = v._vcustom;
|
_vcustom = v._vcustom;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -134,6 +164,12 @@ PIString PIVariant::typeName(PIVariant::Type type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as boolean
|
||||||
|
* \details In case of numeric types returns \b true if value != 0. \n
|
||||||
|
* In case of String type returns \a PIString::toBool(). \n
|
||||||
|
* In case of StringList type returns \b false if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toBool() of first string. \n
|
||||||
|
* In case of other types returns \b false. */
|
||||||
bool PIVariant::toBool() const {
|
bool PIVariant::toBool() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -160,6 +196,13 @@ bool PIVariant::toBool() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as int
|
||||||
|
* \details In case of numeric types returns integer value. \n
|
||||||
|
* In case of String type returns \a PIString::toInt(). \n
|
||||||
|
* In case of StringList type returns \b 0 if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toInt() of first string. \n
|
||||||
|
* In case of other types returns \b 0. */
|
||||||
int PIVariant::toInt() const {
|
int PIVariant::toInt() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -179,13 +222,19 @@ int PIVariant::toInt() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toInt();
|
case PIVariant::String: return _vstring.toInt();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toInt();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0; return _vstringlist.front().toInt();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as long long
|
||||||
|
* \details In case of numeric types returns integer value. \n
|
||||||
|
* In case of String type returns \a PIString::toLLong(). \n
|
||||||
|
* In case of StringList type returns \b 0L if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toLLong() of first string. \n
|
||||||
|
* In case of other types returns \b 0L. */
|
||||||
llong PIVariant::toLLong() const {
|
llong PIVariant::toLLong() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -205,13 +254,19 @@ llong PIVariant::toLLong() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toLLong();
|
case PIVariant::String: return _vstring.toLLong();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLLong();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0L; return _vstringlist.front().toLLong();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as float
|
||||||
|
* \details In case of numeric types returns float value. \n
|
||||||
|
* In case of String type returns \a PIString::toFloat(). \n
|
||||||
|
* In case of StringList type returns \b 0.f if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toFloat() of first string. \n
|
||||||
|
* In case of other types returns \b 0.f. */
|
||||||
float PIVariant::toFloat() const {
|
float PIVariant::toFloat() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -231,13 +286,19 @@ float PIVariant::toFloat() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toFloat();
|
case PIVariant::String: return _vstring.toFloat();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toFloat();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.f; return _vstringlist.front().toFloat();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as double
|
||||||
|
* \details In case of numeric types returns double value. \n
|
||||||
|
* In case of String type returns \a PIString::toDouble(). \n
|
||||||
|
* In case of StringList type returns \b 0. if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toDouble() of first string. \n
|
||||||
|
* In case of other types returns \b 0.. */
|
||||||
double PIVariant::toDouble() const {
|
double PIVariant::toDouble() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -257,13 +318,19 @@ double PIVariant::toDouble() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toDouble();
|
case PIVariant::String: return _vstring.toDouble();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toDouble();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.; return _vstringlist.front().toDouble();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0.;
|
return 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as long double
|
||||||
|
* \details In case of numeric types returns long double value. \n
|
||||||
|
* In case of String type returns \a PIString::toLDouble(). \n
|
||||||
|
* In case of StringList type returns \b 0. if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toLDouble() of first string. \n
|
||||||
|
* In case of other types returns \b 0.. */
|
||||||
ldouble PIVariant::toLDouble() const {
|
ldouble PIVariant::toLDouble() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -283,13 +350,19 @@ ldouble PIVariant::toLDouble() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toLDouble();
|
case PIVariant::String: return _vstring.toLDouble();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLDouble();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.; return _vstringlist.front().toLDouble();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0.;
|
return 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as complex
|
||||||
|
* \details In case of numeric types returns complex value. \n
|
||||||
|
* In case of String type returns \a PIString::toDouble(). \n
|
||||||
|
* In case of StringList type returns \b 0. if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toDouble() of first string. \n
|
||||||
|
* In case of other types returns \b 0.. */
|
||||||
complexd PIVariant::toComplexd() const {
|
complexd PIVariant::toComplexd() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -309,13 +382,19 @@ complexd PIVariant::toComplexd() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toDouble();
|
case PIVariant::String: return _vstring.toDouble();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toDouble();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return complexd_0; return _vstringlist.front().toDouble();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return complexd_0;
|
return complexd_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as long complex
|
||||||
|
* \details In case of numeric types returns long complex value. \n
|
||||||
|
* In case of String type returns \a PIString::toLDouble(). \n
|
||||||
|
* In case of StringList type returns \b 0. if string list is empty,
|
||||||
|
* otherwise returns \a PIString::toLDouble() of first string. \n
|
||||||
|
* In case of other types returns \b 0.. */
|
||||||
complexld PIVariant::toComplexld() const {
|
complexld PIVariant::toComplexld() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool:
|
case PIVariant::Bool:
|
||||||
@@ -335,13 +414,17 @@ complexld PIVariant::toComplexld() const {
|
|||||||
case PIVariant::Complexd: return _vcomplexd.real();
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
case PIVariant::Complexld: return _vcomplexld.real();
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
case PIVariant::String: return _vstring.toLDouble();
|
case PIVariant::String: return _vstring.toLDouble();
|
||||||
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLDouble();
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return complexld_0; return _vstringlist.front().toLDouble();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return complexld_0;
|
return complexld_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as time
|
||||||
|
* \details In case of Time type returns time value. \n
|
||||||
|
* In case of DateTime type returns time part of value. \n
|
||||||
|
* In case of other types returns \a PITime(). */
|
||||||
PITime PIVariant::toTime() const {
|
PITime PIVariant::toTime() const {
|
||||||
if (type_ == PIVariant::Time) return _vtime;
|
if (type_ == PIVariant::Time) return _vtime;
|
||||||
if (type_ == PIVariant::DateTime) return _vtime;
|
if (type_ == PIVariant::DateTime) return _vtime;
|
||||||
@@ -349,6 +432,10 @@ PITime PIVariant::toTime() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as date
|
||||||
|
* \details In case of Date type returns date value. \n
|
||||||
|
* In case of DateTime type returns date part of value. \n
|
||||||
|
* In case of other types returns \a PIDate(). */
|
||||||
PIDate PIVariant::toDate() const {
|
PIDate PIVariant::toDate() const {
|
||||||
if (type_ == PIVariant::Date) return _vdate;
|
if (type_ == PIVariant::Date) return _vdate;
|
||||||
if (type_ == PIVariant::DateTime) return *((PIDate*)(&(_vdatetime.day)));
|
if (type_ == PIVariant::DateTime) return *((PIDate*)(&(_vdatetime.day)));
|
||||||
@@ -356,6 +443,11 @@ PIDate PIVariant::toDate() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as date and time
|
||||||
|
* \details In case of Time type returns time value with null date. \n
|
||||||
|
* In case of Date type returns date value with null time. \n
|
||||||
|
* In case of DateTime type returns date and time. \n
|
||||||
|
* In case of other types returns \a PIDateTime(). */
|
||||||
PIDateTime PIVariant::toDateTime() const {
|
PIDateTime PIVariant::toDateTime() const {
|
||||||
if (type_ == PIVariant::DateTime) return _vdatetime;
|
if (type_ == PIVariant::DateTime) return _vdatetime;
|
||||||
if (type_ == PIVariant::Time) return PIDateTime(_vtime);
|
if (type_ == PIVariant::Time) return PIDateTime(_vtime);
|
||||||
@@ -364,12 +456,25 @@ PIDateTime PIVariant::toDateTime() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as system time
|
||||||
|
* \details In case of SystemTime type returns system time. \n
|
||||||
|
* In case of other types returns \a PISystemTime::fromSeconds() from
|
||||||
|
* double value of variant content. */
|
||||||
PISystemTime PIVariant::toSystemTime() const {
|
PISystemTime PIVariant::toSystemTime() const {
|
||||||
if (type_ == PIVariant::SystemTime) return _vsystime;
|
if (type_ == PIVariant::SystemTime) return _vsystime;
|
||||||
return PISystemTime::fromSeconds(toDouble());
|
return PISystemTime::fromSeconds(toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as string
|
||||||
|
* \details In case of numeric types returns \a PIString::fromNumber(). \n
|
||||||
|
* In case of String type returns string value. \n
|
||||||
|
* In case of StringList type returns joined string ("(" + PIStringList::join("; ") + ")"). \n
|
||||||
|
* In case of BitArray or ByteArray types returns number of bits/bytes. \n
|
||||||
|
* In case of Time, Date or DateTime types returns toString() of this values. \n
|
||||||
|
* In case of SystemTime types returns second and nanoseconds of time
|
||||||
|
* ("(PISystemTime::seconds s, PISystemTime::nanoseconds ns)"). \n
|
||||||
|
* In case of other types returns \b "". */
|
||||||
PIString PIVariant::toString() const {
|
PIString PIVariant::toString() const {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariant::Bool: return _vint == 0 ? "false" : "true";
|
case PIVariant::Bool: return _vint == 0 ? "false" : "true";
|
||||||
@@ -389,7 +494,7 @@ PIString PIVariant::toString() const {
|
|||||||
case PIVariant::Complexd: return "(" + PIString::fromNumber(_vcomplexd.real()) + "; " + PIString::fromNumber(_vcomplexd.imag()) + ")";
|
case PIVariant::Complexd: return "(" + PIString::fromNumber(_vcomplexd.real()) + "; " + PIString::fromNumber(_vcomplexd.imag()) + ")";
|
||||||
case PIVariant::Complexld: return "(" + PIString::fromNumber(_vcomplexld.real()) + "; " + PIString::fromNumber(_vcomplexld.imag()) + ")";
|
case PIVariant::Complexld: return "(" + PIString::fromNumber(_vcomplexld.real()) + "; " + PIString::fromNumber(_vcomplexld.imag()) + ")";
|
||||||
case PIVariant::BitArray: return PIString::fromNumber(_vbitarray.bitSize()) + " bits";
|
case PIVariant::BitArray: return PIString::fromNumber(_vbitarray.bitSize()) + " bits";
|
||||||
case PIVariant::ByteArray: return PIString::fromNumber(_vbytearray.size()) + " bytes";
|
case PIVariant::ByteArray: return _vbytearray.toString();
|
||||||
case PIVariant::String: return _vstring;
|
case PIVariant::String: return _vstring;
|
||||||
case PIVariant::StringList: return "(" + _vstringlist.join("; ") + ")";
|
case PIVariant::StringList: return "(" + _vstringlist.join("; ") + ")";
|
||||||
case PIVariant::Time: return _vtime.toString();
|
case PIVariant::Time: return _vtime.toString();
|
||||||
@@ -402,18 +507,27 @@ PIString PIVariant::toString() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as strings list
|
||||||
|
* \details In case of StringList type returns strings list value. \n
|
||||||
|
* In case of other types returns \a PIStringList with one string value of variant content. */
|
||||||
PIStringList PIVariant::toStringList() const {
|
PIStringList PIVariant::toStringList() const {
|
||||||
if (type_ == PIVariant::StringList) return _vstringlist;
|
if (type_ == PIVariant::StringList) return _vstringlist;
|
||||||
return PIStringList(toString());
|
return PIStringList(toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as bit array
|
||||||
|
* \details In case of BitArray type returns bit array value. \n
|
||||||
|
* In case of other types returns \a PIBitArray from \a toLLong() value. */
|
||||||
PIBitArray PIVariant::toBitArray() const {
|
PIBitArray PIVariant::toBitArray() const {
|
||||||
if (type_ == PIVariant::BitArray) return _vbitarray;
|
if (type_ == PIVariant::BitArray) return _vbitarray;
|
||||||
return PIBitArray(ullong(toLLong()));
|
return PIBitArray(ullong(toLLong()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as byte array
|
||||||
|
* \details In case of ByteArray type returns byte array value. \n
|
||||||
|
* In case of other types returns empty \a PIByteArray. */
|
||||||
PIByteArray PIVariant::toByteArray() const {
|
PIByteArray PIVariant::toByteArray() const {
|
||||||
if (type_ == PIVariant::ByteArray) return _vbytearray;
|
if (type_ == PIVariant::ByteArray) return _vbytearray;
|
||||||
return PIByteArray();
|
return PIByteArray();
|
||||||
|
|||||||
255
pivariant.h
255
pivariant.h
@@ -49,88 +49,192 @@
|
|||||||
class PIP_EXPORT PIVariant {
|
class PIP_EXPORT PIVariant {
|
||||||
friend PICout operator <<(PICout s, const PIVariant & v);
|
friend PICout operator <<(PICout s, const PIVariant & v);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//! Type of %PIVariant content
|
||||||
enum Type {
|
enum Type {
|
||||||
Invalid = 0,
|
Invalid /** Invalid type , default type of empty contructor */ = 0 ,
|
||||||
Bool,
|
Bool /** bool */ ,
|
||||||
Char,
|
Char /** char */ ,
|
||||||
UChar,
|
UChar /** uchar */ ,
|
||||||
Short,
|
Short /** short */ ,
|
||||||
UShort,
|
UShort /** ushort */ ,
|
||||||
Int,
|
Int /** int */ ,
|
||||||
UInt,
|
UInt /** uint */ ,
|
||||||
Long,
|
Long /** long */ ,
|
||||||
ULong,
|
ULong /** ulong */ ,
|
||||||
LLong,
|
LLong /** llong */ ,
|
||||||
ULLong,
|
ULLong /** ullong */ ,
|
||||||
Float,
|
Float /** float */ ,
|
||||||
Double,
|
Double /** double */ ,
|
||||||
LDouble,
|
LDouble /** ldouble */ ,
|
||||||
Complexd,
|
Complexd /** complexd */ ,
|
||||||
Complexld,
|
Complexld /** complexld */ ,
|
||||||
BitArray,
|
BitArray /** PIBitArray */ ,
|
||||||
ByteArray,
|
ByteArray /** PIByteArray */ ,
|
||||||
String,
|
String /** PIString */ ,
|
||||||
StringList,
|
StringList /** PIStringList */ ,
|
||||||
Time,
|
Time /** PITime */ ,
|
||||||
Date,
|
Date /** PIDate */ ,
|
||||||
DateTime,
|
DateTime /** PIDateTime */ ,
|
||||||
SystemTime,
|
SystemTime /** PISystemTime */ ,
|
||||||
Custom = 0xFF
|
Custom /** Custom */ = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Empty constructor, \a type() will be set to \a Invalid
|
||||||
PIVariant();
|
PIVariant();
|
||||||
|
|
||||||
|
//! Constructs variant from string
|
||||||
PIVariant(const char * v) {setValue(PIString(v));}
|
PIVariant(const char * v) {setValue(PIString(v));}
|
||||||
|
|
||||||
|
//! Constructs variant from boolean
|
||||||
PIVariant(const bool v) {setValue(v);}
|
PIVariant(const bool v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from char
|
||||||
PIVariant(const char v) {setValue(v);}
|
PIVariant(const char v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const uchar v) {setValue(v);}
|
PIVariant(const uchar v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const short v) {setValue(v);}
|
PIVariant(const short v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const ushort v) {setValue(v);}
|
PIVariant(const ushort v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const int & v) {setValue(v);}
|
PIVariant(const int & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const uint & v) {setValue(v);}
|
PIVariant(const uint & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const long & v) {setValue(v);}
|
PIVariant(const long & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const ulong & v) {setValue(v);}
|
PIVariant(const ulong & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const llong & v) {setValue(v);}
|
PIVariant(const llong & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from integer
|
||||||
PIVariant(const ullong & v) {setValue(v);}
|
PIVariant(const ullong & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from float
|
||||||
PIVariant(const float & v) {setValue(v);}
|
PIVariant(const float & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from double
|
||||||
PIVariant(const double & v) {setValue(v);}
|
PIVariant(const double & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from long double
|
||||||
PIVariant(const ldouble & v) {setValue(v);}
|
PIVariant(const ldouble & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from complex
|
||||||
PIVariant(const complexd & v) {setValue(v);}
|
PIVariant(const complexd & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from complex
|
||||||
PIVariant(const complexld & v) {setValue(v);}
|
PIVariant(const complexld & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from bit array
|
||||||
PIVariant(const PIBitArray & v) {setValue(v);}
|
PIVariant(const PIBitArray & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from byte array
|
||||||
PIVariant(const PIByteArray & v) {setValue(v);}
|
PIVariant(const PIByteArray & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from string
|
||||||
PIVariant(const PIString & v) {setValue(v);}
|
PIVariant(const PIString & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from strings list
|
||||||
PIVariant(const PIStringList & v) {setValue(v);}
|
PIVariant(const PIStringList & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from time
|
||||||
PIVariant(const PITime & v) {setValue(v);}
|
PIVariant(const PITime & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from date
|
||||||
PIVariant(const PIDate & v) {setValue(v);}
|
PIVariant(const PIDate & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from date and time
|
||||||
PIVariant(const PIDateTime & v) {setValue(v);}
|
PIVariant(const PIDateTime & v) {setValue(v);}
|
||||||
|
|
||||||
|
//! Constructs variant from system time
|
||||||
PIVariant(const PISystemTime & v) {setValue(v);}
|
PIVariant(const PISystemTime & v) {setValue(v);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Set variant content and type to string
|
||||||
void setValue(const char * v) {setValue(PIString(v));}
|
void setValue(const char * v) {setValue(PIString(v));}
|
||||||
|
|
||||||
|
//! Set variant content and type to boolean
|
||||||
void setValue(const bool v) {type_ = PIVariant::Bool; _vint = (v ? 1 : 0);}
|
void setValue(const bool v) {type_ = PIVariant::Bool; _vint = (v ? 1 : 0);}
|
||||||
|
|
||||||
|
//! Set variant content and type to char
|
||||||
void setValue(const char v) {type_ = PIVariant::Char; _vint = v;}
|
void setValue(const char v) {type_ = PIVariant::Char; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const uchar v) {type_ = PIVariant::UChar; _vint = v;}
|
void setValue(const uchar v) {type_ = PIVariant::UChar; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const short v) {type_ = PIVariant::Short; _vint = v;}
|
void setValue(const short v) {type_ = PIVariant::Short; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const ushort v) {type_ = PIVariant::UShort; _vint = v;}
|
void setValue(const ushort v) {type_ = PIVariant::UShort; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const int & v) {type_ = PIVariant::Int; _vint = v;}
|
void setValue(const int & v) {type_ = PIVariant::Int; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const uint & v) {type_ = PIVariant::UInt; _vint = v;}
|
void setValue(const uint & v) {type_ = PIVariant::UInt; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const long & v) {type_ = PIVariant::Long; _vint = v;}
|
void setValue(const long & v) {type_ = PIVariant::Long; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const ulong & v) {type_ = PIVariant::ULong; _vint = v;}
|
void setValue(const ulong & v) {type_ = PIVariant::ULong; _vint = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const llong & v) {type_ = PIVariant::LLong; _vllong = v;}
|
void setValue(const llong & v) {type_ = PIVariant::LLong; _vllong = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to integer
|
||||||
void setValue(const ullong & v) {type_ = PIVariant::ULLong; _vllong = v;}
|
void setValue(const ullong & v) {type_ = PIVariant::ULLong; _vllong = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to float
|
||||||
void setValue(const float & v) {type_ = PIVariant::Float; _vfloat = v;}
|
void setValue(const float & v) {type_ = PIVariant::Float; _vfloat = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to double
|
||||||
void setValue(const double & v) {type_ = PIVariant::Double; _vdouble = v;}
|
void setValue(const double & v) {type_ = PIVariant::Double; _vdouble = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to long double
|
||||||
void setValue(const ldouble & v) {type_ = PIVariant::LDouble; _vldouble = v;}
|
void setValue(const ldouble & v) {type_ = PIVariant::LDouble; _vldouble = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to complex
|
||||||
void setValue(const complexd & v) {type_ = PIVariant::Complexd; _vcomplexd = v;}
|
void setValue(const complexd & v) {type_ = PIVariant::Complexd; _vcomplexd = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to complex
|
||||||
void setValue(const complexld & v) {type_ = PIVariant::Complexld; _vcomplexld = v;}
|
void setValue(const complexld & v) {type_ = PIVariant::Complexld; _vcomplexld = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to bit array
|
||||||
void setValue(const PIBitArray & v) {type_ = PIVariant::BitArray; _vbitarray = v;}
|
void setValue(const PIBitArray & v) {type_ = PIVariant::BitArray; _vbitarray = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to byte array
|
||||||
void setValue(const PIByteArray & v) {type_ = PIVariant::ByteArray; _vbytearray = v;}
|
void setValue(const PIByteArray & v) {type_ = PIVariant::ByteArray; _vbytearray = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to string
|
||||||
void setValue(const PIString & v) {type_ = PIVariant::String; _vstring = v;}
|
void setValue(const PIString & v) {type_ = PIVariant::String; _vstring = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to strings list
|
||||||
void setValue(const PIStringList & v) {type_ = PIVariant::StringList; _vstringlist = v;}
|
void setValue(const PIStringList & v) {type_ = PIVariant::StringList; _vstringlist = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to time
|
||||||
void setValue(const PITime & v) {type_ = PIVariant::Time; _vtime = v;}
|
void setValue(const PITime & v) {type_ = PIVariant::Time; _vtime = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to date
|
||||||
void setValue(const PIDate & v) {type_ = PIVariant::Date; _vdate = v;}
|
void setValue(const PIDate & v) {type_ = PIVariant::Date; _vdate = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to date and time
|
||||||
void setValue(const PIDateTime & v) {type_ = PIVariant::DateTime; _vdatetime = v;}
|
void setValue(const PIDateTime & v) {type_ = PIVariant::DateTime; _vdatetime = v;}
|
||||||
|
|
||||||
|
//! Set variant content and type to system time
|
||||||
void setValue(const PISystemTime & v) {type_ = PIVariant::SystemTime; _vsystime = v;}
|
void setValue(const PISystemTime & v) {type_ = PIVariant::SystemTime; _vsystime = v;}
|
||||||
|
|
||||||
|
|
||||||
bool toBool() const;
|
bool toBool() const;
|
||||||
int toInt() const;
|
int toInt() const;
|
||||||
llong toLLong() const;
|
llong toLLong() const;
|
||||||
@@ -148,6 +252,10 @@ public:
|
|||||||
PIBitArray toBitArray() const;
|
PIBitArray toBitArray() const;
|
||||||
PIByteArray toByteArray() const;
|
PIByteArray toByteArray() const;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns variant content as custom type
|
||||||
|
* \details In case of known types this function equivalent \a to<Type> function. \n
|
||||||
|
* Otherwise returns content as type T. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T toValue() const {if (_vcustom.size() != sizeof(T)) return T(); return *((T*)_vcustom.data());}
|
T toValue() const {if (_vcustom.size() != sizeof(T)) return T(); return *((T*)_vcustom.data());}
|
||||||
/*
|
/*
|
||||||
@@ -177,46 +285,89 @@ public:
|
|||||||
operator const char*() const {return toString().data();}
|
operator const char*() const {return toString().data();}
|
||||||
operator void*() const {return (void*)(toLLong());}
|
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);}
|
|
||||||
void operator =(const char v) {setValue(v);}
|
|
||||||
void operator =(const uchar v) {setValue(v);}
|
|
||||||
void operator =(const short v) {setValue(v);}
|
|
||||||
void operator =(const ushort v) {setValue(v);}
|
|
||||||
void operator =(const int & v) {setValue(v);}
|
|
||||||
void operator =(const uint & v) {setValue(v);}
|
|
||||||
void operator =(const long & v) {setValue(v);}
|
|
||||||
void operator =(const ulong & v) {setValue(v);}
|
|
||||||
void operator =(const llong & v) {setValue(v);}
|
|
||||||
void operator =(const ullong & v) {setValue(v);}
|
|
||||||
void operator =(const float & v) {setValue(v);}
|
|
||||||
void operator =(const double & v) {setValue(v);}
|
|
||||||
void operator =(const ldouble & v) {setValue(v);}
|
|
||||||
void operator =(const complexd & v) {setValue(v);}
|
|
||||||
void operator =(const complexld & v) {setValue(v);}
|
|
||||||
void operator =(const PIBitArray & v) {setValue(v);}
|
|
||||||
void operator =(const PIByteArray & v) {setValue(v);}
|
|
||||||
void operator =(const PIString & v) {setValue(v);}
|
|
||||||
void operator =(const PIStringList & v) {setValue(v);}
|
|
||||||
void operator =(const PITime & v) {setValue(v);}
|
|
||||||
void operator =(const PIDate & v) {setValue(v);}
|
|
||||||
void operator =(const PIDateTime & v) {setValue(v);}
|
|
||||||
void operator =(const PISystemTime & v) {setValue(v);}
|
|
||||||
|
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIVariant & v);
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const char * v) {setValue(PIString(v)); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const bool v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const char v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const uchar v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const short v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const ushort v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const int & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const uint & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const long & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const ulong & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const llong & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const ullong & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const float & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const double & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const ldouble & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const complexd & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const complexld & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIBitArray & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIByteArray & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIString & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIStringList & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PITime & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIDate & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PIDateTime & v) {setValue(v); return *this;}
|
||||||
|
//! Assign operator
|
||||||
|
PIVariant & operator =(const PISystemTime & v) {setValue(v); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare operator
|
||||||
bool operator ==(const PIVariant & v) const;
|
bool operator ==(const PIVariant & v) const;
|
||||||
|
//! Compare operator
|
||||||
bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns type of variant content
|
||||||
PIVariant::Type type() const {return type_;}
|
PIVariant::Type type() const {return type_;}
|
||||||
|
|
||||||
|
//! Returns type name of variant content
|
||||||
PIString typeName() const {return typeName(type_);}
|
PIString typeName() const {return typeName(type_);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns \b true if type is not Invalid
|
||||||
bool isValid() const {return type_ != PIVariant::Invalid;}
|
bool isValid() const {return type_ != PIVariant::Invalid;}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns new variant from custom type
|
||||||
|
* \details In case of known types this function equivalent \a PIVariant(T) constructors. \n
|
||||||
|
* Otherwise returns variant with content \a v and type Custom. */
|
||||||
template <typename T>
|
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 fromValue(const T & v) {PIVariant ret; ret._vcustom.resize(sizeof(T)); new((T*)(ret._vcustom.data()))T(v); ret.type_ = PIVariant::Custom; return ret;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns type from name
|
||||||
static PIVariant::Type typeFromName(const PIString & tname);
|
static PIVariant::Type typeFromName(const PIString & tname);
|
||||||
|
|
||||||
|
//! Returns type name
|
||||||
static PIString typeName(PIVariant::Type type);
|
static PIString typeName(PIVariant::Type type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
57
pivector.h
57
pivector.h
@@ -41,8 +41,7 @@ public:
|
|||||||
PIVector(const PIVector<T> & other): piv_data(0), piv_size(0), piv_rsize(0) {
|
PIVector(const PIVector<T> & other): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
alloc(other.piv_size);
|
alloc(other.piv_size);
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
newT(piv_data, other.piv_data, piv_size);
|
||||||
new(piv_data + i)T(other.piv_data[i]);
|
|
||||||
//printf("(s=%d, d=%p) }!\n", int(piv_size), piv_data);
|
//printf("(s=%d, d=%p) }!\n", int(piv_size), piv_data);
|
||||||
}
|
}
|
||||||
PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) {
|
PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
@@ -77,10 +76,11 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}*/
|
}*/
|
||||||
if (!oj) {
|
if (!oj) {
|
||||||
|
deleteT(piv_data, piv_size);
|
||||||
alloc(other.piv_size);
|
alloc(other.piv_size);
|
||||||
//zeroRaw(piv_data, piv_size);
|
//zeroRaw(piv_data, piv_size);
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
new(piv_data + i)T(other.piv_data[i]); //piv_data[i] = other.piv_data[i];
|
elementNew(piv_data + i, other.piv_data[i]); //piv_data[i] = other.piv_data[i];
|
||||||
} else {
|
} else {
|
||||||
printf("JUNK other\n");
|
printf("JUNK other\n");
|
||||||
}
|
}
|
||||||
@@ -174,6 +174,7 @@ public:
|
|||||||
size_t size() const {return piv_size;}
|
size_t size() const {return piv_size;}
|
||||||
ssize_t size_s() const {return piv_size;}
|
ssize_t size_s() const {return piv_size;}
|
||||||
size_t length() const {return piv_size;}
|
size_t length() const {return piv_size;}
|
||||||
|
size_t capacity() const {return piv_rsize;}
|
||||||
bool isEmpty() const {return (piv_size == 0);}
|
bool isEmpty() const {return (piv_size == 0);}
|
||||||
|
|
||||||
T & operator [](size_t index) {return piv_data[index];}
|
T & operator [](size_t index) {return piv_data[index];}
|
||||||
@@ -197,7 +198,7 @@ public:
|
|||||||
deleteT(piv_data, piv_size);
|
deleteT(piv_data, piv_size);
|
||||||
//zeroRaw(piv_data, piv_size);
|
//zeroRaw(piv_data, piv_size);
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
new(piv_data + i)T(f);
|
elementNew(piv_data + i, f);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
@@ -213,7 +214,7 @@ public:
|
|||||||
alloc(new_size);
|
alloc(new_size);
|
||||||
//if (sizeof(T) == 1) memset(&(piv_data[os]), f, ds);
|
//if (sizeof(T) == 1) memset(&(piv_data[os]), f, ds);
|
||||||
//zeroRaw(&(piv_data[os]), new_size - os);
|
//zeroRaw(&(piv_data[os]), new_size - os);
|
||||||
for (size_t i = os; i < new_size; ++i) new(piv_data + i)T(f);
|
for (size_t i = os; i < new_size; ++i) elementNew(piv_data + i, f);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -226,18 +227,27 @@ public:
|
|||||||
memmove(&(piv_data[index + 1]), &(piv_data[index]), os * sizeof(T));
|
memmove(&(piv_data[index + 1]), &(piv_data[index]), os * sizeof(T));
|
||||||
}
|
}
|
||||||
//zeroRaw(&(piv_data[index]), 1);
|
//zeroRaw(&(piv_data[index]), 1);
|
||||||
new(piv_data + index)T(v);
|
elementNew(piv_data + index, v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PIVector<T> & insert(size_t index, const PIVector<T> & other) {
|
||||||
|
if (other.isEmpty()) return *this;
|
||||||
|
ssize_t os = piv_size - index;
|
||||||
|
alloc(piv_size + other.pid_size, true);
|
||||||
|
if (os > 0)
|
||||||
|
memmove(&(piv_data[index + other.piv_size]), &(piv_data[index]), os * sizeof(T));
|
||||||
|
newT(piv_data + index, other.piv_data, other.piv_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIVector<T> & remove(size_t index, size_t count = 1) {
|
PIVector<T> & remove(size_t index, size_t count = 1) {
|
||||||
|
if (count == 0) return *this;
|
||||||
if (index + count >= piv_size) {
|
if (index + count >= piv_size) {
|
||||||
resize(index);
|
resize(index);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
size_t os = piv_size - index - count;
|
size_t os = piv_size - index - count;
|
||||||
T * de = &(piv_data[index]);
|
deleteT(&(piv_data[index]), count);
|
||||||
deleteT(de, count);
|
|
||||||
memmove(&(piv_data[index]), &(piv_data[index + count]), os * sizeof(T));
|
memmove(&(piv_data[index]), &(piv_data[index + count]), os * sizeof(T));
|
||||||
piv_size -= count;
|
piv_size -= count;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -258,14 +268,13 @@ public:
|
|||||||
PIVector<T> & removeOne(const T & v) {for (size_t i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); return *this;} return *this;}
|
PIVector<T> & removeOne(const T & v) {for (size_t i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); return *this;} return *this;}
|
||||||
PIVector<T> & removeAll(const T & v) {for (llong i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); --i;} return *this;}
|
PIVector<T> & removeAll(const T & v) {for (llong i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); --i;} return *this;}
|
||||||
|
|
||||||
PIVector<T> & push_back(const T & v) {alloc(piv_size + 1); new(piv_data + piv_size - 1)T(v); return *this;}
|
PIVector<T> & push_back(const T & v) {alloc(piv_size + 1); elementNew(piv_data + piv_size - 1, v); return *this;}
|
||||||
PIVector<T> & append(const T & v) {return push_back(v);}
|
PIVector<T> & append(const T & v) {return push_back(v);}
|
||||||
PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
||||||
PIVector<T> & operator <<(const PIVector<T> & t) {
|
PIVector<T> & operator <<(const PIVector<T> & other) {
|
||||||
size_t ps = piv_size;
|
size_t ps = piv_size;
|
||||||
alloc(piv_size + t.piv_size);
|
alloc(piv_size + other.piv_size);
|
||||||
for (int i = 0; i < t.piv_size; ++i)
|
newT(piv_data + ps, other.piv_data, other.piv_size);
|
||||||
new(piv_data + ps + i)T(t.piv_data[i]);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +297,10 @@ private:
|
|||||||
while (s_ >> t) ++t;
|
while (s_ >> t) ++t;
|
||||||
return (1 << t);
|
return (1 << t);
|
||||||
}
|
}
|
||||||
|
inline void newT(T * dst, const T * src, size_t s) {
|
||||||
|
for (size_t i = 0; i < s; ++i)
|
||||||
|
elementNew(dst + i, src[i]);
|
||||||
|
}
|
||||||
T * newRaw(size_t s) {
|
T * newRaw(size_t s) {
|
||||||
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
|
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
|
||||||
//uchar * ret = new uchar[s * sizeof(T)];
|
//uchar * ret = new uchar[s * sizeof(T)];
|
||||||
@@ -300,11 +313,11 @@ private:
|
|||||||
if (piv_tdata == 0) piv_tdata = (T*)(malloc(s * sizeof(T)));
|
if (piv_tdata == 0) piv_tdata = (T*)(malloc(s * sizeof(T)));
|
||||||
else piv_tdata = (T*)(realloc(piv_tdata, s * sizeof(T)));
|
else piv_tdata = (T*)(realloc(piv_tdata, s * sizeof(T)));
|
||||||
}*/
|
}*/
|
||||||
void deleteT(T * d, size_t sz) {
|
inline void deleteT(T * d, size_t sz) {
|
||||||
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
if ((uchar*)d != 0) {
|
if ((uchar*)d != 0) {
|
||||||
for (size_t i = 0; i < sz; ++i)
|
for (size_t i = 0; i < sz; ++i)
|
||||||
d[i].~T();
|
elementDelete(d[i]);
|
||||||
//zeroRaw(d, sz);
|
//zeroRaw(d, sz);
|
||||||
}
|
}
|
||||||
//cout << " > ok]~" << endl;
|
//cout << " > ok]~" << endl;
|
||||||
@@ -320,6 +333,8 @@ private:
|
|||||||
if ((uchar*)d != 0) memset(d, 0, s*sizeof(T));
|
if ((uchar*)d != 0) memset(d, 0, s*sizeof(T));
|
||||||
//cout << " > ok]~" << endl;
|
//cout << " > ok]~" << endl;
|
||||||
}
|
}
|
||||||
|
inline void elementNew(T * to, const T & from) {new(to)T(from);}
|
||||||
|
inline void elementDelete(T & from) {from.~T();}
|
||||||
void dealloc() {deleteRaw(piv_data);}
|
void dealloc() {deleteRaw(piv_data);}
|
||||||
inline void alloc(size_t new_size) {
|
inline void alloc(size_t new_size) {
|
||||||
if (new_size <= piv_rsize) {
|
if (new_size <= piv_rsize) {
|
||||||
@@ -348,7 +363,7 @@ private:
|
|||||||
T * piv_data;
|
T * piv_data;
|
||||||
size_t piv_size, piv_rsize;
|
size_t piv_size, piv_rsize;
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
#define __PIVECTOR_SIMPLE_FUNCTIONS__(T) \
|
#define __PIVECTOR_SIMPLE_FUNCTIONS__(T) \
|
||||||
template<> inline PIVector<T>::~PIVector() {dealloc(); _reset();} \
|
template<> inline PIVector<T>::~PIVector() {dealloc(); _reset();} \
|
||||||
template<> inline PIVector<T> & PIVector<T>::push_back(const T & v) {alloc(piv_size + 1); piv_data[piv_size - 1] = v; return *this;} \
|
template<> inline PIVector<T> & PIVector<T>::push_back(const T & v) {alloc(piv_size + 1); piv_data[piv_size - 1] = v; return *this;} \
|
||||||
@@ -377,6 +392,7 @@ private:
|
|||||||
return *this; \
|
return *this; \
|
||||||
} \
|
} \
|
||||||
template<> inline PIVector<T> & PIVector<T>::remove(size_t index, size_t count) { \
|
template<> inline PIVector<T> & PIVector<T>::remove(size_t index, size_t count) { \
|
||||||
|
if (count == 0) return *this; \
|
||||||
if (index + count >= piv_size) { \
|
if (index + count >= piv_size) { \
|
||||||
resize(index); \
|
resize(index); \
|
||||||
return *this; \
|
return *this; \
|
||||||
@@ -399,7 +415,12 @@ __PIVECTOR_SIMPLE_FUNCTIONS__(llong)
|
|||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(ullong)
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ullong)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(float)
|
__PIVECTOR_SIMPLE_FUNCTIONS__(float)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(double)
|
__PIVECTOR_SIMPLE_FUNCTIONS__(double)
|
||||||
__PIVECTOR_SIMPLE_FUNCTIONS__(ldouble)
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ldouble)*/
|
||||||
|
#define __PIVECTOR_SIMPLE_TYPE__(T) \
|
||||||
|
template<> inline void PIVector<T>::newT(T * dst, const T * src, size_t s) {memcpy(dst, src, s * sizeof(T));} \
|
||||||
|
template<> inline void PIVector<T>::deleteT(T * d, size_t sz) {;} \
|
||||||
|
template<> inline void PIVector<T>::elementNew(T * to, const T & from) {(*to) = from;} \
|
||||||
|
template<> inline void PIVector<T>::elementDelete(T & from) {;}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -484,7 +505,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define __PIVECTOR_SIMPLE_FUNCTIONS__(T)
|
#define __PIVECTOR_SIMPLE_TYPE__(T)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user