29.07.2011 - fundamental new
This commit is contained in:
28
.kdev4/_custom.kdev4
Normal file
28
.kdev4/_custom.kdev4
Normal file
@@ -0,0 +1,28 @@
|
||||
[Containments][1]
|
||||
ActionPluginsSource=Global
|
||||
ExpandAllApplets=false
|
||||
activity=pip
|
||||
activityId=
|
||||
desktop=-1
|
||||
formfactor=0
|
||||
immutability=1
|
||||
lastDesktop=-1
|
||||
lastScreen=0
|
||||
location=0
|
||||
orientation=2
|
||||
plugin=newspaper
|
||||
screen=0
|
||||
wallpaperplugin=color
|
||||
wallpaperpluginmode=
|
||||
|
||||
[Containments][1][Wallpaper][color]
|
||||
backgroundMode=0
|
||||
color1=255,255,255
|
||||
color2=0,0,0
|
||||
|
||||
[General]
|
||||
immutability=1
|
||||
|
||||
[Project]
|
||||
Manager=KDevCMakeManager
|
||||
Name=pip
|
||||
@@ -24,7 +24,10 @@ Arguments=
|
||||
Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
|
||||
Dependency Action=Build
|
||||
EnvironmentGroup=default
|
||||
Project Target=pip,pip
|
||||
Executable=
|
||||
External Terminal=konsole --noclose --workdir %workdir -e %exe
|
||||
Project Target=pip,pip_test
|
||||
Use External Terminal=false
|
||||
Working Directory=
|
||||
isExecutable=false
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
project(pip)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||
file(GLOB CPPS "*.cpp")
|
||||
file(GLOB CPPS "pi*.cpp")
|
||||
add_definitions(-O2 -g3 -Wall)
|
||||
add_executable(pip ${CPPS})
|
||||
add_library(pip SHARED ${CPPS})
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip pthread ws2_32)
|
||||
else (${WIN32})
|
||||
target_link_libraries(pip pthread rt)
|
||||
endif (${WIN32})
|
||||
add_executable(pip_test "main.cpp")
|
||||
if (${WIN32})
|
||||
target_link_libraries(pip_test pip pthread ws2_32)
|
||||
else (${WIN32})
|
||||
target_link_libraries(pip_test pip pthread rt)
|
||||
endif (${WIN32})
|
||||
|
||||
240
Makefile_qnx
Normal file
240
Makefile_qnx
Normal file
@@ -0,0 +1,240 @@
|
||||
####### Compiler, tools and options
|
||||
|
||||
TARGET = pip
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -pipe -D_REENTRANT
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
INCPATH = -I.
|
||||
LINK = g++
|
||||
LFLAGS = -Wl,-O2
|
||||
LIBS = -lsocket
|
||||
DEL_FILE = rm -f
|
||||
DEL_DIR = rmdir
|
||||
|
||||
####### Output directory
|
||||
|
||||
OBJECTS_DIR = ./
|
||||
|
||||
####### Files
|
||||
|
||||
SOURCES = main.cpp \
|
||||
pibytearray.cpp \
|
||||
piconfig.cpp \
|
||||
piconsole.cpp \
|
||||
pidir.cpp \
|
||||
piethernet.cpp \
|
||||
pievaluator.cpp \
|
||||
pifile.cpp \
|
||||
pikbdlistener.cpp \
|
||||
pimath.cpp \
|
||||
piprotocol.cpp \
|
||||
piserial.cpp \
|
||||
pistring.cpp \
|
||||
pithread.cpp \
|
||||
pitimer.cpp \
|
||||
pivariable.cpp
|
||||
OBJECTS = main.o \
|
||||
pibytearray.o \
|
||||
piconfig.o \
|
||||
piconsole.o \
|
||||
pidir.o \
|
||||
piethernet.o \
|
||||
pievaluator.o \
|
||||
pifile.o \
|
||||
pikbdlistener.o \
|
||||
pimath.o \
|
||||
piprotocol.o \
|
||||
piserial.o \
|
||||
pistring.o \
|
||||
pithread.o \
|
||||
pitimer.o \
|
||||
pivariable.o
|
||||
|
||||
first: all
|
||||
####### Implicit rules
|
||||
|
||||
.SUFFIXES: .o .c .cpp .cc .cxx .C
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||
|
||||
.cc.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||
|
||||
.cxx.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||
|
||||
.C.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
|
||||
|
||||
####### Build rules
|
||||
|
||||
all: Makefile $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
|
||||
|
||||
clean:compiler_clean
|
||||
-$(DEL_FILE) $(OBJECTS)
|
||||
-$(DEL_FILE) *~ core *.core
|
||||
|
||||
distclean: clean
|
||||
-$(DEL_FILE) $(TARGET)
|
||||
-$(DEL_FILE) Makefile
|
||||
|
||||
compiler_clean:
|
||||
|
||||
####### Compile
|
||||
|
||||
main.o: main.cpp pip.h \
|
||||
pitimer.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h \
|
||||
pivariable.h \
|
||||
piconfig.h \
|
||||
pifile.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h \
|
||||
piconsole.h \
|
||||
pikbdlistener.h \
|
||||
pievaluator.h \
|
||||
pimath.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp
|
||||
|
||||
pibytearray.o: pibytearray.cpp pibytearray.h \
|
||||
pibitarray.h \
|
||||
piincludes.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pibytearray.o pibytearray.cpp
|
||||
|
||||
piconfig.o: piconfig.cpp piconfig.h \
|
||||
pifile.h \
|
||||
piincludes.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piconfig.o piconfig.cpp
|
||||
|
||||
piconsole.o: piconsole.cpp piconsole.h \
|
||||
pikbdlistener.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piconsole.o piconsole.cpp
|
||||
|
||||
pidir.o: pidir.cpp pidir.h \
|
||||
pifile.h \
|
||||
piincludes.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pidir.o pidir.cpp
|
||||
|
||||
piethernet.o: piethernet.cpp piethernet.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piethernet.o piethernet.cpp
|
||||
|
||||
pievaluator.o: pievaluator.cpp pievaluator.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
piincludes.h \
|
||||
pichar.h \
|
||||
pimath.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pievaluator.o pievaluator.cpp
|
||||
|
||||
pifile.o: pifile.cpp pifile.h \
|
||||
piincludes.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pifile.o pifile.cpp
|
||||
|
||||
pikbdlistener.o: pikbdlistener.cpp pikbdlistener.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pikbdlistener.o pikbdlistener.cpp
|
||||
|
||||
pimath.o: pimath.cpp pimath.h \
|
||||
piincludes.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pimath.o pimath.cpp
|
||||
|
||||
piprotocol.o: piprotocol.cpp piprotocol.h \
|
||||
piserial.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h \
|
||||
piethernet.h \
|
||||
pitimer.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piprotocol.o piprotocol.cpp
|
||||
|
||||
piserial.o: piserial.cpp piserial.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piserial.o piserial.cpp
|
||||
|
||||
pistring.o: pistring.cpp pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
piincludes.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pistring.o pistring.cpp
|
||||
|
||||
pithread.o: pithread.cpp pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pithread.o pithread.cpp
|
||||
|
||||
pitimer.o: pitimer.cpp pitimer.h \
|
||||
pithread.h \
|
||||
piincludes.h \
|
||||
pimutex.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pitimer.o pitimer.cpp
|
||||
|
||||
pivariable.o: pivariable.cpp pivariable.h \
|
||||
piconfig.h \
|
||||
pifile.h \
|
||||
piincludes.h \
|
||||
pistring.h \
|
||||
pibytearray.h \
|
||||
pibitarray.h \
|
||||
pichar.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pivariable.o pivariable.cpp
|
||||
|
||||
####### Install
|
||||
|
||||
install: FORCE
|
||||
|
||||
uninstall: FORCE
|
||||
|
||||
FORCE:
|
||||
|
||||
41
main.cpp
41
main.cpp
@@ -1,26 +1,21 @@
|
||||
#include "pip.h"
|
||||
#include <pip.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
/*PIString s("I love Kusia! <3");
|
||||
PIByteArray c(s.data(), s.size());
|
||||
c.compressHuffman();
|
||||
cout << s << endl << c << endl;
|
||||
//c.decompressRLE(128);
|
||||
cout << c << endl;*/
|
||||
PIBitArray a(0xFFF00Fu);
|
||||
//cout << a << endl;
|
||||
a.setBit(31);
|
||||
cout << a << endl;
|
||||
a.push_back(true);
|
||||
cout << a << endl;
|
||||
a.push_front(true);
|
||||
cout << a << endl;
|
||||
a.push_front(false);
|
||||
cout << a << endl;
|
||||
a.pop_front();
|
||||
cout << a << endl;
|
||||
a.pop_front();
|
||||
cout << a << endl;
|
||||
a.pop_front();
|
||||
cout << a << endl;
|
||||
PIString s("sos№⚒№хуй"/*☢⚒SOŮ*/);
|
||||
/*cout << s << endl;
|
||||
cout << s.length() << endl;
|
||||
cout << s.stdWString().length() << endl;*/
|
||||
//system("cd /");
|
||||
PIProcess p;
|
||||
//p.setWorkingDirectory("/");
|
||||
//p.setEnvironmentVariable("PWD", "/");
|
||||
//cout << p.environment().join("\n") << endl;
|
||||
p.exec("cd");
|
||||
p.waitForFinish();
|
||||
|
||||
//cout << s << endl;
|
||||
/*wchar_t wc;
|
||||
cout << (int)(uchar)("№"[0]) << ", " << (int)(uchar)("№"[1]) << endl;
|
||||
cout << isascii("№"[0]) << endl;
|
||||
cout << mbtowc(&wc, "№", 4) << endl;*/
|
||||
};
|
||||
|
||||
8
make_install.sh
Executable file
8
make_install.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#! /bin/bash
|
||||
cmake .
|
||||
make -j3
|
||||
if [ $@ != "" ] ; then
|
||||
chown -v $@ /usr/lib/ /usr/include/
|
||||
fi
|
||||
cp -vf *.h /usr/include/
|
||||
cp -vf libpip.so /usr/lib/libpip.so
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef PIBITARRAY_H
|
||||
#define PIBITARRAY_H
|
||||
|
||||
#include "piincludes.h"
|
||||
#include "picontainers.h"
|
||||
|
||||
class PIBitArray {
|
||||
public:
|
||||
|
||||
@@ -74,8 +74,9 @@ private:
|
||||
class PIByteArray: public PIVector<uchar> {
|
||||
public:
|
||||
PIByteArray() {;}
|
||||
PIByteArray(const char * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
||||
PIByteArray(const uchar * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
||||
PIByteArray(const uint size) {resize(size);}
|
||||
PIByteArray(const char * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
||||
PIByteArray(const uchar * data, const uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
||||
|
||||
PIByteArray & convertToBase64();
|
||||
PIByteArray & convertFromBase64();
|
||||
|
||||
102
pichar.h
Normal file
102
pichar.h
Normal file
@@ -0,0 +1,102 @@
|
||||
#ifndef PICHAR_H
|
||||
#define PICHAR_H
|
||||
|
||||
#include "piincludes.h"
|
||||
|
||||
class PIChar
|
||||
{
|
||||
friend class PIString;
|
||||
public:
|
||||
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
||||
PIChar(const short c) {ch = c; ch &= 0xFFFF;}
|
||||
PIChar(const int c = 0) {ch = c;}
|
||||
PIChar(const uchar c) {ch = c; ch &= 0xFF;}
|
||||
PIChar(const ushort c) {ch = c; ch &= 0xFFFF;}
|
||||
PIChar(const uint c) {ch = c;}
|
||||
PIChar(const char * c) {ch = *reinterpret_cast<const int * >(c);}
|
||||
|
||||
//inline operator const int() {return static_cast<const int>(ch);}
|
||||
//inline operator const char() {return toAscii();}
|
||||
|
||||
inline PIChar & operator =(const char v) {ch = v; return *this;}
|
||||
/*inline PIChar & operator =(const short v) {ch = v; return *this;}
|
||||
inline PIChar & operator =(const int v) {ch = v; return *this;}
|
||||
inline PIChar & operator =(const uchar v) {ch = v; return *this;}
|
||||
inline PIChar & operator =(const ushort v) {ch = v; return *this;}
|
||||
inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
|
||||
|
||||
inline bool operator ==(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) == 0;}
|
||||
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
|
||||
if (isAscii()) return (o.toAscii() == toAscii());
|
||||
return (o.toInt() == toInt());}
|
||||
inline bool operator ==(const char o) const {return (PIChar(o) == *this);}
|
||||
inline bool operator ==(const short o) const {return (PIChar(o) == *this);}
|
||||
inline bool operator ==(const int o) const {return (PIChar(o) == *this);}
|
||||
inline bool operator ==(const uchar o) const {return (PIChar(o) == *this);}
|
||||
inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
|
||||
inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
|
||||
|
||||
inline bool operator !=(const PIChar & o) const {return !(o == *this);}
|
||||
/*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
|
||||
inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
|
||||
inline bool operator !=(const int o) const {return (PIChar(o) != *this);}
|
||||
inline bool operator !=(const uchar o) const {return (PIChar(o) != *this);}
|
||||
inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
|
||||
inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
|
||||
|
||||
inline bool operator >(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) < 0;}
|
||||
inline bool operator <(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) > 0;}
|
||||
inline bool operator >=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) <= 0;}
|
||||
inline bool operator <=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) >= 0;}
|
||||
|
||||
inline bool isDigit() const {return isdigit(ch);}
|
||||
inline bool isHex() const {return isxdigit(ch);}
|
||||
inline bool isGraphical() const {return isgraph(ch);}
|
||||
inline bool isControl() const {return iscntrl(ch);}
|
||||
inline bool isLower() const {return islower(ch);}
|
||||
inline bool isUpper() const {return isupper(ch);}
|
||||
inline bool isPrint() const {return isprint(ch);}
|
||||
inline bool isSpace() const {return isspace(ch);}
|
||||
inline bool isAlpha() const {return isalpha(ch);}
|
||||
inline bool isAscii() const {return isascii(ch);}
|
||||
|
||||
inline int toInt() const {return static_cast<const int>(ch);}
|
||||
inline const wchar_t * toWCharPtr() const {return &ch;}
|
||||
inline const char * toCharPtr() const {return reinterpret_cast<const char * >(&ch);}
|
||||
inline const wchar_t toWChar() const {return ch;}
|
||||
inline char toAscii() const {return ch % 256;}
|
||||
inline int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
|
||||
#ifdef WINDOWS
|
||||
inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
|
||||
inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
|
||||
#else
|
||||
inline PIChar toUpper() const {return PIChar(toupper(ch));}
|
||||
inline PIChar toLower() const {return PIChar(tolower(ch));}
|
||||
#endif
|
||||
|
||||
private:
|
||||
wchar_t ch;
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||
|
||||
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||
|
||||
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||
|
||||
inline bool operator ==(const int v, const PIChar & c) {return (PIChar(v) == c);}
|
||||
inline bool operator >(const int v, const PIChar & c) {return (PIChar(v) > c);}
|
||||
inline bool operator <(const int v, const PIChar & c) {return (PIChar(v) < c);}
|
||||
inline bool operator >=(const int v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||
inline bool operator <=(const int v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||
|
||||
#endif // PICHAR_H
|
||||
63
picli.cpp
Normal file
63
picli.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "picli.h"
|
||||
|
||||
|
||||
PICLI::PICLI(int argc, char * argv[]) {
|
||||
needParse = true;
|
||||
_prefix_short = "-";
|
||||
_prefix_full = "--";
|
||||
_count_opt = 0;
|
||||
_count_mand = 1;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
_args_raw << argv[i];
|
||||
}
|
||||
|
||||
|
||||
void PICLI::parse() {
|
||||
if (!needParse) return;
|
||||
PIString cra, full;
|
||||
Argument * last = 0;
|
||||
for (int i = 1; i < _args_raw.size_s(); ++i) {
|
||||
cra = _args_raw[i];
|
||||
if (cra.left(2) == _prefix_full) {
|
||||
last = 0;
|
||||
full = cra.right(cra.length() - 2);
|
||||
piForeachA (a, _args) {
|
||||
if (a.full_key == full) {
|
||||
a.found = true;
|
||||
last = &a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cra.left(1) == _prefix_short) {
|
||||
last = 0;
|
||||
for (int j = 1; j < cra.length(); ++j) {
|
||||
piForeachA (a, _args) {
|
||||
if (a.short_key == cra[j]) {
|
||||
a.found = true;
|
||||
last = &a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (last == 0 ? true : !last->has_value) {
|
||||
if (_args_mand.size_s() < _count_mand) {
|
||||
_args_mand << cra;
|
||||
continue;
|
||||
}
|
||||
if (_args_opt.size_s() < _count_opt) {
|
||||
_args_opt << cra;
|
||||
continue;
|
||||
}
|
||||
cout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
||||
}
|
||||
if (last == 0 ? false : last->has_value) {
|
||||
last->value = cra;
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
needParse = false;
|
||||
}
|
||||
60
picli.h
Normal file
60
picli.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef PICLI_H
|
||||
#define PICLI_H
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
class PICLI
|
||||
{
|
||||
public:
|
||||
PICLI(int argc, char * argv[]);
|
||||
|
||||
inline void addArgument(const PIString & name, bool value = false) {_args << Argument(name, name[0], name, value); needParse = true;}
|
||||
inline void addArgument(const PIString & name, const PIChar & shortKey, bool value = false) {_args << Argument(name, shortKey, name, value); needParse = true;}
|
||||
inline void addArgument(const PIString & name, const char * shortKey, bool value = false) {_args << Argument(name, PIChar(shortKey), name, value); needParse = true;}
|
||||
inline void addArgument(const PIString & name, const PIChar & shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, shortKey, fullKey, value); needParse = true;}
|
||||
inline void addArgument(const PIString & name, const char * shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, PIChar(shortKey), fullKey, value); needParse = true;}
|
||||
|
||||
inline PIString rawArgument(int index) {return _args_raw[index];}
|
||||
inline PIString mandatoryArgument(int index) {return _args_mand[index];}
|
||||
inline PIString optionalArgument(int index) {return _args_opt[index];}
|
||||
inline const PIStringList & rawArguments() const {return _args_raw;}
|
||||
inline const PIStringList & mandatoryArguments() const {return _args_mand;}
|
||||
inline const PIStringList & optionalArguments() const {return _args_opt;}
|
||||
inline const PIString programCommand() const {return _args_raw.size() > 0 ? _args_raw.front() : PIString();}
|
||||
inline bool hasArgument(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return true; return false;}
|
||||
inline PIString argumentValue(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return i.value; return PIString();}
|
||||
inline PIString argumentShortKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.short_key; return PIString();}
|
||||
inline PIString argumentFullKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.full_key; return PIString();}
|
||||
|
||||
inline const PIString & shortKeyPrefix() const {return _prefix_short;}
|
||||
inline const PIString & fullKeyPrefix() const {return _prefix_full;}
|
||||
inline const int mandatoryArgumentsCount() const {return _count_mand;}
|
||||
inline const int optionalArgumentsCount() const {return _count_opt;}
|
||||
inline void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix;}
|
||||
inline void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix;}
|
||||
inline void setMandatoryArgumentsCount(const int count) {_count_mand = count;}
|
||||
inline void setOptionalArgumentsCount(const int count) {_count_opt = count;}
|
||||
|
||||
private:
|
||||
struct Argument {
|
||||
Argument() {has_value = found = false;}
|
||||
Argument(const PIString & n, const PIChar & s, const PIString & f, bool v) {name = n; short_key = s; full_key = f; has_value = v; found = false;}
|
||||
PIString name;
|
||||
PIChar short_key;
|
||||
PIString full_key;
|
||||
PIString value;
|
||||
bool has_value, found;
|
||||
};
|
||||
|
||||
void parse();
|
||||
|
||||
PIString _prefix_short, _prefix_full;
|
||||
PIStringList _args_raw, _args_mand, _args_opt;
|
||||
PISet<PIString> keys_full, keys_short;
|
||||
PIVector<Argument> _args;
|
||||
int _count_mand, _count_opt;
|
||||
bool needParse;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICLI_H
|
||||
22
picodec.cpp
Normal file
22
picodec.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "picodec.h"
|
||||
|
||||
|
||||
PIStringList PICodec::availableCodecs() {
|
||||
exec("iconv", "-l");
|
||||
waitForFinish();
|
||||
PIString str(readOutput());
|
||||
str.cutLeft(str.find("\n "));
|
||||
str.replaceAll("\n", "");
|
||||
return str.split("//");
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PICodec::exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str) {
|
||||
tf.open();
|
||||
tf.clear();
|
||||
tf << str;
|
||||
tf.close();
|
||||
exec("iconv", ("-f=" + from), ("-t=" + to), tf.path());
|
||||
waitForFinish();
|
||||
return readOutput();
|
||||
}
|
||||
31
picodec.h
Normal file
31
picodec.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef PICODEC_H
|
||||
#define PICODEC_H
|
||||
|
||||
#include "piprocess.h"
|
||||
|
||||
class PICodec: private PIProcess
|
||||
{
|
||||
public:
|
||||
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write); tf.open();}
|
||||
PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write);}
|
||||
~PICodec() {tf.remove();}
|
||||
|
||||
void setFromCoding(const PIString & from) {c_from = from;}
|
||||
void setToCoding(const PIString & to) {c_to = to;}
|
||||
void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;}
|
||||
|
||||
PIStringList availableCodecs();
|
||||
PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));}
|
||||
PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));}
|
||||
PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));}
|
||||
PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));}
|
||||
|
||||
private:
|
||||
PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str);
|
||||
|
||||
PIString c_from, c_to;
|
||||
PIFile tf;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICODEC_H
|
||||
583
piconfig.cpp
583
piconfig.cpp
@@ -1,259 +1,474 @@
|
||||
#include "piconfig.h"
|
||||
|
||||
|
||||
PIConfig::PIConfig(const PIString & path, Flags<Mode> mode): PIFile(path, mode) {
|
||||
PIConfig::Entry PIConfig::Branch::_empty;
|
||||
PIConfig::Entry PIConfig::Entry::_empty;
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::Branch::allLeaves() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachCA (i, *this) {
|
||||
if (i->isLeaf()) b << i;
|
||||
else allLeaves(b, i);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIString & def, bool * exist) {
|
||||
if (vname.isEmpty()) {
|
||||
_empty.clear();
|
||||
_empty.delim = delim;
|
||||
if (exist != 0) *exist = false;
|
||||
return _empty;
|
||||
}
|
||||
PIStringList tree = vname.split(delim);
|
||||
PIString name = tree.front();
|
||||
tree.pop_front();
|
||||
Entry * ce = 0;
|
||||
piForeachCA (i, *this)
|
||||
if (i->_name == name) {
|
||||
ce = i;
|
||||
break;
|
||||
}
|
||||
if (ce == 0) {
|
||||
_empty._name = vname;
|
||||
_empty._value = def;
|
||||
_empty.delim = delim;
|
||||
if (exist != 0) *exist = false;
|
||||
return _empty;
|
||||
}
|
||||
piForeachCA (i, tree) {
|
||||
ce = ce->findChild(i);
|
||||
if (ce == 0) {
|
||||
_empty._name = vname;
|
||||
_empty._value = def;
|
||||
_empty.delim = delim;
|
||||
if (exist != 0) *exist = false;
|
||||
return _empty;
|
||||
}
|
||||
}
|
||||
if (exist != 0) *exist = true;
|
||||
return *ce;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachA (i, *this) {
|
||||
if (i->isLeaf()) {
|
||||
if (i->_name.find(name) >= 0)
|
||||
b << i;
|
||||
} else {
|
||||
piForeachA (j, i->_children)
|
||||
if (j->_name.find(name) >= 0)
|
||||
b << j;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::Branch::getLeaves() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachA (i, *this)
|
||||
if (i->isLeaf())
|
||||
b << i;
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::Branch::getBranches() {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachA (i, *this)
|
||||
if (!i->isLeaf())
|
||||
b << i;
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch & PIConfig::Branch::filter(const PIString & f) {
|
||||
for (int i = 0; i < size_s(); ++i) {
|
||||
if (at(i)->_name.find(f) < 0) {
|
||||
remove(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const {
|
||||
if (e->_children.isEmpty()) {
|
||||
if (e->_name == name) return true;
|
||||
else return false;
|
||||
}
|
||||
piForeachCA (i, e->_children)
|
||||
if (entryExists(i, name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIString & def, bool * exist) {
|
||||
PIStringList tree = vname.split(delim);
|
||||
Entry * ce = this;
|
||||
piForeachCA (i, tree) {
|
||||
ce = ce->findChild(i);
|
||||
if (ce == 0) {
|
||||
_empty._name = vname;
|
||||
_empty._value = def;
|
||||
_empty.delim = delim;
|
||||
if (exist != 0) *exist = false;
|
||||
return _empty;
|
||||
}
|
||||
}
|
||||
if (exist != 0) *exist = true;
|
||||
return *ce;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachA (i, _children)
|
||||
if (i->_name.find(vname) >= 0)
|
||||
b << i;
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const {
|
||||
if (e->_children.isEmpty()) {
|
||||
if (e->_name == name) return true;
|
||||
else return false;
|
||||
}
|
||||
piForeachCA (i, e->_children)
|
||||
if (entryExists(i, name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::PIConfig(const PIString & path, PIFlags<Mode> mode): PIFile(path, mode) {
|
||||
delim = ".";
|
||||
root.delim = delim;
|
||||
empty.delim = delim;
|
||||
empty._parent = 0;
|
||||
if (!isOpened() && (mode[Write] || mode[New]))
|
||||
open(path, Read | Write | New);
|
||||
parse();
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIConfig::getValue(const PIString & vname, const PIStringList & def, bool * exist) const {
|
||||
return getValue(vname, def.join("%|%"), exist).split("%|%");}
|
||||
bool PIConfig::getValue(const PIString & vname, const bool def, bool * exist) const {
|
||||
return atob(getValue(vname, btos(def), exist));}
|
||||
char PIConfig::getValue(const PIString & vname, const char def, bool * exist) const {
|
||||
return getValue(vname, PIString(def), exist)[0];}
|
||||
short PIConfig::getValue(const PIString & vname, const short def, bool * exist) const {
|
||||
return getValue(vname, itos(def), exist).toShort();}
|
||||
int PIConfig::getValue(const PIString & vname, const int def, bool * exist) const {
|
||||
return getValue(vname, itos(def), exist).toInt();}
|
||||
long PIConfig::getValue(const PIString & vname, const long def, bool * exist) const {
|
||||
return getValue(vname, ltos(def), exist).toLong();}
|
||||
uchar PIConfig::getValue(const PIString & vname, const uchar def, bool * exist) const {
|
||||
return getValue(vname, uitos(def), exist).toInt();}
|
||||
ushort PIConfig::getValue(const PIString & vname, const ushort def, bool * exist) const {
|
||||
return getValue(vname, uitos(def), exist).toShort();}
|
||||
uint PIConfig::getValue(const PIString & vname, const uint def, bool * exist) const {
|
||||
return getValue(vname, uitos(def), exist).toInt();}
|
||||
ulong PIConfig::getValue(const PIString & vname, const ulong def, bool * exist) const {
|
||||
return getValue(vname, ultos(def), exist).toLong();}
|
||||
float PIConfig::getValue(const PIString & vname, const float def, bool * exist) const {
|
||||
return getValue(vname, ftos(def), exist).toFloat();}
|
||||
double PIConfig::getValue(const PIString & vname, const double def, bool * exist) const {
|
||||
return getValue(vname, dtos(def), exist).toDouble();}
|
||||
|
||||
|
||||
void PIConfig::setValue(const PIString & name, const PIStringList & value, bool write) {
|
||||
setValue(name, value.join("%|%"), "l", write);}
|
||||
void PIConfig::setValue(const PIString & name, const char * value, bool write) {
|
||||
setValue(name, PIString(value), "s", write);}
|
||||
void PIConfig::setValue(const PIString & name, const bool value, bool write) {
|
||||
setValue(name, btos(value), "b", write);}
|
||||
void PIConfig::setValue(const PIString & name, const char value, bool write) {
|
||||
setValue(name, PIString(1, value), "s", write);}
|
||||
void PIConfig::setValue(const PIString & name, const short value, bool write) {
|
||||
setValue(name, itos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const int value, bool write) {
|
||||
setValue(name, itos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const long value, bool write) {
|
||||
setValue(name, ltos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const uchar value, bool write) {
|
||||
setValue(name, uitos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const ushort value, bool write) {
|
||||
setValue(name, uitos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const uint value, bool write) {
|
||||
setValue(name, uitos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const ulong value, bool write) {
|
||||
setValue(name, ultos(value), "n", write);}
|
||||
void PIConfig::setValue(const PIString & name, const float value, bool write) {
|
||||
setValue(name, ftos(value), "f", write);}
|
||||
void PIConfig::setValue(const PIString & name, const double value, bool write) {
|
||||
setValue(name, dtos(value), "f", write);}
|
||||
|
||||
|
||||
PIString PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) const {
|
||||
for (uint i = 0; i < settname.size(); i++) {
|
||||
if (settname[i] == vname) {
|
||||
if (exist != 0) *exist = true;
|
||||
return settval[i];
|
||||
PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) {
|
||||
PIStringList tree = vname.split(delim);
|
||||
Entry * ce = &root;
|
||||
piForeachCA (i, tree) {
|
||||
ce = ce->findChild(i);
|
||||
if (ce == 0) {
|
||||
if (exist != 0) *exist = false;
|
||||
empty._name = vname;
|
||||
empty._value = def;
|
||||
empty.delim = delim;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
if (exist != 0) *exist = false;
|
||||
return def;
|
||||
if (exist != 0) *exist = true;
|
||||
return *ce;
|
||||
}
|
||||
|
||||
|
||||
PIConfig::Branch PIConfig::getValues(const PIString & vname) {
|
||||
Branch b;
|
||||
b.delim = delim;
|
||||
piForeachA (i, root._children)
|
||||
if (i->_name.find(vname) >= 0)
|
||||
b << i;
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
void PIConfig::addEntry(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
||||
if (getValue(name)._parent != 0)
|
||||
return;
|
||||
bool toRoot = false;
|
||||
PIStringList tree = name.split(delim);
|
||||
PIString ename = tree.back();
|
||||
tree.pop_back();
|
||||
Entry * te, * ce, * entry = &root;
|
||||
if (tree.isEmpty()) toRoot = true;
|
||||
piForeachA (i, tree) {
|
||||
te = entry->findChild(i);
|
||||
if (te == 0) {
|
||||
ce = new Entry();
|
||||
ce->delim = delim;
|
||||
ce->_tab = entry->_tab;
|
||||
ce->_line = entry->_line;
|
||||
ce->_name = i;
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
entry = ce;
|
||||
} else entry = te;
|
||||
}
|
||||
PIConfig::Branch ch = entry->_children;
|
||||
std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare);
|
||||
te = (entry->isLeaf() ? 0 : ch.back());
|
||||
ce = new Entry();
|
||||
ce->delim = delim;
|
||||
ce->_name = ename;
|
||||
ce->_value = value;
|
||||
ce->_type = type;
|
||||
if (te == 0) {
|
||||
ce->_tab = entry->_tab;
|
||||
if (toRoot) ce->_line = other.size_s() - 1;
|
||||
else ce->_line = entry->_line;
|
||||
} else {
|
||||
ce->_tab = te->_tab;
|
||||
if (toRoot) ce->_line = other.size_s() - 1;
|
||||
else {
|
||||
ch = entry->_parent->_children;
|
||||
std::sort(ch.begin(), ch.end(), PIConfig::Entry::compare);
|
||||
ce->_line = ch.back()->_line + 1;
|
||||
}
|
||||
}
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
other.insert(ce->_line, "");
|
||||
Branch b = allLeaves();
|
||||
bool found = false;
|
||||
for (int i = 0; i < b.size_s(); ++i) {
|
||||
if (found) {
|
||||
b[i]->_line++;
|
||||
continue;
|
||||
}
|
||||
if (b[i] == ce) {
|
||||
found = true;
|
||||
if (i > 0)
|
||||
if (b[i - 1]->_line == b[i]->_line)
|
||||
b[i - 1]->_line++;
|
||||
}
|
||||
}
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::setValue(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
||||
int number = getNumber(name);
|
||||
if (number == -1) {
|
||||
addLine(name, value, type);
|
||||
Entry & e(getValue(name));
|
||||
if (&e == &empty) {
|
||||
addEntry(name, value, type);
|
||||
return;
|
||||
}
|
||||
PIString tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
|
||||
settval[number] = value;
|
||||
all[settlines[number]] = tmp;
|
||||
e._value = value;
|
||||
e._type = type;
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
bool PIConfig::existsValue(const PIString & name) {
|
||||
for (uint i = 0; i < settname.size(); i++)
|
||||
if (settname[i] == name) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::addLine(const PIString & name, const PIString & value, const PIString & type) {
|
||||
if (setttab.size() > 0) *this << setttab[setttab.size() - 1] << name << " = " << value << " #" << type << "\n";
|
||||
else *this << name << " = " << value << " #" << type << "\n";
|
||||
settname.push_back(name);
|
||||
settval.push_back(value);
|
||||
settcom.push_back("");
|
||||
setttype.push_back(type);
|
||||
if (setttab.size() > 0) setttab.push_back(setttab[setttab.size() - 1]);
|
||||
else setttab.push_back("\t");
|
||||
settlines.push_back(all.size());
|
||||
all.push_back(name + " = " + value + " #" + type);
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::insertLine(uint number, const PIString & name, const PIString & value, const PIString & type) {
|
||||
if (number >= settname.size()) {
|
||||
addLine(name, value, type);
|
||||
return;
|
||||
int PIConfig::entryIndex(const PIString & name) {
|
||||
PIStringList tree = name.split(delim);
|
||||
Entry * ce = &root;
|
||||
piForeachCA (i, tree) {
|
||||
ce = ce->findChild(i);
|
||||
if (ce == 0)
|
||||
return -1;
|
||||
}
|
||||
settname.insert(number, name);
|
||||
settval.insert(number, value);
|
||||
settcom.insert(number, "");
|
||||
setttab.insert(number, setttab[number]);
|
||||
setttype.insert(number, type);
|
||||
settlines.insert(number, settlines[number]);
|
||||
for (uint i = number + 1; i < settlines.size(); i++) settlines[i]++;
|
||||
all.insert(settlines[number], name + " = " + value + " #" + type);
|
||||
flush();
|
||||
writeAll();
|
||||
}
|
||||
|
||||
|
||||
int PIConfig::getNumber(const PIString & name) {
|
||||
for (uint i = 0; i < settname.size(); i++)
|
||||
if (settname[i] == name)
|
||||
return i;
|
||||
return -1;
|
||||
Branch b = allLeaves();
|
||||
return allLeaves().indexOf(ce);
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::setValue(uint number, const PIString & value, bool write) {
|
||||
PIString tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
|
||||
settval[number] = value;
|
||||
all[settlines[number]] = tmp;
|
||||
Entry & e(entryByIndex(number));
|
||||
if (&e == &empty) return;
|
||||
e._value = value;
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::setName(uint number, const PIString & name) {
|
||||
PIString tmp = name + " = " + settval[number] + " #" + setttype[number] + " " + settcom[number];
|
||||
settname[number] = name;
|
||||
all[settlines[number]] = tmp;
|
||||
writeAll();
|
||||
void PIConfig::setName(uint number, const PIString & name, bool write) {
|
||||
Entry & e(entryByIndex(number));
|
||||
if (&e == &empty) return;
|
||||
e._name = name;
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::setType(uint number, const PIString & type) {
|
||||
PIString tmp = settname[number] + " = " + settval[number] + " #" + type + " " + settcom[number];
|
||||
setttype[number] = type;
|
||||
all[settlines[number]] = tmp;
|
||||
writeAll();
|
||||
void PIConfig::setType(uint number, const PIString & type, bool write) {
|
||||
Entry & e(entryByIndex(number));
|
||||
if (&e == &empty) return;
|
||||
e._type = type;
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::setComment(uint number, const PIString & comment) {
|
||||
PIString tmp = settname[number] + " = " + settval[number] + " #" + setttype[number] + " " + comment;
|
||||
settcom[number] = comment;
|
||||
all[settlines[number]] = tmp;
|
||||
writeAll();
|
||||
void PIConfig::setComment(uint number, const PIString & comment, bool write) {
|
||||
Entry & e(entryByIndex(number));
|
||||
if (&e == &empty) return;
|
||||
e._comment = comment;
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::deleteLine(const PIString & name) {
|
||||
bool exist = false;
|
||||
uint i;
|
||||
for (i = 0; i < settname.size(); i++) {
|
||||
if (settname[i] == name) {
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
void PIConfig::removeEntry(const PIString & name, bool write) {
|
||||
Entry & e(getValue(name));
|
||||
if (&e == &empty) return;
|
||||
Branch b = allLeaves();
|
||||
removeEntry(b, &e);
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::removeEntry(uint number, bool write) {
|
||||
Entry & e(entryByIndex(number));
|
||||
if (&e == &empty) return;
|
||||
Branch b = allLeaves();
|
||||
removeEntry(b, &e);
|
||||
if (write) writeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
||||
bool leaf = true;
|
||||
if (!e->isLeaf() && !e->_value.isEmpty()) {
|
||||
e->_value.clear();
|
||||
leaf = false;
|
||||
} else {
|
||||
int cc = e->_children.size_s();
|
||||
piForTimes (cc)
|
||||
removeEntry(b, e->_children.back());
|
||||
}
|
||||
if (!exist) return;
|
||||
deleteLine(i);
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::deleteLine(uint number) {
|
||||
settname.erase(settname.begin() + number);
|
||||
settval.erase(settval.begin() + number);
|
||||
settcom.erase(settcom.begin() + number);
|
||||
setttab.erase(setttab.begin() + number);
|
||||
setttype.erase(setttype.begin() + number);
|
||||
all.erase(all.begin() + settlines[number]);
|
||||
for (uint i = number; i < settlines.size(); i++) settlines[i]--;
|
||||
settlines.erase(settlines.begin() + number);
|
||||
writeAll();
|
||||
bool found = false;
|
||||
for (int i = 0; i < b.size_s(); ++i) {
|
||||
if (found) {
|
||||
b[i]->_line--;
|
||||
continue;
|
||||
}
|
||||
if (b[i] == e) found = true;
|
||||
}
|
||||
if (!leaf) return;
|
||||
e->_parent->_children.remove(e);
|
||||
b.remove(e);
|
||||
other.remove(e->_line);
|
||||
delete e;
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::writeAll() {
|
||||
clear();
|
||||
uint c = 0;
|
||||
for (uint i = 0; i < all.size() - 1; i++) {
|
||||
if (c < settlines.size() && c < setttab.size()) {
|
||||
if (settlines[c] == i) {
|
||||
*this << setttab[c];
|
||||
c++;
|
||||
//writeEntry(&root);
|
||||
buildFullNames(&root);
|
||||
Branch b = allLeaves();
|
||||
int j = 0;
|
||||
for (int i = 0; i < other.size_s(); ++i) {
|
||||
//cout << j << endl;
|
||||
if (j >= 0 && j < b.size_s()) {
|
||||
if (b[j]->_line == i) {
|
||||
b[j]->buildLine();
|
||||
*this << b[j]->_all << '\n';
|
||||
++j;
|
||||
} else {
|
||||
*this << other[i];
|
||||
if (i < other.size_s() - 1) *this << '\n';
|
||||
}
|
||||
} else {
|
||||
*this << other[i];
|
||||
if (i < other.size_s() - 1) *this << '\n';
|
||||
}
|
||||
*this << all[i] << "\n";
|
||||
}
|
||||
flush();
|
||||
readAll();
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::readAll() {
|
||||
settname.clear();
|
||||
settval.clear();
|
||||
settcom.clear();
|
||||
setttab.clear();
|
||||
settlines.clear();
|
||||
setttype.clear();
|
||||
all.clear();
|
||||
root.clear();
|
||||
flush();
|
||||
parse();
|
||||
}
|
||||
|
||||
|
||||
bool PIConfig::entryExists(const Entry * e, const PIString & name) const {
|
||||
if (e->_children.isEmpty()) {
|
||||
if (e->_name == name) return true;
|
||||
else return false;
|
||||
}
|
||||
piForeachCA (i, e->_children)
|
||||
if (entryExists(i, name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIConfig::parse() {
|
||||
PIString str, tab, comm;
|
||||
PIString src, str, tab, comm, all, name, type;
|
||||
PIStringList tree;
|
||||
Entry * entry, * te, * ce;
|
||||
int ind, sind;
|
||||
bool isNew;
|
||||
if (!isOpened()) return;
|
||||
seek(0);
|
||||
lines = 0;
|
||||
seekToBegin();
|
||||
other.clear();
|
||||
lines = centry = 0;
|
||||
while (!isEnd()) {
|
||||
str = readLine();
|
||||
other.push_back(PIString());
|
||||
src = str = readLine();
|
||||
//cout << str << endl;
|
||||
tab = str.left(str.find(str.trimmed().left(1)));
|
||||
str.trim();
|
||||
all.push_back(str);
|
||||
all = str;
|
||||
ind = str.find('=');
|
||||
if ((ind > 0) && !(str[0] == '#')) {
|
||||
sind = str.find('#');
|
||||
if (sind > 0) {
|
||||
comm = str.right(str.size() - sind - 1).trimmed();
|
||||
if (comm.length() > 0) setttype.push_back(comm[0]);
|
||||
else setttype.push_back("s");
|
||||
comm = comm.right(comm.size() - 1).trimmed();
|
||||
settcom.push_back(comm);
|
||||
comm = str.right(str.length() - sind - 1).trimmed();
|
||||
if (comm.length() > 0) type = comm[0];
|
||||
else type = "s";
|
||||
comm = comm.right(comm.length() - 1).trimmed();
|
||||
str = str.left(sind);
|
||||
} else {
|
||||
setttype.push_back("s");
|
||||
settcom.push_back("");
|
||||
type = "s";
|
||||
comm = "";
|
||||
}
|
||||
settname.push_back(str.left(ind).trimmed());
|
||||
settval.push_back(str.right(str.size() - ind - 1).trimmed());
|
||||
setttab.push_back(tab);
|
||||
settlines.push_back(lines);
|
||||
}
|
||||
//name = str.left(ind).trimmed();
|
||||
tree = str.left(ind).trimmed().split(delim);
|
||||
name = tree.back();
|
||||
tree.pop_back();
|
||||
entry = &root;
|
||||
piForeachA (i, tree) {
|
||||
te = entry->findChild(i);
|
||||
if (te == 0) {
|
||||
ce = new Entry();
|
||||
ce->delim = delim;
|
||||
ce->_tab = tab;
|
||||
ce->_line = lines;
|
||||
ce->_name = i;
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
entry = ce;
|
||||
} else entry = te;
|
||||
}
|
||||
isNew = false;
|
||||
ce = entry->findChild(name);
|
||||
if (ce == 0) {
|
||||
ce = new Entry();
|
||||
isNew = true;
|
||||
}
|
||||
ce->delim = delim;
|
||||
ce->_tab = tab;
|
||||
ce->_name = name;
|
||||
ce->_value = str.right(str.length() - ind - 1).trimmed();
|
||||
ce->_type = type;
|
||||
ce->_comment = comm;
|
||||
ce->_line = lines;
|
||||
ce->_all = all;
|
||||
if (isNew) {
|
||||
ce->_parent = entry;
|
||||
entry->_children << ce;
|
||||
}
|
||||
} else other.back() = src;
|
||||
lines++;
|
||||
}
|
||||
setEntryDelim(&root, delim);
|
||||
}
|
||||
|
||||
235
piconfig.h
235
piconfig.h
@@ -3,72 +3,205 @@
|
||||
|
||||
#include "pifile.h"
|
||||
|
||||
#define PICONFIG_GET_VALUE \
|
||||
inline Entry & getValue(const PIString & vname, const char * def, bool * exist = 0) {return getValue(vname, PIString(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const PIStringList & def, bool * exist = 0) {return getValue(vname, def.join("%|%"), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const bool def, bool * exist = 0) {return getValue(vname, PIString::fromBool(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const short def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const int def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const long def, bool * exist = 0) {return getValue(vname, ltos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const uchar def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const ushort def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const uint def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const ulong def, bool * exist = 0) {return getValue(vname, ultos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const float def, bool * exist = 0) {return getValue(vname, ftos(def), exist);} \
|
||||
inline Entry & getValue(const PIString & vname, const double def, bool * exist = 0) {return getValue(vname, dtos(def), exist);}
|
||||
|
||||
class PIConfig: public PIFile
|
||||
{
|
||||
friend class Entry;
|
||||
friend class Branch;
|
||||
public:
|
||||
PIConfig(const PIString & path, Flags<Mode> mode = Read | Write);
|
||||
PIConfig(const PIString & path, PIFlags<Mode> mode = Read | Write);
|
||||
~PIConfig() {;}
|
||||
|
||||
class Entry;
|
||||
|
||||
class Branch: public PIVector<Entry * > {
|
||||
friend class PIConfig;
|
||||
friend class Entry;
|
||||
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
||||
public:
|
||||
inline Branch() {;}
|
||||
|
||||
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0);
|
||||
PICONFIG_GET_VALUE
|
||||
|
||||
Branch allLeaves();
|
||||
Branch getValues(const PIString & name);
|
||||
Branch getLeaves();
|
||||
Branch getBranches();
|
||||
Branch & filter(const PIString & f);
|
||||
inline bool isEntryExists(const PIString & name) const {piForeachCA (i, *this) if (entryExists(i, name)) return true; return false;}
|
||||
inline int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
|
||||
|
||||
inline void clear() {piForeachA (i, *this) delete i; PIVector<Entry * >::clear();}
|
||||
|
||||
private:
|
||||
bool entryExists(const Entry * e, const PIString & name) const;
|
||||
inline void allLeaves(Branch & b, Entry * e) {piForeachCA (i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}}
|
||||
inline void coutt(std::ostream & s, const PIString & p) const {piForeachCA (i, *this) i->coutt(s, p);}
|
||||
|
||||
static Entry _empty;
|
||||
PIString delim;
|
||||
|
||||
};
|
||||
|
||||
class Entry {
|
||||
friend class PIConfig;
|
||||
friend class Branch;
|
||||
public:
|
||||
inline Entry() {_parent = 0;}
|
||||
|
||||
inline Entry * parent() const {return _parent;}
|
||||
inline int childCount() {return _children.size_s();}
|
||||
inline Branch & children() {_children.delim = delim; return _children;}
|
||||
inline Entry * child(const int index) const {return _children[index];}
|
||||
inline Entry * findChild(const PIString & name) {piForeachCA (i, _children) if (i->_name == name) return i; return 0;}
|
||||
inline const Entry * findChild(const PIString & name) const {piForeachCA (i, _children) if (i->_name == name) return i; return 0;}
|
||||
inline bool isLeaf() const {return _children.isEmpty();}
|
||||
|
||||
inline const PIString & name() const {return _name;}
|
||||
inline const PIString & value() const {return _value;}
|
||||
inline const PIString & type() const {return _type;}
|
||||
inline const PIString & comment() const {return _comment;}
|
||||
|
||||
inline Entry & setName(const PIString & value) {_name = value; return *this;}
|
||||
inline Entry & setType(const PIString & value) {_type = value; return *this;}
|
||||
inline Entry & setComment(const PIString & value) {_comment = value; return *this;}
|
||||
inline Entry & setValue(const PIString & value) {_value = value; return *this;}
|
||||
inline Entry & setValue(const PIStringList & value) {setValue(value.join("%|%")); setType("l"); return *this;}
|
||||
inline Entry & setValue(const char * value) {setValue(PIString(value)); setType("s"); return *this;}
|
||||
inline Entry & setValue(const bool value) {setValue(btos(value)); setType("b"); return *this;}
|
||||
inline Entry & setValue(const char value) {setValue(PIString(1, value)); setType("s"); return *this;}
|
||||
inline Entry & setValue(const short value) {setValue(itos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const int value) {setValue(itos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const long value) {setValue(ltos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const uchar value) {setValue(uitos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const ushort value) {setValue(uitos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const uint value) {setValue(uitos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const ulong value) {setValue(ultos(value)); setType("n"); return *this;}
|
||||
inline Entry & setValue(const float value) {setValue(ftos(value)); setType("f"); return *this;}
|
||||
inline Entry & setValue(const double value) {setValue(dtos(value)); setType("f"); return *this;}
|
||||
|
||||
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0);
|
||||
PICONFIG_GET_VALUE
|
||||
|
||||
Branch getValues(const PIString & vname);
|
||||
|
||||
inline bool isEntryExists(const PIString & name) const {return entryExists(this, name);}
|
||||
|
||||
operator bool() {return _value.toBool();}
|
||||
operator char() {return (_value.isEmpty() ? 0 : _value[0].toAscii());}
|
||||
operator short() {return _value.toShort();}
|
||||
operator int() {return _value.toInt();}
|
||||
operator long() {return _value.toLong();}
|
||||
operator uchar() {return _value.toInt();}
|
||||
operator ushort() {return _value.toShort();}
|
||||
operator uint() {return _value.toInt();}
|
||||
operator ulong() {return _value.toLong();}
|
||||
operator float() {return _value.toFloat();}
|
||||
operator double() {return _value.toDouble();}
|
||||
operator PIString() {return _value;}
|
||||
operator PIStringList() {return _value.split("%|%");}
|
||||
|
||||
private:
|
||||
inline static bool compare(const PIConfig::Entry * f, const PIConfig::Entry * s) {return f->_line < s->_line;}
|
||||
bool entryExists(const Entry * e, const PIString & name) const;
|
||||
inline void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
|
||||
inline void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
|
||||
inline void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachCA (i, _children) i->coutt(s, nl);}
|
||||
|
||||
static Entry _empty;
|
||||
Entry * _parent;
|
||||
Branch _children;
|
||||
PIString _tab;
|
||||
PIString _name;
|
||||
PIString _value;
|
||||
PIString _type;
|
||||
PIString _comment;
|
||||
PIString _all;
|
||||
PIString _full_name;
|
||||
PIString delim;
|
||||
int _line;
|
||||
};
|
||||
|
||||
PIString getValue(const PIString & vname, const PIString & def = "", bool * exist = 0) const;
|
||||
PIString getValue(const PIString & vname, const char * def = "", bool * exist = 0) const {return getValue(vname, PIString(def), exist);}
|
||||
PIStringList getValue(const PIString & vname, const PIStringList & def = PIStringList(), bool * exist = 0) const;
|
||||
bool getValue(const PIString & vname, const bool def = false, bool * exist = 0) const;
|
||||
char getValue(const PIString & vname, const char def = 0, bool * exist = 0) const;
|
||||
short getValue(const PIString & vname, const short def = 0, bool * exist = 0) const;
|
||||
int getValue(const PIString & vname, const int def = 0, bool * exist = 0) const;
|
||||
long getValue(const PIString & vname, const long def = 0, bool * exist = 0) const;
|
||||
uchar getValue(const PIString & vname, const uchar def = 0, bool * exist = 0) const;
|
||||
ushort getValue(const PIString & vname, const ushort def = 0, bool * exist = 0) const;
|
||||
uint getValue(const PIString & vname, const uint def = 0, bool * exist = 0) const;
|
||||
ulong getValue(const PIString & vname, const ulong def = 0, bool * exist = 0) const;
|
||||
float getValue(const PIString & vname, const float def = 0., bool * exist = 0) const;
|
||||
double getValue(const PIString & vname, const double def = 0., bool * exist = 0) const;
|
||||
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0);
|
||||
PICONFIG_GET_VALUE
|
||||
|
||||
Branch getValues(const PIString & vname);
|
||||
|
||||
void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
|
||||
void setValue(const PIString & name, const PIStringList & value, bool write = true);
|
||||
void setValue(const PIString & name, const char * value, bool write = true);
|
||||
void setValue(const PIString & name, const bool value, bool write = true);
|
||||
void setValue(const PIString & name, const char value, bool write = true);
|
||||
void setValue(const PIString & name, const short value, bool write = true);
|
||||
void setValue(const PIString & name, const int value, bool write = true);
|
||||
void setValue(const PIString & name, const long value, bool write = true);
|
||||
void setValue(const PIString & name, const uchar value, bool write = true);
|
||||
void setValue(const PIString & name, const ushort value, bool write = true);
|
||||
void setValue(const PIString & name, const uint value, bool write = true);
|
||||
void setValue(const PIString & name, const ulong value, bool write = true);
|
||||
void setValue(const PIString & name, const float value, bool write = true);
|
||||
void setValue(const PIString & name, const double value, bool write = true);
|
||||
inline void setValue(const PIString & name, const PIStringList & value, bool write = true) {setValue(name, value.join("%|%"), "l", write);}
|
||||
inline void setValue(const PIString & name, const char * value, bool write = true) {setValue(name, PIString(value), "s", write);}
|
||||
inline void setValue(const PIString & name, const bool value, bool write = true) {setValue(name, btos(value), "b", write);}
|
||||
inline void setValue(const PIString & name, const short value, bool write = true) {setValue(name, itos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const int value, bool write = true) {setValue(name, itos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const long value, bool write = true) {setValue(name, ltos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const uchar value, bool write = true) {setValue(name, uitos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const ushort value, bool write = true) {setValue(name, uitos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const uint value, bool write = true) {setValue(name, uitos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const ulong value, bool write = true) {setValue(name, ultos(value), "n", write);}
|
||||
inline void setValue(const PIString & name, const float value, bool write = true) {setValue(name, ftos(value), "f", write);}
|
||||
inline void setValue(const PIString & name, const double value, bool write = true) {setValue(name, dtos(value), "f", write);}
|
||||
|
||||
PIString getValue(uint number) const {return settval[number];}
|
||||
PIString getName(uint number) const {return settname[number];}
|
||||
PIString getComment(uint number) const {return settcom[number];}
|
||||
inline Entry & rootEntry() {return root;}
|
||||
inline int entriesCount() const {return childCount(&root);}
|
||||
inline bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
|
||||
|
||||
inline Branch allTree() {Branch b; piForeachCA (i, root._children) b << i; return b;}
|
||||
inline Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;}
|
||||
int entryIndex(const PIString & name);
|
||||
|
||||
inline PIString getName(uint number) {return entryByIndex(number)._name;}
|
||||
inline PIString getValue(uint number) {return entryByIndex(number)._value;}
|
||||
inline PIChar getType(uint number) {return entryByIndex(number)._type[0];}
|
||||
inline PIString getComment(uint number) {return entryByIndex(number)._comment;}
|
||||
|
||||
void addEntry(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
|
||||
void setName(uint number, const PIString & name, bool write = true);
|
||||
void setValue(uint number, const PIString & value, bool write = true);
|
||||
bool existsValue(const PIString & name);
|
||||
char getType(uint number) const {return setttype[number][0];}
|
||||
int getNumber(const PIString & name);
|
||||
void setName(uint number, const PIString & name);
|
||||
void setType(uint number, const PIString & type);
|
||||
void setComment(uint number, const PIString & comment);
|
||||
int numValues() const {return settval.size();}
|
||||
void addLine(const PIString & name, const PIString & value, const PIString & type = "s");
|
||||
void insertLine(uint number, const PIString & name, const PIString & value, const PIString & type = "s");
|
||||
void deleteLine(const PIString & name);
|
||||
void deleteLine(uint number);
|
||||
void setType(uint number, const PIString & type, bool write = true);
|
||||
void setComment(uint number, const PIString & comment, bool write = true);
|
||||
|
||||
void removeEntry(const PIString & name, bool write = true);
|
||||
void removeEntry(uint number, bool write = true);
|
||||
|
||||
void readAll();
|
||||
void writeAll();
|
||||
|
||||
const PIString & delimiter() const {return delim;}
|
||||
void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();}
|
||||
|
||||
private:
|
||||
int childCount(const Entry * e) const {int c = 0; piForeachCA (i, e->_children) c += childCount(i); c += e->_children.size_s(); return c;}
|
||||
bool entryExists(const Entry * e, const PIString & name) const;
|
||||
void buildFullNames(Entry * e) {piForeachCA (i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}}
|
||||
void allLeaves(Branch & b, Entry * e) {piForeachCA (i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}}
|
||||
void setEntryDelim(Entry * e, const PIString & d) {piForeachCA (i, e->_children) setEntryDelim(i, d); e->delim = d;}
|
||||
inline Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);}
|
||||
void removeEntry(Branch & b, Entry * e);
|
||||
void parse();
|
||||
|
||||
PIVector<PIString> settname;
|
||||
PIVector<PIString> settval;
|
||||
PIVector<PIString> settcom;
|
||||
PIVector<PIString> setttab;
|
||||
PIVector<PIString> setttype;
|
||||
PIVector<PIString> all;
|
||||
PIVector<uint> settlines;
|
||||
|
||||
int centry;
|
||||
PIString delim;
|
||||
Entry root, empty;
|
||||
uint lines;
|
||||
|
||||
PIStringList other;
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v) {v.coutt(s, ""); return s;}
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v) {s << v.value(); return s;}
|
||||
|
||||
#endif // PICONFIG_H
|
||||
|
||||
254
piconsole.cpp
254
piconsole.cpp
@@ -6,7 +6,7 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
||||
needLockRun(true);
|
||||
ret_func = slot;
|
||||
num_format = 0;
|
||||
cur_tab = width = height = my = 0;
|
||||
cur_tab = width = height = pwidth = pheight = my = 0;
|
||||
#ifdef WINDOWS
|
||||
ulcoord.X = ulcoord.Y = 0;
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
@@ -17,29 +17,25 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
||||
GetConsoleMode(hOut, &smode);
|
||||
GetConsoleCursorInfo(hOut, &curinfo);
|
||||
#endif
|
||||
addTab(PIString("main"));
|
||||
addTab("main");
|
||||
listener = new PIKbdListener(key_event, this);
|
||||
if (startNow) start(40);
|
||||
if (startNow) start();
|
||||
}
|
||||
|
||||
|
||||
PIConsole::~PIConsole() {
|
||||
if (isRunning()) {
|
||||
if (isRunning())
|
||||
stop();
|
||||
waitForFinish();
|
||||
moveTo(0, my + 4);
|
||||
showCursor();
|
||||
}
|
||||
delete listener;
|
||||
clearTabs(false);
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hOut, smode);
|
||||
SetConsoleTextAttribute(hOut, dattr);
|
||||
#endif
|
||||
delete listener;
|
||||
}
|
||||
|
||||
|
||||
int PIConsole::addTab(PIString name, char bind_key) {
|
||||
int PIConsole::addTab(const PIString & name, char bind_key) {
|
||||
tabs.push_back(Tab(name, bind_key));
|
||||
cur_tab = tabs.size() - 1;
|
||||
return tabs.size();
|
||||
@@ -53,7 +49,7 @@ void PIConsole::removeTab(uint index) {
|
||||
}
|
||||
|
||||
|
||||
void PIConsole::removeTab(PIString name) {
|
||||
void PIConsole::removeTab(const PIString & name) {
|
||||
uint index = tabs.size() + 1;
|
||||
for (uint i = 0; i < tabs.size(); ++i) {
|
||||
if (tabs[i].name == name) {
|
||||
@@ -66,7 +62,7 @@ void PIConsole::removeTab(PIString name) {
|
||||
|
||||
|
||||
bool PIConsole::setTab(uint index) {
|
||||
if (index >= tabs.size() || index < 0)
|
||||
if (index >= tabs.size())
|
||||
return false;
|
||||
cur_tab = index;
|
||||
if (!isRunning()) return true;
|
||||
@@ -78,7 +74,7 @@ bool PIConsole::setTab(uint index) {
|
||||
}
|
||||
|
||||
|
||||
bool PIConsole::setTab(PIString name) {
|
||||
bool PIConsole::setTab(const PIString & name) {
|
||||
uint index = tabs.size() + 1;
|
||||
for (uint i = 0; i < tabs.size(); ++i) {
|
||||
if (tabs[i].name == name) {
|
||||
@@ -91,14 +87,14 @@ bool PIConsole::setTab(PIString name) {
|
||||
|
||||
|
||||
bool PIConsole::setTabBindKey(uint index, char bind_key) {
|
||||
if (index < 0 || index >= tabs.size())
|
||||
if (index >= tabs.size())
|
||||
return false;
|
||||
tabs[index].key = bind_key;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIConsole::setTabBindKey(PIString name, char bind_key) {
|
||||
bool PIConsole::setTabBindKey(const PIString & name, char bind_key) {
|
||||
uint index =tabs.size() + 1;
|
||||
for (uint i = 0; i < tabs.size(); ++i) {
|
||||
if (tabs[i].name == name) {
|
||||
@@ -122,15 +118,28 @@ void PIConsole::key_event(char key, void * t) {
|
||||
}
|
||||
|
||||
|
||||
PIString PIConsole::fstr(Flags<PIConsole::Format> f) {
|
||||
void PIConsole::stop(bool clear) {
|
||||
PIThread::stop(true);
|
||||
if (clear) clearScreen();
|
||||
moveTo(0, my + 4);
|
||||
showCursor();
|
||||
couts(fstr(Normal).stdString());
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hOut, smode);
|
||||
SetConsoleTextAttribute(hOut, dattr);
|
||||
#endif
|
||||
fflush(0);
|
||||
}
|
||||
|
||||
|
||||
PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
||||
if (f[PIConsole::Dec]) num_format = 0;
|
||||
if (f[PIConsole::Hex]) num_format = 1;
|
||||
|
||||
if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Scientific]) num_format = 3;
|
||||
|
||||
#ifdef WINDOWS
|
||||
WORD attr = dattr;
|
||||
WORD attr = 0;
|
||||
|
||||
if (f[PIConsole::Inverse]) {
|
||||
if (f[PIConsole::Red]) attr |= BACKGROUND_RED;
|
||||
@@ -140,7 +149,13 @@ if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
|
||||
if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::BackRed]) attr |= FOREGROUND_RED;
|
||||
if (f[PIConsole::BackGreen]) attr |= FOREGROUND_GREEN;
|
||||
if (f[PIConsole::BackBlue]) attr |= FOREGROUND_BLUE;
|
||||
if (f[PIConsole::BackYellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
if (f[PIConsole::BackMagenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::BackCyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::BackWhite]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
} else {
|
||||
if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
|
||||
if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN;
|
||||
@@ -149,6 +164,13 @@ if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
if (f[PIConsole::BackRed]) attr |= BACKGROUND_RED;
|
||||
if (f[PIConsole::BackGreen]) attr |= BACKGROUND_GREEN;
|
||||
if (f[PIConsole::BackBlue]) attr |= BACKGROUND_BLUE;
|
||||
if (f[PIConsole::BackYellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN);
|
||||
if (f[PIConsole::BackMagenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
|
||||
if (f[PIConsole::BackCyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
if (f[PIConsole::BackWhite]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
}
|
||||
if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY;
|
||||
|
||||
@@ -172,7 +194,16 @@ if (f[PIConsole::Oct]) num_format = 2;
|
||||
if (f[PIConsole::Magenta]) ts += ";35";
|
||||
if (f[PIConsole::Cyan]) ts += ";36";
|
||||
if (f[PIConsole::White]) ts += ";37";
|
||||
|
||||
|
||||
if (f[PIConsole::BackBlack]) ts += ";40";
|
||||
if (f[PIConsole::BackRed]) ts += ";41";
|
||||
if (f[PIConsole::BackGreen]) ts += ";42";
|
||||
if (f[PIConsole::BackYellow]) ts += ";43";
|
||||
if (f[PIConsole::BackBlue]) ts += ";44";
|
||||
if (f[PIConsole::BackMagenta]) ts += ";45";
|
||||
if (f[PIConsole::BackCyan]) ts += ";46";
|
||||
if (f[PIConsole::BackWhite]) ts += ";47";
|
||||
|
||||
return ts + "m";
|
||||
#endif
|
||||
}
|
||||
@@ -181,6 +212,7 @@ if (f[PIConsole::Oct]) num_format = 2;
|
||||
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%d", x); break;}
|
||||
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;}
|
||||
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Ld", x); break;}
|
||||
#define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
|
||||
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
|
||||
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
|
||||
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;}
|
||||
@@ -196,7 +228,7 @@ inline int PIConsole::couts(const short v) {siprint(v);}
|
||||
inline int PIConsole::couts(const int v) {iprint(v);}
|
||||
inline int PIConsole::couts(const long v) {liprint(v);}
|
||||
inline int PIConsole::couts(const llong v) {lliprint(v);}
|
||||
inline int PIConsole::couts(const uchar v) {uprint(v);}
|
||||
inline int PIConsole::couts(const uchar v) {cuprint(v);}
|
||||
inline int PIConsole::couts(const ushort v) {suprint(v);}
|
||||
inline int PIConsole::couts(const uint v) {uprint(v);}
|
||||
inline int PIConsole::couts(const ulong v) {luprint(v);}
|
||||
@@ -217,7 +249,6 @@ void PIConsole::begin() {
|
||||
|
||||
void PIConsole::run() {
|
||||
uint cx, clen = 0;
|
||||
string ts;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||
@@ -228,19 +259,20 @@ void PIConsole::run() {
|
||||
width = ws.ws_col;
|
||||
height = ws.ws_row;
|
||||
#endif
|
||||
if (pwidth != width || pheight != height) {
|
||||
clearScreen();
|
||||
fillLabels();
|
||||
}
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
col_cnt = vars().size();
|
||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||
for (uint i = 0; i < col_cnt; ++i) {
|
||||
cx = col_wid * i;
|
||||
toUpperLeft();
|
||||
for (uint j = 0; j < vars()[i].size(); ++j) {
|
||||
if (my < j) my = j;
|
||||
tv = vars()[i][j];
|
||||
if (my < vars()[i].size()) my = vars()[i].size();
|
||||
piForeachCA (tv, vars()[i]) {
|
||||
moveRight(cx);
|
||||
if (tv.name.size() == 0) {
|
||||
newLine();
|
||||
continue;
|
||||
}
|
||||
if (tv.type == 0 && tv.s == 0) {
|
||||
newLine();
|
||||
continue;
|
||||
@@ -261,10 +293,10 @@ void PIConsole::run() {
|
||||
case 11: clen = printValue(*tv.uc, tv.format); break;
|
||||
case 12: clen = printValue(*tv.ll, tv.format); break;
|
||||
case 13: clen = printValue(*tv.ull, tv.format); break;
|
||||
case 14: clen = printValue(bitsValue(tv.uc, tv.bitFrom, tv.bitCount), tv.format); break;
|
||||
case 14: clen = printValue(bitsValue(tv.ptr, tv.bitFrom, tv.bitCount), tv.format); break;
|
||||
}
|
||||
if (clen + tv.offset < (uint)col_wid) {
|
||||
ts = PIString(col_wid - clen - tv.offset, ' ').stdString();
|
||||
string ts = PIString(col_wid - clen - tv.offset, ' ').stdString();
|
||||
printf("%s", ts.c_str());
|
||||
}
|
||||
newLine();
|
||||
@@ -275,7 +307,7 @@ void PIConsole::run() {
|
||||
|
||||
|
||||
void PIConsole::fillLabels() {
|
||||
uint cx, my = 0;
|
||||
uint cx, cy, my = 0;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||
@@ -290,27 +322,43 @@ void PIConsole::fillLabels() {
|
||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||
for (uint i = 0; i < col_cnt; ++i) {
|
||||
cx = col_wid * i;
|
||||
cy = 1;
|
||||
toUpperLeft();
|
||||
for (uint j = 0; j < vars()[i].size(); ++j) {
|
||||
if (my < j) my = j;
|
||||
moveRight(cx);
|
||||
tv = vars()[i][j];
|
||||
vars()[i][j].nx = cx;
|
||||
vars()[i][j].ny = cy;
|
||||
if (tv.name.size() == 0) {
|
||||
vars()[i][j].offset = 0;
|
||||
clearLine();
|
||||
newLine();
|
||||
cy++;
|
||||
continue;
|
||||
}
|
||||
clearLine();
|
||||
if (tv.type == 0 && tv.s == 0) {
|
||||
vars()[i][j].offset = vars()[i][j].name.length();
|
||||
vars()[i][j].nx += vars()[i][j].offset;
|
||||
printLine(tv.name, cx, tv.format);
|
||||
newLine();
|
||||
cy++;
|
||||
continue;
|
||||
}
|
||||
vars()[i][j].offset = printValue(tv.name + ": ", tv.format);
|
||||
vars()[i][j].offset = (tv.name + ": ").length();
|
||||
vars()[i][j].nx += vars()[i][j].offset;
|
||||
printValue(tv.name + ": ", tv.format);
|
||||
newLine();
|
||||
cy++;
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
moveTo(0, my + 1);
|
||||
#else
|
||||
moveTo(0, my + 2);
|
||||
if (tabs[cur_tab].status.length() > 0) {
|
||||
#endif
|
||||
if (!tabs[cur_tab].status.isEmpty()) {
|
||||
printValue(tabs[cur_tab].status);
|
||||
newLine();
|
||||
}
|
||||
@@ -325,24 +373,24 @@ void PIConsole::status() {
|
||||
for (uint i = 0; i < tabsCount(); ++i) {
|
||||
ctab = &tabs[i];
|
||||
if (ctab->key == 0) continue;
|
||||
printValue(ctab->key, PIConsole::Bold);
|
||||
printValue(ctab->key, PIConsole::White | PIConsole::Bold);
|
||||
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
||||
printValue(PIString(" "), PIConsole::Normal);
|
||||
printValue(" ");
|
||||
}
|
||||
newLine();
|
||||
}
|
||||
|
||||
|
||||
int PIConsole::bitsValue(unsigned char * src, int offset, int count) {
|
||||
int PIConsole::bitsValue(void * src, int offset, int count) {
|
||||
int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8;
|
||||
char cbyte = src[stbyte];
|
||||
char cbyte = reinterpret_cast<char * >(src)[stbyte];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret |= ((cbyte >> cbit & 1) << i);
|
||||
cbit++;
|
||||
if (cbit == 8) {
|
||||
cbit = 0;
|
||||
stbyte++;
|
||||
cbyte = src[stbyte];
|
||||
cbyte = reinterpret_cast<char * >(src)[stbyte];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -350,77 +398,109 @@ int PIConsole::bitsValue(unsigned char * src, int offset, int count) {
|
||||
|
||||
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column);
|
||||
|
||||
void PIConsole::addString(PIString name, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addString(const PIString & name, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, PIString* ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, PIString* ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, bool * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, bool * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, int * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, int * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, long * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, long * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, char * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, char * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, float * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, float * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, double * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, double * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, short * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, short * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, uint * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, uint * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, ulong * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, ulong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, ushort * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, ushort * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, uchar * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, uchar * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, llong * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, llong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addVariable(PIString name, ullong * ptr, int column, Flags<PIConsole::Format> format) {
|
||||
void PIConsole::addVariable(const PIString & name, ullong * ptr, int column, PIFlags<PIConsole::Format> format) {
|
||||
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addBitVariable(PIString name, uchar * ptr, int fromBit, int bitCount, int column, Flags<PIConsole::Format> format) {
|
||||
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.uc = ptr; tv.format = format;
|
||||
void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column, PIFlags<PIConsole::Format> format) {
|
||||
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format;
|
||||
checkColumn(column); vars()[column - 1].push_back(tv);}
|
||||
void PIConsole::addEmptyLine(int column) {
|
||||
void PIConsole::addEmptyLine(int column, uint count) {
|
||||
tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal;
|
||||
checkColumn(column); vars()[column - 1].push_back(tv);}
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
checkColumn(column);
|
||||
vars()[column - 1].push_back(tv);
|
||||
}
|
||||
}
|
||||
|
||||
#define PRINT_VAR_BODY couts(fstr(format).stdString()); int ret = couts(value); fstr(PIConsole::Dec); return ret;
|
||||
|
||||
inline void PIConsole::printLine(const PIString & value, int dx, Flags<PIConsole::Format> format) {
|
||||
PIString PIConsole::getString(int x, int y) {
|
||||
bool run = isRunning();
|
||||
if (run) PIThread::stop(true);
|
||||
listener->terminate();
|
||||
msleep(10);
|
||||
listener->setActive(false);
|
||||
moveTo(x, y);
|
||||
showCursor();
|
||||
PIByteArray ba(4096);
|
||||
fflush(0);
|
||||
scanf("%s", ba.data());
|
||||
//fflush(0);
|
||||
listener->start();
|
||||
msleep(10);
|
||||
if (run) start();
|
||||
msleep(10);
|
||||
listener->setActive(true);
|
||||
return PIString(ba);
|
||||
}
|
||||
|
||||
|
||||
PIString PIConsole::getString(const PIString & name) {
|
||||
piForeachCA (i, tabs[cur_tab].variables)
|
||||
piForeachCA (j, i)
|
||||
if (j.name == name)
|
||||
return getString(j.nx + 1, j.ny);
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
#define PRINT_VAR_BODY couts(fstr(format).stdString()); int ret = couts(value); couts(fstr(PIConsole::Dec).stdString()); return ret;
|
||||
|
||||
inline void PIConsole::printLine(const PIString & value, int dx, PIFlags<PIConsole::Format> format) {
|
||||
int i = width - value.length() - dx;
|
||||
#ifdef QNX
|
||||
--i;
|
||||
#endif
|
||||
string ts = fstr(format).stdString();
|
||||
couts(ts);
|
||||
if (i >= 0) ts = (value + PIString(i, ' ')).stdString();
|
||||
else ts = value.left(value.size() + i).stdString();
|
||||
couts(ts);
|
||||
ts = fstr(Dec).stdString();
|
||||
couts(ts);
|
||||
PIString ts = fstr(format);
|
||||
couts(ts.stdString());
|
||||
if (i >= 0) ts = value + PIString(i, ' ');
|
||||
else ts = value.left(value.size() + i);
|
||||
couts(ts.stdString());
|
||||
couts(fstr(Dec).stdString());
|
||||
}
|
||||
inline int PIConsole::printValue(const PIString & value, Flags<PIConsole::Format> format) {
|
||||
string ts = fstr(format).stdString();
|
||||
couts(ts);
|
||||
ts = value.stdString();
|
||||
int ret = couts(ts);
|
||||
inline int PIConsole::printValue(const PIString & value, PIFlags<PIConsole::Format> format) {
|
||||
couts(fstr(format).stdString());
|
||||
int ret = couts(value.stdString());
|
||||
fstr(PIConsole::Dec);
|
||||
return ret;
|
||||
}
|
||||
inline int PIConsole::printValue(const char * value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const bool value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const int value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const long value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const llong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const float value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const double value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const char value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const short value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const uchar value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ushort value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const uint value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ulong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ullong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const char * value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const bool value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const int value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const long value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const llong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const float value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const double value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const char value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const short value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const uchar value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ushort value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const uint value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ulong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
inline int PIConsole::printValue(const ullong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||
|
||||
146
piconsole.h
146
piconsole.h
@@ -29,42 +29,73 @@ public:
|
||||
Magenta = 0x2000,
|
||||
Cyan = 0x4000,
|
||||
White = 0x8000,
|
||||
Dec = 0x10000,
|
||||
Hex = 0x20000,
|
||||
Oct = 0x40000,
|
||||
Scientific = 0x80000};
|
||||
BackBlack = 0x10000,
|
||||
BackRed = 0x20000,
|
||||
BackGreen = 0x40000,
|
||||
BackYellow = 0x80000,
|
||||
BackBlue = 0x100000,
|
||||
BackMagenta = 0x200000,
|
||||
BackCyan = 0x400000,
|
||||
BackWhite = 0x800000,
|
||||
Dec = 0x1000000,
|
||||
Hex = 0x2000000,
|
||||
Oct = 0x4000000,
|
||||
Scientific = 0x8000000};
|
||||
|
||||
void addString(PIString name, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, PIString * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, char * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, bool * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, short * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, int * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, long * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, llong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, uchar * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, ushort * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, uint * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, ulong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, ullong * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, float * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(PIString name, double * ptr, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addBitVariable(PIString name, uchar * ptr, int fromBit, int bitCount, int column = 1, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addEmptyLine(int column = 1);
|
||||
int addTab(PIString name, char bind_key = 0);
|
||||
void removeTab(uint index);
|
||||
void removeTab(PIString name);
|
||||
void addString(const PIString & name, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, PIString * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, char * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, bool * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, short * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, int * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, long * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, llong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, uchar * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ushort * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, uint * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ulong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, ullong * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, float * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addVariable(const PIString & name, double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
void addEmptyLine(int column = 1, uint count = 1);
|
||||
|
||||
PIString getString(int x, int y);
|
||||
short getShort(int x, int y) {return getString(x, y).toShort();}
|
||||
int getInt(int x, int y) {return getString(x, y).toInt();}
|
||||
float getFloat(int x, int y) {return getString(x, y).toFloat();}
|
||||
double getDouble(int x, int y) {return getString(x, y).toDouble();}
|
||||
PIString getString(const PIString & name);
|
||||
short getShort(const PIString & name) {return getString(name).toShort();}
|
||||
int getInt(const PIString & name) {return getString(name).toInt();}
|
||||
float getFloat(const PIString & name) {return getString(name).toFloat();}
|
||||
double getDouble(const PIString & name) {return getString(name).toDouble();}
|
||||
|
||||
uint tabsCount() const {return tabs.size();}
|
||||
bool setTab(uint index);
|
||||
bool setTab(PIString name);
|
||||
bool setTabBindKey(uint index, char bind_key);
|
||||
bool setTabBindKey(PIString name, char bind_key);
|
||||
void addCustomStatus(PIString str) {tabs[cur_tab].status = str;}
|
||||
void clearCustomStatus() {tabs[cur_tab].status = "";}
|
||||
void clearVariables(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();}
|
||||
void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();}
|
||||
PIString fstr(Flags<PIConsole::Format> f);
|
||||
PIString currentTab() const {return tabs[cur_tab].name;}
|
||||
int addTab(const PIString & name, char bind_key = 0);
|
||||
void removeTab(uint index);
|
||||
void removeTab(const PIString & name);
|
||||
bool setTab(uint index);
|
||||
bool setTab(const PIString & name);
|
||||
bool setTabBindKey(uint index, char bind_key);
|
||||
bool setTabBindKey(const PIString & name, char bind_key);
|
||||
void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();}
|
||||
|
||||
void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;}
|
||||
void clearCustomStatus() {tabs[cur_tab].status.clear();}
|
||||
|
||||
void clearVariables(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();}
|
||||
|
||||
inline void waitForFinish() {WAIT_FOR_EXIT}
|
||||
inline void start() {PIThread::start(40);}
|
||||
void stop(bool clear = false);
|
||||
PIString fstr(PIFlags<PIConsole::Format> f);
|
||||
|
||||
inline void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);}
|
||||
inline void disableExitCapture() {listener->disableExitCapture();}
|
||||
inline bool exitCaptured() const {return listener->exitCaptured();}
|
||||
inline char exitKey() const {return listener->exitKey();}
|
||||
|
||||
private:
|
||||
void begin();
|
||||
@@ -101,28 +132,30 @@ private:
|
||||
#endif
|
||||
void status();
|
||||
void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}}
|
||||
int bitsValue(unsigned char * src, int offset, int count);
|
||||
inline void printLine(const PIString & str, int dx = 0, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const PIString & str, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const char * str, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const bool value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const int value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const long value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const llong value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const float value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const double value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const char value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const short value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const uchar value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ushort value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const uint value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ulong value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ullong value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
||||
int bitsValue(void * src, int offset, int count);
|
||||
inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const char * str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const bool value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const int value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const long value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const llong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const float value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const double value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const char value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const short value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const uchar value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ushort value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const uint value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ulong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
inline int printValue(const ullong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||
static void key_event(char key, void * t);
|
||||
|
||||
struct Variable {
|
||||
PIString name;
|
||||
Flags<PIConsole::Format> format;
|
||||
PIFlags<PIConsole::Format> format;
|
||||
int nx;
|
||||
int ny;
|
||||
int type;
|
||||
int offset;
|
||||
int bitFrom;
|
||||
@@ -142,13 +175,14 @@ private:
|
||||
uint * ui;
|
||||
ulong * ul;
|
||||
ullong * ull;
|
||||
void * ptr;
|
||||
};
|
||||
void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset;
|
||||
bitFrom = src.bitFrom; bitCount = src.bitCount; c = src.c;}
|
||||
bitFrom = src.bitFrom; bitCount = src.bitCount; c = src.c; nx = src.nx; ny = src.ny;}
|
||||
};
|
||||
|
||||
struct Tab {
|
||||
vector<vector<Variable> > variables;
|
||||
PIVector<PIVector<Variable> > variables;
|
||||
PIString name;
|
||||
PIString status;
|
||||
char key;
|
||||
@@ -156,7 +190,7 @@ private:
|
||||
Tab(PIString n, char k) {name = n; key = k;}
|
||||
};
|
||||
|
||||
inline vector<vector<Variable> > & vars() {return tabs[cur_tab].variables;}
|
||||
inline PIVector<PIVector<Variable> > & vars() {return tabs[cur_tab].variables;}
|
||||
inline int couts(const string v);
|
||||
inline int couts(const char * v);
|
||||
inline int couts(const bool v);
|
||||
@@ -183,11 +217,11 @@ private:
|
||||
#else
|
||||
struct termios sterm, vterm;
|
||||
#endif
|
||||
vector<Tab> tabs;
|
||||
PIVector<Tab> tabs;
|
||||
Variable tv;
|
||||
PIKbdListener * listener;
|
||||
KBFunc ret_func;
|
||||
int width, height, ret, col_wid, num_format;
|
||||
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
||||
uint my;
|
||||
uint cur_tab, col_cnt;
|
||||
|
||||
|
||||
226
picontainers.h
Normal file
226
picontainers.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#ifndef PICONTAINERS_H
|
||||
#define PICONTAINERS_H
|
||||
|
||||
#include "piincludes.h"
|
||||
|
||||
template<typename Type>
|
||||
class _PIForeachC {
|
||||
public:
|
||||
_PIForeachC(const Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;}
|
||||
typename Type::value_type _var;
|
||||
typename Type::const_iterator _it;
|
||||
typename Type::const_reverse_iterator _rit;
|
||||
const Type & _t;
|
||||
bool _break, _inv;
|
||||
inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
|
||||
inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
class _PIForeach {
|
||||
public:
|
||||
_PIForeach(Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;}
|
||||
typename Type::value_type _var;
|
||||
typename Type::iterator _it;
|
||||
typename Type::reverse_iterator _rit;
|
||||
Type & _t;
|
||||
bool _break, _inv;
|
||||
inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
|
||||
inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;}
|
||||
};
|
||||
|
||||
#define piForTimes(c) for(int i = 0; i < c; ++i)
|
||||
|
||||
#define piForeach(i,c) for(_PIForeach<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(i = *_for._it; !_for._break; _for._break = true)
|
||||
#define piForeachR(i,c) for(_PIForeach<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(i = *_for._rit; !_for._break; _for._break = true)
|
||||
#define piForeachA(i,c) for(_PIForeach<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
|
||||
#define piForeachAR(i,c) for(_PIForeach<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
|
||||
#define piForeachC(i,c) for(_PIForeachC<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(const i = *_for._it; !_for._break; _for._break = true)
|
||||
#define piForeachCR(i,c) for(_PIForeachC<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(const i = *_for._rit; !_for._break; _for._break = true)
|
||||
#define piForeachCA(i,c) for(_PIForeachC<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
|
||||
#define piForeachCAR(i,c) for(_PIForeachC<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
|
||||
|
||||
#define piForeachRA piForeachAR
|
||||
#define piForeachRC piForeachCR
|
||||
#define piForeachAC piForeachCA
|
||||
#define piForeachCRA piForeachCAR
|
||||
#define piForeachARC piForeachCAR
|
||||
#define piForeachACR piForeachCAR
|
||||
#define piForeachRCA piForeachCAR
|
||||
#define piForeachRAC piForeachCAR
|
||||
|
||||
template<typename Enum>
|
||||
class PIFlags {
|
||||
public:
|
||||
inline PIFlags(): flags(0) {;}
|
||||
inline PIFlags(Enum e): flags(e) {;}
|
||||
inline PIFlags(const PIFlags & f): flags(f.flags) {;}
|
||||
inline PIFlags(const int i): flags(i) {;}
|
||||
inline void operator =(const PIFlags & f) {flags = f.flags;}
|
||||
inline void operator =(const Enum & e) {flags = e;}
|
||||
inline void operator =(const int & i) {flags = i;}
|
||||
inline void operator |=(const PIFlags & f) {flags = flags | f.flags;}
|
||||
inline void operator |=(const Enum & e) {flags = flags | e;}
|
||||
inline void operator |=(const int i) {flags = flags | i;}
|
||||
inline void operator &=(const PIFlags & f) {flags = flags & f.flags;}
|
||||
inline void operator &=(const Enum & e) {flags = flags & e;}
|
||||
inline void operator &=(const int i) {flags = flags & i;}
|
||||
inline PIFlags & operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
||||
inline PIFlags & operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
||||
inline PIFlags & operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
||||
inline PIFlags & operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
||||
inline PIFlags & operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
||||
inline PIFlags & operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
||||
inline bool operator [](Enum e) {return (flags & e) == e;}
|
||||
inline operator int() const {return flags;}
|
||||
private:
|
||||
int flags;
|
||||
};
|
||||
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIVector: public vector<Type, Allocator> {
|
||||
typedef PIVector<Type, Allocator> _CVector;
|
||||
typedef vector<Type, Allocator> _stlc;
|
||||
public:
|
||||
inline PIVector() {;}
|
||||
inline PIVector(const Type & value) {_stlc::push_back(value);}
|
||||
inline PIVector(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||
inline PIVector(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||
inline PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||
inline PIVector(uint size, const Type & value = Type()) {_stlc::resize(size, value);}
|
||||
inline const Type & at(uint index) const {return (*this)[index];}
|
||||
inline Type & at(uint index) {return (*this)[index];}
|
||||
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
inline bool isEmpty() const {return _stlc::empty();}
|
||||
inline _CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||
inline _CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||
inline _CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||
inline _CVector & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
inline _CVector & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
inline _CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
||||
inline _CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||
inline _CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||
inline bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIVector<Type> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIList: public list<Type, Allocator> {
|
||||
typedef PIList<Type, Allocator> _CList;
|
||||
typedef list<Type, Allocator> _stlc;
|
||||
public:
|
||||
inline PIList() {;}
|
||||
inline PIList(const Type & value) {_stlc::resize(1, value);}
|
||||
inline PIList(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||
inline PIList(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||
inline PIList(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||
inline PIList(uint size, const Type & value = Type()) {_stlc::resize(size, value);}
|
||||
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
inline bool isEmpty() const {return _stlc::empty();}
|
||||
inline _CList & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||
inline _CList & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
inline _CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
inline _CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||
inline _CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
|
||||
class PISet: public set<Type, Compare, Allocator> {
|
||||
typedef PISet<Type, Compare, Allocator> _CSet;
|
||||
typedef set<Type, Compare, Allocator> _stlc;
|
||||
public:
|
||||
inline PISet() {;}
|
||||
inline PISet(const Type & value) {_stlc::resize(1, value);}
|
||||
inline PISet(const Type & v0, const Type & v1) {_stlc::insert(v0); _stlc::insert(v1);}
|
||||
inline PISet(const Type & v0, const Type & v1, const Type & v2) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2);}
|
||||
inline PISet(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2); _stlc::insert(v3);}
|
||||
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
inline bool isEmpty() const {return _stlc::empty();}
|
||||
inline _CSet & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||
inline _CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||
inline _CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
||||
inline bool operator [](const Type & t) {return _stlc::find(t);}
|
||||
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
class PIStack: public PIVector<Type> {
|
||||
typedef PIStack<Type> _CStack;
|
||||
public:
|
||||
inline PIStack() {;}
|
||||
inline PIStack(const Type & value) {_CStack::resize(1, value);}
|
||||
inline PIStack(const Type & v0, const Type & v1) {_CStack::push_back(v0); _CStack::push_back(v1);}
|
||||
inline PIStack(const Type & v0, const Type & v1, const Type & v2) {_CStack::push_back(v0); _CStack::push_back(v1); _CStack::push_back(v2);}
|
||||
inline PIStack(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_CStack::push_back(v0); _CStack::push_back(v1); _CStack::push_back(v2); _CStack::push_back(v3);}
|
||||
inline _CStack & push(const Type & v) {_CStack::push_back(v); return *this;}
|
||||
inline Type pop() {Type t = Type(); if (_CStack::size() == 0) return t; t = _CStack::back(); _CStack::pop_back(); return t;}
|
||||
inline Type & top() {return _CStack::back();}
|
||||
inline const Type & top() const {return _CStack::back();}
|
||||
inline PIVector<Type> toVector() {PIVector<Type> v; for (typename _CStack::const_iterator i = _CStack::begin(); i != _CStack::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIDeque: public deque<Type, Allocator> {
|
||||
typedef PIDeque<Type, Allocator> _CDeque;
|
||||
typedef deque<Type, Allocator> _stlc;
|
||||
public:
|
||||
inline PIDeque() {;}
|
||||
inline PIDeque(const Type & value) {_stlc::resize(1, value);}
|
||||
inline PIDeque(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||
inline PIDeque(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||
inline PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||
inline bool isEmpty() const {return _stlc::empty();}
|
||||
inline _CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
||||
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
class PIQueue: public PIDeque<Type> {
|
||||
typedef PIQueue<Type> _CQueue;
|
||||
public:
|
||||
inline PIQueue() {;}
|
||||
inline PIQueue(const Type & value) {_CQueue::resize(1, value);}
|
||||
inline PIQueue(const Type & v0, const Type & v1) {_CQueue::push_front(v0); _CQueue::push_front(v1);}
|
||||
inline PIQueue(const Type & v0, const Type & v1, const Type & v2) {_CQueue::push_front(v0); _CQueue::push_front(v1); _CQueue::push_front(v2);}
|
||||
inline PIQueue(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_CQueue::push_front(v0); _CQueue::push_front(v1); _CQueue::push_front(v2); _CQueue::push_front(v3);}
|
||||
inline _CQueue & enqueue(const Type & v) {_CQueue::push_front(v); return *this;}
|
||||
inline Type dequeue() {Type t = Type(); if (_CQueue::size() == 0) return t; t = _CQueue::back(); _CQueue::pop_back(); return t;}
|
||||
inline Type & head() {return _CQueue::back();}
|
||||
inline const Type & head() const {return _CQueue::back();}
|
||||
inline PIVector<Type> toVector() {PIVector<Type> v; for (typename _CQueue::const_iterator i = _CQueue::begin(); i != _CQueue::end(); ++i) v << *i; return v;}
|
||||
};
|
||||
|
||||
|
||||
template<typename Type0, typename Type1>
|
||||
class PIPair {
|
||||
public:
|
||||
inline PIPair() {first = Type0(); second = Type1();}
|
||||
inline PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||
Type0 first;
|
||||
Type1 second;
|
||||
};
|
||||
template<typename Type0, typename Type1>
|
||||
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
||||
|
||||
|
||||
template<typename Type, typename Key = int>
|
||||
class PIHash: public PISet<PIPair<Key, Type> > {
|
||||
typedef PIHash<Type, Key> _CHash;
|
||||
typedef PISet<PIPair<Key, Type> > _CSet;
|
||||
public:
|
||||
inline PIHash() {;}
|
||||
inline PIHash(const Type & value, const Key & key) {insert(value, key);}
|
||||
inline _CHash & insert(const Type & value, const Key & key) {_CSet::insert(PIPair<Key, Type>(key, value));}
|
||||
inline Type value(Key key) {piForeachCA (i, *this) if (i.first == key) return i.second;; return Key();}
|
||||
inline Type operator[](Key key) {return value(key);}
|
||||
};
|
||||
|
||||
#endif // PICONTAINERS_H
|
||||
142
pidir.cpp
142
pidir.cpp
@@ -1,5 +1,19 @@
|
||||
#include "pidir.h"
|
||||
|
||||
#ifndef WINDOWS
|
||||
#ifdef WINDOWS
|
||||
const PIChar PIDir::separator = '\\';
|
||||
#else
|
||||
const PIChar PIDir::separator = '/';
|
||||
#endif
|
||||
|
||||
|
||||
PIDir::PIDir() {
|
||||
path_ = PIDir::current().path_;
|
||||
dir_ = 0;
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
PIDir::PIDir(const PIString & dir) {
|
||||
path_ = dir.stdString();
|
||||
@@ -8,7 +22,7 @@ PIDir::PIDir(const PIString & dir) {
|
||||
}
|
||||
|
||||
|
||||
bool PIDir::operator==(const PIDir & d) const {
|
||||
bool PIDir::operator ==(const PIDir & d) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,7 +31,7 @@ bool PIDir::open() {
|
||||
if (dir_ != 0)
|
||||
if (!close())
|
||||
return false;
|
||||
dir_ = opendir(path_.c_str());
|
||||
dir_ = opendir(path_.data());
|
||||
return (dir_ != 0);
|
||||
}
|
||||
|
||||
@@ -38,6 +52,118 @@ PIString PIDir::absolutePath() {
|
||||
}
|
||||
|
||||
|
||||
PIDir & PIDir::cleanPath() {
|
||||
PIString p(path_);
|
||||
if (p.size() == 0) {
|
||||
path_ = ".";
|
||||
open();
|
||||
return *this;
|
||||
}
|
||||
bool isAbs = isAbsolute();
|
||||
for (uint i = p.size() - 1; i > 0; --i) {
|
||||
if (p[i] == separator && p[i - 1] == separator) {
|
||||
p.cutLeft(i);
|
||||
isAbs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PIStringList l = PIString(p).split(separator);
|
||||
l.removeStrings(".");
|
||||
l.removeStrings("");
|
||||
bool found = true;
|
||||
while (found) {
|
||||
found = false;
|
||||
for (uint i = 0; i < l.size() - 1; ++i) {
|
||||
if (l.size() < 2) break;
|
||||
if (l[i] != ".." && l[i + 1] == "..") {
|
||||
if (l.size() + i > 2) l.remove(i, 2);
|
||||
else l.remove(i, 1);
|
||||
--i;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
while (found) {
|
||||
found = false;
|
||||
if (l.size() > 0) if (l[0] == "..")
|
||||
{l.pop_front(); found = true;}
|
||||
}
|
||||
path_ = separator + l.join(separator);
|
||||
if (!isAbs) path_.insert(0, ".");
|
||||
if (path_.size() == 0) path_ = "./";
|
||||
open();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIDir & PIDir::cd(const PIString & path) {
|
||||
if (path_.size() == 0) return *this;
|
||||
if (path_[path_.size() - 1] == separator) path_ << path;
|
||||
else path_ << separator << path;
|
||||
return cleanPath();
|
||||
}
|
||||
|
||||
|
||||
bool PIDir::mkDir(bool withParents) {
|
||||
PIDir d = cleanedPath();
|
||||
string p = d.path_;
|
||||
PIString tp;
|
||||
int ret;
|
||||
bool isAbs = isAbsolute();
|
||||
if (withParents) {
|
||||
PIStringList l = PIString(p).split(separator);
|
||||
for (int i = l.size_s() - 1; i >= 0; --i) {
|
||||
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
|
||||
else {
|
||||
tp = separator;
|
||||
if (!isAbs) tp.push_front('.');
|
||||
}
|
||||
//cout << tp << endl;
|
||||
if (isExists(tp)) {
|
||||
for (int j = i + 1; j <= l.size_s(); ++j) {
|
||||
tp = PIStringList(l).remove(j, l.size_s() - j).join(separator);
|
||||
//cout << tp << endl;
|
||||
p = tp.stdString();
|
||||
ret = mkdir(p.c_str(), 16877);
|
||||
if (ret == 0) continue;
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
ret = mkdir(p.c_str(), 16877);
|
||||
if (ret == 0) return true;
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stat((p + separator + list[i]->d_name).data(), &fs);
|
||||
l.push_back(DirEntry(list[i]->d_name, fs.st_mode, fs.st_size));
|
||||
delete list[i];
|
||||
}
|
||||
delete list;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIDir PIDir::current() {
|
||||
char rc[1024];
|
||||
if (getcwd(rc, 1024) == 0) return PIString();
|
||||
@@ -58,12 +184,10 @@ PIDir PIDir::temporary() {
|
||||
}
|
||||
|
||||
|
||||
bool PIDir::mkDir(const PIString & path) {
|
||||
string s = path.stdString();
|
||||
int ret = mkdir(s.c_str(), 16877);
|
||||
if (ret == 0) return true;
|
||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
||||
return false;
|
||||
bool PIDir::mkDir(const PIString & path, bool withParents) {
|
||||
PIDir d(path);
|
||||
if (d.isExists()) return true;
|
||||
return d.mkDir(withParents);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,3 +198,5 @@ bool PIDir::rmDir(const PIString & path) {
|
||||
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
42
pidir.h
42
pidir.h
@@ -2,41 +2,67 @@
|
||||
#define PIDIR_H
|
||||
|
||||
#include "pifile.h"
|
||||
#ifndef WINDOWS
|
||||
#include <sys/dir.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
class PIDir
|
||||
{
|
||||
public:
|
||||
PIDir() {dir_ = 0;}
|
||||
PIDir();
|
||||
PIDir(const PIString & dir);
|
||||
~PIDir() {close();}
|
||||
|
||||
struct DirEntry {
|
||||
DirEntry() {;}
|
||||
DirEntry(const PIString & name_, const int & mode_, const int & size_) {
|
||||
name = name_; mode = mode_; size = size_;}
|
||||
|
||||
PIString name;
|
||||
int mode;
|
||||
int size;
|
||||
|
||||
bool isDir() const {return (mode & S_IFDIR);}
|
||||
bool isFile() const {return (mode & S_IFREG);}
|
||||
bool isSymLink() const {return (mode & S_IFLNK);}
|
||||
bool isBlkDevice() const {return (mode & S_IFBLK);}
|
||||
bool isChrDevice() const {return (mode & S_IFCHR);}
|
||||
bool isSocket() const {return (mode & S_IFSOCK);}
|
||||
};
|
||||
|
||||
inline const bool isExists() {return (dir_ != 0);}
|
||||
inline const bool isAbsolute() {if (path_.size() == 0) return false; return (path_[0] == separator);}
|
||||
inline PIString path() {return PIString(path_);}
|
||||
PIDir & cleanPath();
|
||||
inline PIDir cleanedPath() {PIDir d(path_); d.cleanPath(); return d;}
|
||||
PIString absolutePath();
|
||||
bool mkDir(bool withParents = true);
|
||||
PIVector<DirEntry> entries();
|
||||
|
||||
PIDir & cd(const PIString & path);
|
||||
inline PIDir & up() {return cd("..");}
|
||||
|
||||
bool operator ==(const PIDir & d) const;
|
||||
|
||||
#ifdef WINDOWS
|
||||
static const char separator = '\\';
|
||||
#else
|
||||
static const char separator = '/';
|
||||
#endif
|
||||
static const PIChar separator;
|
||||
|
||||
static PIDir current();
|
||||
static PIDir home();
|
||||
static PIDir temporary();
|
||||
static bool mkDir(const PIString & path);
|
||||
static bool mkDir(const PIString & path, bool withParents = true);
|
||||
static bool rmDir(const PIString & path);
|
||||
static bool isExists(const PIString & path) {return PIDir(path).isExists();}
|
||||
//static bool rmDir(const PIString & path);
|
||||
|
||||
private:
|
||||
bool open();
|
||||
bool close();
|
||||
|
||||
string path_;
|
||||
PIString path_;
|
||||
|
||||
DIR * dir_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // PIDIR_H
|
||||
|
||||
@@ -8,7 +8,8 @@ PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot):
|
||||
port_ = port_s = port;
|
||||
sock = sock_s = -1;
|
||||
ret_func = slot;
|
||||
buffer = new char[BUFFER_SIZE];
|
||||
tries = 0;
|
||||
//buffer_ = new char[BUFFER_SIZE];
|
||||
#ifdef WINDOWS
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
@@ -22,26 +23,36 @@ PIEthernet::~PIEthernet() {
|
||||
#ifdef WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
delete buffer;
|
||||
if (sock != -1) {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
sock = -1;
|
||||
}
|
||||
if (sock_s != -1) {
|
||||
shutdown(sock_s, SHUT_RDWR);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock_s);
|
||||
#else
|
||||
close(sock_s);
|
||||
#endif
|
||||
sock_s = -1;
|
||||
}
|
||||
//if (buffer_ != 0) delete buffer_;
|
||||
//buffer_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::terminate() {
|
||||
if (!initialized()) return;
|
||||
if (!receiverInitialized()) return;
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
pthread_cancel(thread);
|
||||
}
|
||||
tries = 0;
|
||||
/*if (sock != -1) {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
@@ -63,20 +74,20 @@ void PIEthernet::begin() {
|
||||
|
||||
void PIEthernet::run() {
|
||||
#ifdef WINDOWS
|
||||
int addr_len;
|
||||
int addr_len = sizeof(sockaddr_storage);
|
||||
#else
|
||||
socklen_t addr_len;
|
||||
socklen_t addr_len = sizeof(sockaddr_storage);
|
||||
#endif
|
||||
//cout << "[PIEthernet] reading ... ";
|
||||
readed = recvfrom(sock, buffer, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len);
|
||||
//cout << "[PIEthernet] reading from " << &addr_ << endl;
|
||||
readed = recvfrom(sock, buffer_, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len);
|
||||
//cout << WSAGetLastError() << endl;
|
||||
if (readed < 0) {
|
||||
//cout << "[PIEthernet] Error while reading" << endl;
|
||||
cout << "[PIEthernet] Error while reading, " << errorString() << endl;
|
||||
//stop();
|
||||
//init();
|
||||
return;
|
||||
}
|
||||
if (ret_func != 0) ret_func(data, buffer);
|
||||
if (ret_func != 0) ret_func(data, buffer_, readed);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +97,23 @@ void PIEthernet::end() {
|
||||
|
||||
|
||||
bool PIEthernet::init() {
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.stdString().data());
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = PF_INET;
|
||||
addr_.sin_port = htons(port_);
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
||||
cout << "[PIEthernet] Cant`t bind to " << ip_.stdString() << ":" << port_ << endl;
|
||||
if (tries < 10) {
|
||||
if (init()) {
|
||||
tries = 0;
|
||||
return true;
|
||||
} else return false;
|
||||
} else
|
||||
cout << "[PIEthernet] Cant`t bind to " << ip_ << ":" << port_ << ", " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -100,10 +121,20 @@ bool PIEthernet::init() {
|
||||
|
||||
|
||||
bool PIEthernet::initSend() {
|
||||
#ifdef WINDOWS
|
||||
closesocket(sock_s);
|
||||
#else
|
||||
close(sock_s);
|
||||
#endif
|
||||
sock_s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sock_s == -1) {
|
||||
cout << "[PIEthernet] Unable to create socket" << endl;
|
||||
if (tries < 10) {
|
||||
if (init()) {
|
||||
tries = 0;
|
||||
return true;
|
||||
} else return false;
|
||||
} else
|
||||
cout << "[PIEthernet] Unable to create socket, " << errorString() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -116,7 +147,7 @@ bool PIEthernet::send(PIString ip, int port, char * data, int size) {
|
||||
return false;
|
||||
}
|
||||
saddr_.sin_port = htons(port);
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip.stdString().data());
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip.data());
|
||||
saddr_.sin_family = PF_INET;
|
||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
if (wrote != size) {
|
||||
@@ -134,7 +165,7 @@ bool PIEthernet::send(char * data, int size) {
|
||||
return false;
|
||||
}
|
||||
saddr_.sin_port = htons(port_s);
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip_s.stdString().data());
|
||||
saddr_.sin_addr.s_addr = inet_addr(ip_s.data());
|
||||
saddr_.sin_family = PF_INET;
|
||||
//cout << "[PIEthernet] sending in " << sock_s << endl;
|
||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||
|
||||
24
piethernet.h
24
piethernet.h
@@ -4,22 +4,22 @@
|
||||
#include "pithread.h"
|
||||
#include "pistring.h"
|
||||
#ifndef WINDOWS
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# define SHUT_RDWR SD_BOTH
|
||||
# include <winsock2.h>
|
||||
# define SHUT_RDWR SD_BOTH
|
||||
#endif
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
typedef bool (*EthernetFunc)(void * , char * );
|
||||
typedef bool (*EthernetFunc)(void * , char * , int );
|
||||
|
||||
class PIEthernet: public PIThread
|
||||
{
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, char*)"
|
||||
// slot is any function format "bool <func>(void*, char*, int)"
|
||||
PIEthernet(PIString ip = "", int port = 0, void * data = 0, EthernetFunc slot = 0);
|
||||
~PIEthernet();
|
||||
|
||||
@@ -32,22 +32,22 @@ public:
|
||||
bool send(char * data, int size);
|
||||
bool init();
|
||||
bool initSend();
|
||||
bool initialized() const {return sock != -1;}
|
||||
bool receiverInitialized() const {return sock != -1;}
|
||||
bool senderInitialized() const {return sock_s != -1;}
|
||||
void terminate();
|
||||
inline const char * buffer() const {return buffer_;}
|
||||
|
||||
private:
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
|
||||
|
||||
int sock, sock_s, port_, port_s, wrote;
|
||||
int sock, sock_s, port_, port_s, wrote, readed, tries;
|
||||
sockaddr_in addr_, saddr_;
|
||||
PIString ip_, ip_s;
|
||||
EthernetFunc ret_func;
|
||||
char * buffer;
|
||||
void * data;
|
||||
int readed;
|
||||
char buffer_[BUFFER_SIZE];
|
||||
|
||||
};
|
||||
|
||||
|
||||
1033
pievaluator.cpp
Normal file
1033
pievaluator.cpp
Normal file
@@ -0,0 +1,1033 @@
|
||||
#include "pievaluator.h"
|
||||
|
||||
|
||||
PIEvaluatorContent::PIEvaluatorContent() {
|
||||
addFunction("arcsin", 1);
|
||||
addFunction("arccos", 1);
|
||||
addFunction("arctg", 1);
|
||||
addFunction("arcctg", 1);
|
||||
addFunction("random", 2);
|
||||
addFunction("sin", 1);
|
||||
addFunction("cos", 1);
|
||||
addFunction("ctg", 1);
|
||||
addFunction("tg", 1);
|
||||
addFunction("exp", 1);
|
||||
addFunction("cth", 1);
|
||||
addFunction("sh", 1);
|
||||
addFunction("ch", 1);
|
||||
addFunction("th", 1);
|
||||
addFunction("sqrt", 1);
|
||||
addFunction("sqr", 1);
|
||||
addFunction("pow", 2);
|
||||
addFunction("abs", 1);
|
||||
addFunction("ln", 1);
|
||||
addFunction("lg", 1);
|
||||
addFunction("log", 2);
|
||||
addFunction("im", 1);
|
||||
addFunction("re", 1);
|
||||
addFunction("arg", 1);
|
||||
addFunction("len", 1);
|
||||
addFunction("conj", 1);
|
||||
addFunction("sign", 1);
|
||||
addFunction("rad", 1);
|
||||
addFunction("deg", 1);
|
||||
clearCustomVariables();
|
||||
//addVariable("n", 0.);
|
||||
//addVariable("x1", 123);
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluatorContent::setVariableValue(int index, complexd new_value) {
|
||||
if (index < 0 || index >= variables.size_s()) return false;
|
||||
variables[index].value = new_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluatorContent::setVariableName(int index, const PIString & new_name) {
|
||||
if (index < 0 || index >= variables.size_s()) return false;
|
||||
variables[index].name = new_name;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluatorContent::clearCustomVariables() {
|
||||
variables.clear();
|
||||
addVariable("i", complexd_1);
|
||||
addVariable("pi", atan(1.) * 4.);
|
||||
addVariable("e", exp(1.));
|
||||
cv_count = variables.size();
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluatorContent::sortVariables() {
|
||||
PIEvaluatorTypes::Variable tv;
|
||||
for (uint i = 0; i < variables.size(); i++) {
|
||||
for (uint j = variables.size() - 1; j > i; j--) {
|
||||
if (variables[j].name.length() <= variables[i].name.length()) continue;
|
||||
piSwap<PIEvaluatorTypes::Variable>(variables[i], variables[j]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* qDebug() << "---";
|
||||
* for (int i = 0; i < variables.size(); i++) {
|
||||
* qDebug() << variables[i].name;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
PIEvaluatorTypes::BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) {
|
||||
if (name == "sin") return PIEvaluatorTypes::bfSin;
|
||||
if (name == "cos") return PIEvaluatorTypes::bfCos;
|
||||
if (name == "tg") return PIEvaluatorTypes::bfTg;
|
||||
if (name == "ctg") return PIEvaluatorTypes::bfCtg;
|
||||
if (name == "arcsin") return PIEvaluatorTypes::bfArcsin;
|
||||
if (name == "arccos") return PIEvaluatorTypes::bfArccos;
|
||||
if (name == "arctg") return PIEvaluatorTypes::bfArctg;
|
||||
if (name == "arcctg") return PIEvaluatorTypes::bfArcctg;
|
||||
if (name == "exp") return PIEvaluatorTypes::bfExp;
|
||||
if (name == "random") return PIEvaluatorTypes::bfRandom;
|
||||
if (name == "sh") return PIEvaluatorTypes::bfSh;
|
||||
if (name == "ch") return PIEvaluatorTypes::bfCh;
|
||||
if (name == "th") return PIEvaluatorTypes::bfTh;
|
||||
if (name == "cth") return PIEvaluatorTypes::bfCth;
|
||||
if (name == "sqrt") return PIEvaluatorTypes::bfSqrt;
|
||||
if (name == "sqr") return PIEvaluatorTypes::bfSqr;
|
||||
if (name == "pow") return PIEvaluatorTypes::bfPow;
|
||||
if (name == "abs") return PIEvaluatorTypes::bfAbs;
|
||||
if (name == "ln") return PIEvaluatorTypes::bfLn;
|
||||
if (name == "lg") return PIEvaluatorTypes::bfLg;
|
||||
if (name == "log") return PIEvaluatorTypes::bfLog;
|
||||
if (name == "im") return PIEvaluatorTypes::bfIm;
|
||||
if (name == "re") return PIEvaluatorTypes::bfRe;
|
||||
if (name == "arg") return PIEvaluatorTypes::bfArg;
|
||||
if (name == "len") return PIEvaluatorTypes::bfLen;
|
||||
if (name == "conj") return PIEvaluatorTypes::bfConj;
|
||||
if (name == "sign") return PIEvaluatorTypes::bfSign;
|
||||
if (name == "rad") return PIEvaluatorTypes::bfRad;
|
||||
if (name == "deg") return PIEvaluatorTypes::bfDeg;
|
||||
return PIEvaluatorTypes::bfUnknown;
|
||||
}
|
||||
|
||||
const PIString & PIEvaluator::prepare(const PIString & string) {
|
||||
currentString = string.trimmed();
|
||||
if (currentString.isEmpty()) currentString = "0";
|
||||
replaceOperators();
|
||||
removeSpaces();
|
||||
checkBrackets();
|
||||
while (fillElements()) checkBrackets();
|
||||
while (setSignes()) fillElements();
|
||||
removeJunk();
|
||||
findUnknownVariables();
|
||||
return currentString;
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::removeSpaces() {
|
||||
PIString tmps = currentString;
|
||||
for (int i = 0; i < tmps.length(); i++) {
|
||||
if (tmps[i] == ' ' || tmps[i] == '\t') {
|
||||
tmps.remove(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
currentString = tmps;
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::removeJunk() {
|
||||
PIChar cc;
|
||||
bool junk = true;
|
||||
int bcnt;
|
||||
while (junk) {
|
||||
if (currentString.left(1) != "(" || currentString.right(1) != ")") return;
|
||||
bcnt = 1;
|
||||
junk = false;
|
||||
for (int i = 1; i < currentString.length(); i++) {
|
||||
cc = currentString[i];
|
||||
if (cc == '(') bcnt++;
|
||||
if (cc == ')') bcnt--;
|
||||
if (bcnt == 0) {
|
||||
if (i == currentString.length() - 1) {
|
||||
currentString = currentString.mid(1, currentString.length() - 2);
|
||||
elements.pop_front();
|
||||
elements.pop_back();
|
||||
junk = true;
|
||||
break;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::replaceOperators() {
|
||||
currentString.replaceAll("==", "=");
|
||||
currentString.replaceAll("!=", ":");
|
||||
currentString.replaceAll(">=", "}");
|
||||
currentString.replaceAll("<=", "{");
|
||||
currentString.replaceAll("&&", "&");
|
||||
currentString.replaceAll("||", "|");
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::makeOutput(PIString & string) {
|
||||
string.replaceAll(":", "≠");
|
||||
string.replaceAll("}", "≥");
|
||||
string.replaceAll("{", "≤");
|
||||
string.replaceAll("&", "⋀");
|
||||
string.replaceAll("|", "⋁");
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::findUnknownVariables() {
|
||||
PIString cvar;
|
||||
unknownVars.clear();
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
if (elements[i].var_num == -666) cvar += currentString[i];
|
||||
else {
|
||||
if (cvar.length() == 0) continue;
|
||||
unknownVars << cvar;
|
||||
cvar = "";
|
||||
}
|
||||
}
|
||||
if (cvar.length() > 0) unknownVars << cvar;
|
||||
unknownVars.removeDuplicates();
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::isSign(const PIChar & ch) {
|
||||
return ch == '+' || ch == '-' ||
|
||||
ch == '*' || ch == '/' ||
|
||||
ch == '%' || ch == '^' ||
|
||||
ch == '=' || ch == ':' ||
|
||||
ch == '>' || ch == '<' ||
|
||||
ch == '}' || ch == '{' ||
|
||||
ch == '&' || ch == '|';
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::checkBrackets() {
|
||||
PIString tmps = currentString;
|
||||
PIChar fc, sc;
|
||||
int bcnt = 0, bpos = 0, inserted = 0;
|
||||
currentString = tmps;
|
||||
for (int i = 0; i < tmps.length(); i++) {
|
||||
if (tmps[i] == '(') {
|
||||
if (bcnt == 0) bpos = i;
|
||||
bcnt++;
|
||||
}
|
||||
if (tmps[i] == ')') {
|
||||
if (bcnt == 0) {
|
||||
currentString.insert(bpos + inserted, "(");
|
||||
inserted++;
|
||||
} else bcnt--;
|
||||
}
|
||||
}
|
||||
if (bcnt > 0) currentString += PIString(bcnt, ')');
|
||||
tmps = currentString;
|
||||
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||
fc = tmps[i].toLower();
|
||||
sc = tmps[i + 1].toLower();
|
||||
if ((fc == ')' && sc == '(') ||
|
||||
(fc == ')' && sc >= '0' && sc <= '9') ||
|
||||
(fc == ')' && sc >= 'a' && sc <= 'z') ) tmps.insert(++i, '*');
|
||||
}
|
||||
currentString = tmps;
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::fillElements() {
|
||||
int fstart, flen, cnum = 0, cpart = 0, cfunc;
|
||||
PIChar cc, nc, pc, fc = '!';
|
||||
bool numFound = false;
|
||||
PIString curfind, tmps = currentString;
|
||||
elements.resize(tmps.length());
|
||||
for (uint i = 0; i < elements.size(); i++) {
|
||||
elements[i].type = PIEvaluatorTypes::etVariable;
|
||||
elements[i].var_num = -666;
|
||||
}
|
||||
currentVariables.clear();
|
||||
//qDebug().nospace() << "search for functions ...";
|
||||
for (int i = 0; i < content.functionsCount(); i++) {
|
||||
curfind = content.function(i).identifier;
|
||||
cfunc = i; //(int)content.function(i).type;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
while (fstart >= 0) {
|
||||
fstart = tmps.find(curfind, fstart);
|
||||
if (fstart < 0) break;
|
||||
if (tmps[fstart + flen] != '(') {
|
||||
currentString.insert(fstart + flen, "(");
|
||||
return true;
|
||||
}
|
||||
for (int j = fstart; j < fstart + flen; j++) {
|
||||
elements[j].set(PIEvaluatorTypes::etFunction, cnum, cfunc);
|
||||
tmps.replace(j, 1, fc);
|
||||
}
|
||||
cnum++;
|
||||
}
|
||||
}
|
||||
cnum = 0;
|
||||
//qDebug().nospace() << "search for variables ...";
|
||||
for (int i = 0; i < content.variablesCount(); i++) {
|
||||
curfind = content.variable(i).name;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
while (fstart >= 0) {
|
||||
fstart = tmps.find(curfind, fstart);
|
||||
if (fstart < 0) break;
|
||||
for (int j = fstart; j < fstart + flen; j++) {
|
||||
elements[j].set(PIEvaluatorTypes::etVariable, cnum, i);
|
||||
tmps.replace(j, 1, fc);
|
||||
}
|
||||
cnum++;
|
||||
}
|
||||
}
|
||||
curfind = "";
|
||||
cnum = 1;
|
||||
//qDebug().nospace() << "search for numbers ...";
|
||||
for (int i = 0; i < tmps.length(); i++) {
|
||||
cc = tmps[i];
|
||||
/*if (cc == " " || cc == "(" || cc == ")") {
|
||||
curfind = "";
|
||||
cpart = 0;
|
||||
numFound = false;
|
||||
continue;
|
||||
}*/
|
||||
switch (cpart) {
|
||||
case 0:
|
||||
if ((cc >= '0' && cc <= '9')) {// || cc == '-' || cc == '+') {
|
||||
curfind += cc;
|
||||
cpart = 1;
|
||||
continue;
|
||||
}
|
||||
if (cc == '.') {
|
||||
curfind += cc;
|
||||
cpart = 2;
|
||||
continue;
|
||||
}
|
||||
if (cc == 'E') {
|
||||
curfind += cc;
|
||||
cpart = 3;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (cc >= '0' && cc <= '9') {
|
||||
curfind += cc;
|
||||
continue;
|
||||
}
|
||||
if (cc == '.') {
|
||||
curfind += cc;
|
||||
cpart = 2;
|
||||
continue;
|
||||
}
|
||||
if (cc == 'E') {
|
||||
curfind += cc;
|
||||
cpart = 3;
|
||||
continue;
|
||||
}
|
||||
numFound = true;
|
||||
break;
|
||||
case 2:
|
||||
if (cc >= '0' && cc <= '9') {
|
||||
curfind += cc;
|
||||
continue;
|
||||
}
|
||||
if (cc == 'E') {
|
||||
curfind += cc;
|
||||
cpart = 3;
|
||||
continue;
|
||||
}
|
||||
numFound = true;
|
||||
break;
|
||||
case 3:
|
||||
if ((cc >= '0' && cc <= '9') || cc == '-' || cc == '+') {
|
||||
curfind += cc;
|
||||
cpart = 4;
|
||||
continue;
|
||||
}
|
||||
numFound = true;
|
||||
break;
|
||||
case 4:
|
||||
if (cc >= '0' && cc <= '9') {
|
||||
curfind += cc;
|
||||
continue;
|
||||
}
|
||||
numFound = true;
|
||||
break;
|
||||
}
|
||||
if (numFound) {
|
||||
//qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble();
|
||||
currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble()));
|
||||
for (int j = i - curfind.length(); j < i; j++) {
|
||||
elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum);
|
||||
tmps.replace(j, 1, fc);
|
||||
}
|
||||
curfind = "";
|
||||
cnum++;
|
||||
cpart = 0;
|
||||
numFound = false;
|
||||
}
|
||||
}
|
||||
if (cpart > 0) {
|
||||
//qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble();
|
||||
currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble()));
|
||||
for (int j = tmps.length() - curfind.length(); j < tmps.length(); j++) {
|
||||
elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum);
|
||||
tmps.replace(j, 1, fc);
|
||||
}
|
||||
}
|
||||
cc = nc = fc;
|
||||
//qDebug().nospace() << "search for signes ...";
|
||||
for (int i = 0; i < tmps.length(); i++) {
|
||||
cc = tmps[i];
|
||||
if (i > 0) pc = tmps[i - 1];
|
||||
else pc = fc;
|
||||
if (i < tmps.length() - 1) nc = tmps[i + 1];
|
||||
else nc = fc;
|
||||
if (cc == '(' || cc == ')' || cc == ',') {
|
||||
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||
continue;
|
||||
}
|
||||
if (cc == '-' || cc == '+') {
|
||||
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||
if (i < tmps.length() - 1) if (elements[i + 1].type == PIEvaluatorTypes::etVariable ||
|
||||
elements[i + 1].type == PIEvaluatorTypes::etFunction) continue;
|
||||
if ((pc == '(' || isSign(pc) || i == 0) && i < tmps.length() - 1) {
|
||||
if (elements[i + 1].type != PIEvaluatorTypes::etOperator) {
|
||||
cnum = elements[i + 1].num;
|
||||
elements[i].set(PIEvaluatorTypes::etNumber, cnum);
|
||||
tmps.replace(i, 1, fc);
|
||||
///cout << "found sign " << cc << " :" << cnum - 1 << endl;
|
||||
if (cc == '-' && currentVariables.size_s() >= cnum)
|
||||
currentVariables[cnum - 1].value = -currentVariables[cnum - 1].value;
|
||||
//i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isSign(cc)) {
|
||||
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
qDebug().nospace() << tmps;
|
||||
cout << " ";
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
*/
|
||||
return false;
|
||||
//for (int i = 0; i < currentVariables.size(); i++) qDebug() << "var " << i << ": " << currentVariables[i].value.real();
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::setSignes() {
|
||||
int inserted = 0, ni, pi = 0, needInsert = 0;
|
||||
PIChar fc, sc, pc;
|
||||
PIString tmps = currentString;
|
||||
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||
needInsert = 0;
|
||||
ni = i + 1;
|
||||
if (i > 0) pi = i - 1;
|
||||
fc = tmps[i].toLower();
|
||||
sc = tmps[ni].toLower();
|
||||
pc = tmps[pi].toLower();
|
||||
//if (elements[i].type == etOperator || elements[ni].type == etVariable) continue;
|
||||
if (fc == ',' || sc == ',') continue;
|
||||
if (elements[i].type == PIEvaluatorTypes::etOperator && elements[ni].type == PIEvaluatorTypes::etOperator) continue;
|
||||
if (fc == ')' && (elements[ni].type == PIEvaluatorTypes::etNumber || elements[ni].type == PIEvaluatorTypes::etVariable || elements[ni].type == PIEvaluatorTypes::etFunction)) needInsert = 1;
|
||||
if (sc == '(' && (elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable)) needInsert = 1;
|
||||
if (elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etNumber && elements[i].num != elements[ni].num) needInsert = 1;
|
||||
if (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etVariable && elements[i].num != elements[ni].num) needInsert = 1;
|
||||
if ((elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etVariable) || (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etNumber)) needInsert = 1;
|
||||
if ((elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable) && elements[ni].type == PIEvaluatorTypes::etFunction) needInsert = 1;
|
||||
if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type == PIEvaluatorTypes::etFunction && elements[i].num != elements[ni].num) needInsert = 2;
|
||||
if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type != PIEvaluatorTypes::etFunction && sc != '(') needInsert = 2;
|
||||
if (elements[pi].type == PIEvaluatorTypes::etOperator && (elements[ni].type == PIEvaluatorTypes::etFunction || elements[ni].type == PIEvaluatorTypes::etVariable) && fc == '-') needInsert = 3;
|
||||
switch (needInsert) {
|
||||
case 1:
|
||||
currentString.insert(ni + inserted, "*");
|
||||
elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1));
|
||||
//inserted++;
|
||||
//i++;
|
||||
return true;
|
||||
/*case 2:
|
||||
currentString.insert(ni + inserted, ")");
|
||||
currentString.insert(ni + inserted, "(");
|
||||
elements.insert(ni + inserted, Element(etOperator, -1));
|
||||
elements.insert(ni + inserted, Element(etOperator, -1));
|
||||
inserted++;
|
||||
i++;
|
||||
return true;*/
|
||||
case 3:
|
||||
currentString.insert(ni + inserted, "1*");
|
||||
elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1));
|
||||
//inserted;
|
||||
//i++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*if (elements[tmps.length() - 1].type == etFunction) {
|
||||
currentString.insert(tmps.length() + inserted, ")");
|
||||
currentString.insert(tmps.length() + inserted, "(");
|
||||
elements.insert(tmps.length() + inserted, Element(etOperator, -1));
|
||||
elements.insert(tmps.length() + inserted, Element(etOperator, -1));
|
||||
return true;
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluator::convert() {
|
||||
int j;
|
||||
PIEvaluatorTypes::Element ce, pe;
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
pe = elements[i];
|
||||
if (pe.type != PIEvaluatorTypes::etFunction) continue;
|
||||
j = i + 1;
|
||||
while (j < currentString.length()) {
|
||||
ce = elements[j];
|
||||
if (ce != pe) break;
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, " ");
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
//i++;
|
||||
}
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
pe = elements[i];
|
||||
if (pe.type != PIEvaluatorTypes::etNumber) continue;
|
||||
j = i + 1;
|
||||
while (j < currentString.length()) {
|
||||
ce = elements[j];
|
||||
if (ce != pe) break;
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, " ");
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
//i++;
|
||||
}
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
pe = elements[i];
|
||||
if (pe.type != PIEvaluatorTypes::etVariable) continue;
|
||||
j = i + 1;
|
||||
while (j < currentString.length()) {
|
||||
ce = elements[j];
|
||||
if (ce != pe) break;
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, " ");
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
//i++;
|
||||
}
|
||||
/*qDebug().nospace() << currentString;
|
||||
cout << " ";
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
}
|
||||
cout << endl;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
const PIString & PIEvaluator::preprocess(const PIString & string) {
|
||||
static PIString ret;
|
||||
int lind;
|
||||
ret = prepare(string);
|
||||
convert();
|
||||
instructions.clear();
|
||||
//qDebug() << preproc->currentString;
|
||||
variables = currentVariables;
|
||||
lind = parse(currentString);
|
||||
if (instructions.size() == 0) {
|
||||
variables.push_back(PIEvaluatorTypes::Variable());
|
||||
instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oNone, PIVector<int>(1, lind), -variables.size()));
|
||||
}
|
||||
kvars = &(content.variables);
|
||||
/*
|
||||
cout << endl << "variables:" << endl;
|
||||
for (int i = 0; i < variables.size(); i++)
|
||||
cout << i << " value = " << variables[i].value << endl;
|
||||
|
||||
cout << endl << "instructions:" << endl;
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
cout << i << endl;
|
||||
cout << " operation " << instructions[i].operation << endl;
|
||||
cout << " operators: ";
|
||||
for (int j = 0; j < instructions[i].operators.size(); j++)
|
||||
cout << instructions[i].operators[j] << "; ";
|
||||
cout << endl << " function " << instructions[i].function << endl;
|
||||
cout << " out " << instructions[i].out << endl;
|
||||
}
|
||||
*/
|
||||
makeOutput(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIEvaluatorTypes::Operation PIEvaluator::operationInOrder(const int & index) {
|
||||
switch (index) {
|
||||
case 0: return PIEvaluatorTypes::oPower;
|
||||
case 1: return PIEvaluatorTypes::oMultiply;
|
||||
case 2: return PIEvaluatorTypes::oDivide;
|
||||
case 3: return PIEvaluatorTypes::oResidue;
|
||||
case 4: return PIEvaluatorTypes::oAdd;
|
||||
case 5: return PIEvaluatorTypes::oSubtract;
|
||||
case 6: return PIEvaluatorTypes::oEqual;
|
||||
case 7: return PIEvaluatorTypes::oNotEqual;
|
||||
case 8: return PIEvaluatorTypes::oGreaterEqual;
|
||||
case 9: return PIEvaluatorTypes::oSmallerEqual;
|
||||
case 10: return PIEvaluatorTypes::oGreater;
|
||||
case 11: return PIEvaluatorTypes::oSmaller;
|
||||
case 12: return PIEvaluatorTypes::oAnd;
|
||||
case 13: return PIEvaluatorTypes::oOr;
|
||||
default: return PIEvaluatorTypes::oNone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
int slen = string.length(), facnt, farg, bcnt, k;
|
||||
PIChar cc;
|
||||
PIEvaluatorTypes::Element ce;
|
||||
PIEvaluatorTypes::Function cfunc;
|
||||
PIEvaluatorTypes::Operation coper;
|
||||
PIString sbrackets, carg;
|
||||
PIVector<int> args, atmp;
|
||||
PIVector<PIEvaluatorTypes::Operation> opers;
|
||||
|
||||
///qDebug() << "to parse :" + string;
|
||||
///cout << " "; for (int i = 0; i < slen; i++) cout << preproc->elements[i + offset].type; cout << endl;
|
||||
|
||||
for (int i = 0; i < slen; i++) {
|
||||
ce = elements[i + offset];
|
||||
cc = string[i];
|
||||
switch (ce.type) {
|
||||
case PIEvaluatorTypes::etNumber:
|
||||
args.push_back(ce.var_num);
|
||||
continue;
|
||||
case PIEvaluatorTypes::etVariable:
|
||||
args.push_back(ce.var_num);
|
||||
continue;
|
||||
case PIEvaluatorTypes::etFunction:
|
||||
i++;
|
||||
cfunc = content.function(ce.var_num);
|
||||
facnt = cfunc.arguments;
|
||||
atmp.clear();
|
||||
bcnt = farg = 1;
|
||||
///qDebug() << "function: " + cfunc.identifier;
|
||||
//for (int k = 0; k < facnt; k++) {
|
||||
bcnt = 1;
|
||||
carg = "";
|
||||
k = i + 1;
|
||||
//if (string.size_s() <= k || k < 0) return -666;
|
||||
while (bcnt > 0) {
|
||||
//if (k < facnt - 1) fcomma = string.indexOf(',', j);
|
||||
cc = string[k];
|
||||
switch (cc.toAscii()) {
|
||||
case '(': bcnt++; break;
|
||||
case ')':
|
||||
bcnt--;
|
||||
if (bcnt == 0) {
|
||||
///qDebug() << "arument: " << carg;
|
||||
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||
k++;
|
||||
carg = "";
|
||||
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if (bcnt == 1) {
|
||||
///qDebug() << "arument: " << carg;
|
||||
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||
k++;
|
||||
carg = "";
|
||||
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
carg += cc;
|
||||
k++;
|
||||
}
|
||||
i = k - 1;
|
||||
if (farg > 0) {
|
||||
variables.push_back(PIEvaluatorTypes::Variable());
|
||||
farg = -variables.size_s();
|
||||
}
|
||||
instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oFunction, atmp, farg, ce.var_num));
|
||||
args.push_back(farg);
|
||||
//for (int i = 0; i < args.size_s(); i++) cout << preproc->currentVariables[-args[i]].value << endl;
|
||||
//i = j + 1;
|
||||
continue;
|
||||
case PIEvaluatorTypes::etOperator:
|
||||
//qDebug() << "operator: " << cc;
|
||||
if (cc == '(') {
|
||||
sbrackets = inBrackets(string.right(slen - i));
|
||||
args.push_back(parse(sbrackets, i + offset + 1));
|
||||
i += sbrackets.length() + 1;
|
||||
continue;
|
||||
}
|
||||
if (cc == '+') {opers.push_back(PIEvaluatorTypes::oAdd); continue;}
|
||||
if (cc == '-') {opers.push_back(PIEvaluatorTypes::oSubtract); continue;}
|
||||
if (cc == '*') {opers.push_back(PIEvaluatorTypes::oMultiply); continue;}
|
||||
if (cc == '/') {opers.push_back(PIEvaluatorTypes::oDivide); continue;}
|
||||
if (cc == '%') {opers.push_back(PIEvaluatorTypes::oResidue); continue;}
|
||||
if (cc == '^') {opers.push_back(PIEvaluatorTypes::oPower); continue;}
|
||||
if (cc == '=') {opers.push_back(PIEvaluatorTypes::oEqual); continue;}
|
||||
if (cc == ':') {opers.push_back(PIEvaluatorTypes::oNotEqual); continue;}
|
||||
if (cc == '}') {opers.push_back(PIEvaluatorTypes::oGreaterEqual); continue;}
|
||||
if (cc == '{') {opers.push_back(PIEvaluatorTypes::oSmallerEqual); continue;}
|
||||
if (cc == '>') {opers.push_back(PIEvaluatorTypes::oGreater); continue;}
|
||||
if (cc == '<') {opers.push_back(PIEvaluatorTypes::oSmaller); continue;}
|
||||
if (cc == '&') {opers.push_back(PIEvaluatorTypes::oAnd); continue;}
|
||||
if (cc == '|') {opers.push_back(PIEvaluatorTypes::oOr); continue;}
|
||||
}
|
||||
}
|
||||
/*
|
||||
cout << "stack: " << endl << "args: ";
|
||||
for (int i = 0; i < args.size_s(); i++) cout << args[i] << ", ";
|
||||
cout << endl << "opers: ";
|
||||
for (int i = 0; i < opers.size_s(); i++) cout << opers[i] << ", ";
|
||||
*/
|
||||
if (opers.size_s() == 0) {
|
||||
if (args.size_s() > 0) return args.back();
|
||||
else return -666;
|
||||
}
|
||||
for (int i = 0; i < PIEvaluatorTypes::operationCount; i++) {
|
||||
coper = operationInOrder(i);
|
||||
for (int j = 0; j < opers.size_s(); j++) {
|
||||
if (coper == PIEvaluatorTypes::oDivide || coper == PIEvaluatorTypes::oMultiply) {
|
||||
if (opers[j] != PIEvaluatorTypes::oDivide && opers[j] != PIEvaluatorTypes::oMultiply) continue;
|
||||
} else {
|
||||
if (opers[j] != coper) continue;
|
||||
}
|
||||
atmp.clear();
|
||||
if (j < args.size_s() && j >= 0) atmp.push_back(args[j]);
|
||||
else atmp.push_back(-666);
|
||||
if (j + 1 < args.size_s() && j >= -1) atmp.push_back(args[j + 1]);
|
||||
else atmp.push_back(-666);
|
||||
farg = 1;
|
||||
if (atmp[0] < 0) farg = atmp[0];
|
||||
else {
|
||||
if (atmp[1] < 0) farg = atmp[1];
|
||||
else {
|
||||
variables.push_back(PIEvaluatorTypes::Variable());
|
||||
farg = -variables.size_s();
|
||||
}
|
||||
}
|
||||
instructions.push_back(PIEvaluatorTypes::Instruction(opers[j], atmp, farg));
|
||||
if (j >= 0 && j < args.size_s()) {
|
||||
args.remove(j);
|
||||
if (j < args.size_s()) args[j] = farg;
|
||||
}
|
||||
opers.remove(j);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
return instructions.back().out;
|
||||
///cout << endl;
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::check() {
|
||||
PIEvaluatorTypes::Instruction ci;
|
||||
bool error;
|
||||
if (unknownVars.size_s() > 0) {
|
||||
lastError = "Unknown variables: \"" + unknownVars.join("\", \"") + "\"";
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < instructions.size_s(); i++) {
|
||||
error = false;
|
||||
ci = instructions[i];
|
||||
switch (ci.operation) {
|
||||
case PIEvaluatorTypes::oNone: break;
|
||||
case PIEvaluatorTypes::oFunction:
|
||||
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||
if (ci.operators[j] == -666) { //(ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size()) {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ci.operators.size_s() != content.function(ci.function).arguments || error) {
|
||||
lastError = "Invalid arguments count for function \"" + content.function(ci.function).identifier + "\"";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (ci.operators[0] == -666 || ci.operators[1] == -666) error = true;
|
||||
if (ci.operators.size_s() != 2 || error) {
|
||||
lastError = "Invalid arguments count for operation \" " + operationChar(ci.operation) + " \"";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ci.out < -variables.size_s()) {
|
||||
lastError = "Invalid variable index \"" + PIString::fromNumber(ci.out) + "\"";
|
||||
return false;
|
||||
}
|
||||
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||
if (ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size_s()) {
|
||||
lastError = "Invalid variable index \"" + PIString::fromNumber(ci.operators[j]) + "\"";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PIString PIEvaluator::inBrackets(const PIString & string) {
|
||||
int slen = string.length(), bcnt = 0;
|
||||
PIChar cc;
|
||||
for (int i = 0; i < slen; i++) {
|
||||
cc = string[i];
|
||||
if (cc == '(') bcnt++;
|
||||
if (cc == ')') {
|
||||
bcnt--;
|
||||
if (bcnt == 0) return string.mid(1, i - 1);
|
||||
}
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
PIString PIEvaluator::operationChar(const PIEvaluatorTypes::Operation & operation) {
|
||||
switch (operation) {
|
||||
case PIEvaluatorTypes::oAdd: return "+";
|
||||
case PIEvaluatorTypes::oSubtract: return "-";
|
||||
case PIEvaluatorTypes::oMultiply: return "*";
|
||||
case PIEvaluatorTypes::oDivide: return "/";
|
||||
case PIEvaluatorTypes::oPower: return "^";
|
||||
case PIEvaluatorTypes::oResidue: return "%";
|
||||
case PIEvaluatorTypes::oEqual: return "=";
|
||||
case PIEvaluatorTypes::oNotEqual: return ("≠");
|
||||
case PIEvaluatorTypes::oGreaterEqual: return ("≥");
|
||||
case PIEvaluatorTypes::oSmallerEqual: return ("≤");
|
||||
case PIEvaluatorTypes::oGreater: return ">";
|
||||
case PIEvaluatorTypes::oSmaller: return "<";
|
||||
case PIEvaluatorTypes::oAnd: return ("⋀");
|
||||
case PIEvaluatorTypes::oOr: return ("⋁");
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline complexd PIEvaluator::residue(const complexd & f, const complexd & s) {
|
||||
complexd ret;
|
||||
if (s.real() != 0.) ret = complexd(f.real() - ((int)(f.real() / s.real())) * s.real(), 0.);
|
||||
if (s.imag() != 0.) ret = complexd(ret.real(), f.imag() - ((int)(f.imag() / s.imag())) * s.imag());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci) {
|
||||
PIEvaluatorTypes::Function cfunc = content.function(ci.function);
|
||||
int oi = -ci.out - 1;
|
||||
complexd tmp, stmp;
|
||||
ldouble ldtmp;
|
||||
//qDebug() << "function " << (int)cfunc.type;
|
||||
switch (cfunc.type) {
|
||||
case PIEvaluatorTypes::bfSin:
|
||||
tmpvars[oi].value = sin(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfCos:
|
||||
tmpvars[oi].value = cos(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfTg:
|
||||
tmpvars[oi].value = tan(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfCtg:
|
||||
tmp = tan(value(ci.operators[0]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfArcsin:
|
||||
tmpvars[oi].value = asinc(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfArccos:
|
||||
tmpvars[oi].value = acosc(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfArctg:
|
||||
tmpvars[oi].value = atanc(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfArcctg:
|
||||
tmp = atanc(value(ci.operators[0]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfSh:
|
||||
tmpvars[oi].value = sinh(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfCh:
|
||||
tmpvars[oi].value = cosh(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfTh:
|
||||
tmpvars[oi].value = tanh(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfCth:
|
||||
tmp = tanh(value(ci.operators[0]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfAbs:
|
||||
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfSqrt:
|
||||
tmpvars[oi].value = sqrt(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfSqr:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[0]);
|
||||
break;
|
||||
case PIEvaluatorTypes::bfExp:
|
||||
tmpvars[oi].value = exp(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfPow:
|
||||
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfLn:
|
||||
tmpvars[oi].value = log(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfLg:
|
||||
tmpvars[oi].value = log10(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfLog:
|
||||
tmp = log(value(ci.operators[1]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = log(value(ci.operators[0])) / tmp;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfRe:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real();
|
||||
break;
|
||||
case PIEvaluatorTypes::bfIm:
|
||||
tmpvars[oi].value = value(ci.operators[0]).imag();
|
||||
break;
|
||||
case PIEvaluatorTypes::bfArg:
|
||||
tmpvars[oi].value = arg(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfLen:
|
||||
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfConj:
|
||||
tmpvars[oi].value = conj(value(ci.operators[0]));
|
||||
break;
|
||||
case PIEvaluatorTypes::bfSign:
|
||||
ldtmp = value(ci.operators[0]).real();
|
||||
tmpvars[oi].value = ldtmp >= 0. ? complexd_1 : -complexd_1;
|
||||
break;
|
||||
case PIEvaluatorTypes::bfRad:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * complexd(deg2rad, 0.);
|
||||
break;
|
||||
case PIEvaluatorTypes::bfDeg:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.);
|
||||
break;
|
||||
case PIEvaluatorTypes::bfRandom:
|
||||
tmp = static_cast<ldouble>(rand()) / RAND_MAX;
|
||||
stmp = value(ci.operators[1]) - value(ci.operators[0]);
|
||||
tmpvars[oi].value = value(ci.operators[0]) + tmp * stmp;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool PIEvaluator::execInstructions() {
|
||||
PIEvaluatorTypes::Instruction ci;
|
||||
int oi;
|
||||
complexd tmp;
|
||||
tmpvars = variables;
|
||||
//cout << "var count " << tmpvars.size_s() << endl;
|
||||
for (int i = 0; i < instructions.size_s(); i++) {
|
||||
ci = instructions[i];
|
||||
oi = -ci.out - 1;
|
||||
//cout << value(ci.operators[0]) << operationChar(ci.operation) << value(ci.operators[1]) << ", " << oi << endl;
|
||||
switch (ci.operation) {
|
||||
case PIEvaluatorTypes::oAdd:
|
||||
tmpvars[oi].value = value(ci.operators[0]) + value(ci.operators[1]);
|
||||
break;
|
||||
case PIEvaluatorTypes::oSubtract:
|
||||
tmpvars[oi].value = value(ci.operators[0]) - value(ci.operators[1]);
|
||||
break;
|
||||
case PIEvaluatorTypes::oMultiply:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
|
||||
break;
|
||||
case PIEvaluatorTypes::oDivide:
|
||||
tmp = value(ci.operators[1]);
|
||||
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
||||
break;
|
||||
case PIEvaluatorTypes::oResidue:
|
||||
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case PIEvaluatorTypes::oPower:
|
||||
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case PIEvaluatorTypes::oEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]) == value(ci.operators[1]);
|
||||
break;
|
||||
case PIEvaluatorTypes::oNotEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]) != value(ci.operators[1]);
|
||||
break;
|
||||
case PIEvaluatorTypes::oGreaterEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() >= value(ci.operators[1]).real();
|
||||
break;
|
||||
case PIEvaluatorTypes::oSmallerEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() <= value(ci.operators[1]).real();
|
||||
break;
|
||||
case PIEvaluatorTypes::oGreater:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > value(ci.operators[1]).real();
|
||||
break;
|
||||
case PIEvaluatorTypes::oSmaller:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() < value(ci.operators[1]).real();
|
||||
break;
|
||||
case PIEvaluatorTypes::oAnd:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. && value(ci.operators[1]).real() > 0.;
|
||||
break;
|
||||
case PIEvaluatorTypes::oOr:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. || value(ci.operators[1]).real() > 0.;
|
||||
break;
|
||||
case PIEvaluatorTypes::oFunction:
|
||||
execFunction(ci);
|
||||
break;
|
||||
case PIEvaluatorTypes::oNone:
|
||||
tmpvars[oi].value = value(ci.operators[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out = value(instructions.back().out);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::check(const PIString & string) {
|
||||
currentString = preprocess(string);
|
||||
if (!check())
|
||||
return false;
|
||||
lastError = "Correct";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
complexd PIEvaluator::evaluate() {
|
||||
if (!execInstructions()) out = 0.;
|
||||
if (fabs(out.real()) < 1E-300) out = complexd(0., out.imag());
|
||||
if (fabs(out.imag()) < 1E-300) out = complexd(out.real(), 0.);
|
||||
return out;
|
||||
}
|
||||
148
pievaluator.h
Normal file
148
pievaluator.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifndef PIEVALUATOR_H
|
||||
#define PIEVALUATOR_H
|
||||
|
||||
#include "pistring.h"
|
||||
#include "pimath.h"
|
||||
|
||||
namespace PIEvaluatorTypes {
|
||||
static const int operationCount = 14;
|
||||
|
||||
enum eType {etNumber, etOperator, etVariable, etFunction};
|
||||
enum Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower,
|
||||
oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual,
|
||||
oAnd, oOr, oFunction};
|
||||
enum BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg,
|
||||
bfArcsin, bfArccos, bfArctg, bfArcctg,
|
||||
bfExp, bfRandom, bfSh, bfCh, bfTh, bfCth,
|
||||
bfSqrt, bfSqr, bfPow, bfAbs,
|
||||
bfLn, bfLg, bfLog, bfSign,
|
||||
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||
bfRad, bfDeg};
|
||||
|
||||
struct Instruction {
|
||||
Instruction() {;}
|
||||
Instruction(Operation oper, PIVector<int> opers, int out_ind, int func = -1) {
|
||||
operation = oper; operators = opers; out = out_ind; function = func;}
|
||||
Operation operation;
|
||||
PIVector<int> operators;
|
||||
int out;
|
||||
int function;};
|
||||
struct Element {
|
||||
Element() {;}
|
||||
Element(eType new_type, int new_num, int new_var_num = -1) {set(new_type, new_num, new_var_num);}
|
||||
void set(eType new_type, int new_num, int new_var_num = -1) {type = new_type; num = new_num; var_num = new_var_num;}
|
||||
eType type;
|
||||
int num;
|
||||
int var_num;};
|
||||
struct Function {
|
||||
Function() {arguments = 0; type = bfUnknown;}
|
||||
Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype;}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
int arguments;};
|
||||
struct Variable {
|
||||
Variable() {value = 0.;}
|
||||
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
||||
PIString name;
|
||||
complexd value;};
|
||||
};
|
||||
/*
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
class PIEvaluatorContent
|
||||
{
|
||||
friend class PIEvaluator;
|
||||
public:
|
||||
PIEvaluatorContent();
|
||||
~PIEvaluatorContent() {;}
|
||||
|
||||
inline void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));}
|
||||
inline void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();}
|
||||
inline int functionsCount() const {return functions.size();}
|
||||
inline int variablesCount() const {return variables.size();}
|
||||
inline int customVariablesCount() const {return variables.size() - cv_count;}
|
||||
inline int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;}
|
||||
inline int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;}
|
||||
inline PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];}
|
||||
inline PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];}
|
||||
inline PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||
inline PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||
inline PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];}
|
||||
bool setVariableValue(int index, complexd new_value);
|
||||
bool setVariableName(int index, const PIString & new_name);
|
||||
inline bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||
inline bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||
inline void removeVariable(int index) {variables.remove(index);}
|
||||
inline void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));}
|
||||
void clearCustomVariables();
|
||||
void sortVariables();
|
||||
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||
|
||||
private:
|
||||
PIVector<PIEvaluatorTypes::Function> functions;
|
||||
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||
int cv_count;
|
||||
|
||||
};
|
||||
|
||||
class PIEvaluator
|
||||
{
|
||||
public:
|
||||
PIEvaluator() {;}
|
||||
~PIEvaluator() {;}
|
||||
|
||||
bool check(const PIString & string);
|
||||
inline int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);}
|
||||
inline void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);}
|
||||
inline void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;}
|
||||
complexd evaluate();
|
||||
inline void removeVariable(const PIString & name) {content.removeVariable(name);}
|
||||
inline void clearCustomVariables() {content.clearCustomVariables();}
|
||||
inline int variableIndex(const PIString & name) const {return content.findVariable(name);}
|
||||
inline const PIStringList & unknownVariables() {return unknownVars;}
|
||||
inline const PIString & expression() {return currentString;}
|
||||
inline const PIString & error() {return lastError;}
|
||||
inline const complexd & lastResult() {return out;}
|
||||
|
||||
PIEvaluatorContent content;
|
||||
|
||||
private:
|
||||
const PIString & prepare(const PIString & string);
|
||||
const PIString & preprocess(const PIString & string);
|
||||
int parse(const PIString & string, int offset = 0);
|
||||
void convert();
|
||||
void checkBrackets();
|
||||
void removeSpaces();
|
||||
void findUnknownVariables();
|
||||
void removeJunk();
|
||||
void replaceOperators();
|
||||
void makeOutput(PIString & string);
|
||||
bool fillElements();
|
||||
bool setSignes();
|
||||
bool isSign(const PIChar & ch);
|
||||
inline PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;}
|
||||
bool check();
|
||||
bool execInstructions();
|
||||
PIString inBrackets(const PIString & string);
|
||||
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
||||
PIEvaluatorTypes::Operation operationInOrder(const int & index);
|
||||
inline complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;}
|
||||
inline complexd residue(const complexd & f, const complexd & s);
|
||||
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||
|
||||
PIVector<PIEvaluatorTypes::Element> elements;
|
||||
PIVector<PIEvaluatorTypes::Variable> currentVariables, variables, tmpvars, * kvars;
|
||||
PIVector<PIEvaluatorTypes::Instruction> instructions;
|
||||
PIStringList unknownVars;
|
||||
PIString currentString, lastError;
|
||||
complexd out;
|
||||
};
|
||||
|
||||
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
||||
|
||||
#endif // PIEVALUATOR_H
|
||||
38
pifile.cpp
38
pifile.cpp
@@ -1,7 +1,7 @@
|
||||
#include "pifile.h"
|
||||
|
||||
|
||||
bool PIFile::open(const PIString & path_, Flags<Mode> mode_) {
|
||||
bool PIFile::open(const PIString & path_, PIFlags<Mode> mode_) {
|
||||
cpath = path_;
|
||||
cmode = mode_;
|
||||
string st = cpath.stdString();
|
||||
@@ -18,7 +18,26 @@ bool PIFile::open(const PIString & path_, Flags<Mode> mode_) {
|
||||
PIString PIFile::readLine() {
|
||||
char * buff = new char[4096];
|
||||
stream.getline(buff, 4096);
|
||||
return string(buff);
|
||||
return PIString(buff);
|
||||
}
|
||||
|
||||
|
||||
int PIFile::readAll(void * data) {
|
||||
int cp = pos(), s = size();
|
||||
stream.seekg(0);
|
||||
stream.read((char * )data, s);
|
||||
seek(cp);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIFile::readAll() {
|
||||
int s = size();
|
||||
if (s < 0) return PIByteArray();
|
||||
PIByteArray a(s);
|
||||
s = readAll(a.data());
|
||||
if (s >= 0) a.resize(s);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +45,11 @@ int PIFile::size() {
|
||||
int s, cp = stream.tellg();
|
||||
stream.seekg(0, fstream::end);
|
||||
s = stream.tellg();
|
||||
stream.seekg(cp);
|
||||
stream.seekg(cp, fstream::beg);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void PIFile::seek(int position) {
|
||||
if (cmode[Read]) stream.seekg(position);
|
||||
if (cmode[Write]) stream.seekp(position);
|
||||
}
|
||||
|
||||
|
||||
void PIFile::resize(int new_size, char fill_) {
|
||||
int ds = new_size - size();
|
||||
if (ds == 0) return;
|
||||
@@ -56,3 +69,10 @@ int PIFile::pos() {
|
||||
if (cmode[Write]) return stream.tellp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PIFile PIFile::openTemporary(PIFlags<PIFile::Mode> mode) {
|
||||
char * rc;
|
||||
rc = tmpnam(0);
|
||||
return PIFile(PIString(rc), mode);
|
||||
}
|
||||
|
||||
58
pifile.h
58
pifile.h
@@ -1,7 +1,6 @@
|
||||
#ifndef PIFILE_H
|
||||
#define PIFILE_H
|
||||
|
||||
#include "piincludes.h"
|
||||
#include "pistring.h"
|
||||
#include <fstream>
|
||||
|
||||
@@ -11,33 +10,46 @@ class PIFile
|
||||
{
|
||||
public:
|
||||
PIFile() {;}
|
||||
|
||||
|
||||
enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app};
|
||||
|
||||
PIFile(const PIString & path, Flags<Mode> mode = Read | Write) {open(path, mode);}
|
||||
|
||||
PIFile(const PIString & path, PIFlags<Mode> mode = Read | Write) {open(path, mode);}
|
||||
PIFile(const PIFile & file) {cpath = file.cpath; cmode = file.cmode;}
|
||||
~PIFile() {if (isOpened()) close();}
|
||||
|
||||
bool open(const PIString & path, Flags<Mode> mode = Read | Write);
|
||||
inline void close() {stream.close();}
|
||||
inline void clear() {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);}
|
||||
void seek(int position);
|
||||
inline void seekToEnd() {stream.seekg(0, fstream::end);}
|
||||
PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;}
|
||||
|
||||
bool open(const PIString & path, PIFlags<Mode> mode);
|
||||
bool open(PIFlags<Mode> mode) {return open(cpath, mode);}
|
||||
bool open(const PIString & path) {return open(path, cmode);}
|
||||
bool open() {return open(cpath, cmode);}
|
||||
void close() {stream.close();}
|
||||
void clear() {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);}
|
||||
void seek(int position) {stream.clear(); stream.seekg(position); stream.seekp(position);}
|
||||
void seekToBegin() {stream.clear(); stream.seekg(0, fstream::beg); stream.seekp(0, fstream::beg);}
|
||||
void seekToEnd() {stream.clear(); stream.seekg(0, fstream::end); stream.seekp(0, fstream::end);}
|
||||
void seekToLine(int line) {stream.clear(); seekToBegin(); piForTimes (line) readLine();} // line 0 - begin of file
|
||||
void resize(int new_size, char fill = 0);
|
||||
inline void fill(char c) {stream.fill(c);}
|
||||
inline void flush() {stream.flush();}
|
||||
void fill(char c) {stream.fill(c);}
|
||||
void flush() {stream.flush();}
|
||||
PIString readLine();
|
||||
|
||||
int readAll(void * data);
|
||||
PIByteArray readAll();
|
||||
void remove() {if (isOpened()) close(); std::remove(cpath.data());}
|
||||
|
||||
PIString path() const {return cpath;}
|
||||
Flags<Mode> mode() const {return cmode;}
|
||||
void setPath(const PIString & path) {cpath = path;}
|
||||
PIFlags<Mode> mode() const {return cmode;}
|
||||
int size();
|
||||
int pos();
|
||||
bool isOpened() const {return stream.is_open();}
|
||||
bool isEnd() const {return stream.eof();}
|
||||
|
||||
bool isOpened() {return stream.is_open();}
|
||||
bool isEnd() {return stream.eof();}
|
||||
bool isEmpty() {return (size() == 0);}
|
||||
|
||||
PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;}
|
||||
PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;}
|
||||
|
||||
PIFile & writeToBinLog(ushort id, const void * data, int size) {writeBinary(id).writeBinary((ushort)size).writeData(data, size); flush(); return *this;}
|
||||
|
||||
PIFile & writeBinary(const char v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const short v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const int v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
@@ -48,10 +60,10 @@ public:
|
||||
PIFile & writeBinary(const ulong v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const float v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
PIFile & writeBinary(const double v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||
|
||||
|
||||
PIFile & operator <<(const char & v) {stream.write(&v, 1); return *this;}
|
||||
//PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;}
|
||||
PIFile & operator <<(const PIString & v) {stream.write(v.data(), v.size()); return *this;}
|
||||
PIFile & operator <<(const PIString & v) {string s = v.stdString(); stream.write(s.c_str(), s.size()); return *this;}
|
||||
PIFile & operator <<(const PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;}
|
||||
PIFile & operator <<(const short & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const int & v) {stream << v; return *this;}
|
||||
@@ -62,7 +74,7 @@ public:
|
||||
PIFile & operator <<(const ulong & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const float & v) {stream << v; return *this;}
|
||||
PIFile & operator <<(const double & v) {stream << v; return *this;}
|
||||
|
||||
|
||||
PIFile & operator >>(char & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(short & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(int & v) {stream >> v; return *this;}
|
||||
@@ -74,11 +86,13 @@ public:
|
||||
PIFile & operator >>(float & v) {stream >> v; return *this;}
|
||||
PIFile & operator >>(double & v) {stream >> v; return *this;}
|
||||
|
||||
static PIFile openTemporary(PIFlags<PIFile::Mode> mode = PIFile::Read | PIFile::Write);
|
||||
|
||||
private:
|
||||
fstream stream;
|
||||
PIString cpath;
|
||||
Flags<Mode> cmode;
|
||||
|
||||
PIFlags<Mode> cmode;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIFILE_H
|
||||
|
||||
@@ -17,6 +17,8 @@ public:
|
||||
inline PIPoint<Type> & move(const PIPoint<Type> & p) {x += p.x; y += p.y; return *this;}
|
||||
inline double angleRad() const {return atan2(y, x);}
|
||||
inline int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);}
|
||||
inline PIPoint<Type> toPolar(bool isDeg = false) const {return PIPoint<Type>(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}
|
||||
inline static PIPoint<Type> fromPolar(const PIPoint<Type> & p) {return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x));}
|
||||
|
||||
inline PIPoint<Type> operator +(const PIPoint<Type> & p) {return PIPoint<Type>(x + p.x, y + p.y);}
|
||||
inline PIPoint<Type> operator +(const Type & p) {return PIPoint<Type>(x + p, y + p);}
|
||||
|
||||
112
piincludes.h
112
piincludes.h
@@ -7,33 +7,48 @@
|
||||
#if __QNX__
|
||||
# define QNX
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
# ifndef QNX
|
||||
# define LINUX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#ifndef QNX
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
# include <clocale>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <cctype>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include <set>
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#include <wincon.h>
|
||||
# include <conio.h>
|
||||
# include <windows.h>
|
||||
# include <wincon.h>
|
||||
#endif
|
||||
|
||||
#define FOREVER for (;;)
|
||||
#define FOREVER_WAIT FOREVER msleep(10);
|
||||
#define FOREVER_WAIT FOREVER msleep(1);
|
||||
|
||||
typedef long long llong;
|
||||
typedef unsigned char uchar;
|
||||
@@ -49,60 +64,46 @@ using std::endl;
|
||||
using std::flush;
|
||||
using std::vector;
|
||||
using std::list;
|
||||
using std::queue;
|
||||
using std::deque;
|
||||
using std::stack;
|
||||
using std::set;
|
||||
using std::string;
|
||||
#ifndef QNX
|
||||
using std::wstring;
|
||||
# ifndef WINDOWS
|
||||
static locale_t currentLocale_t = 0;
|
||||
# endif
|
||||
#else
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIVector: public vector<Type, Allocator> {
|
||||
static bool isPIInit = false;
|
||||
|
||||
class piInit {
|
||||
public:
|
||||
inline const Type & at(uint index) const {return (*this)[index];}
|
||||
inline Type & at(uint index) {return (*this)[index];}
|
||||
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||
inline void fill(const Type & t) {vector<Type, Allocator>::assign(vector<Type, Allocator>::size(), t);}
|
||||
inline void pop_front() {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin());}
|
||||
inline void push_front(const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin(), t);}
|
||||
inline void remove(uint num) {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin() + num);}
|
||||
inline void remove(uint num, uint count) {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin() + num, vector<Type, Allocator>::begin() + num + count);}
|
||||
inline void insert(uint pos, const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin() + pos, t);}
|
||||
piInit() {
|
||||
if (isPIInit) return;
|
||||
isPIInit = true;
|
||||
#ifdef LINUX
|
||||
if (currentLocale_t != 0) {
|
||||
freelocale(currentLocale_t);
|
||||
currentLocale_t = 0;
|
||||
}
|
||||
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
||||
#else
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
}
|
||||
~piInit() {
|
||||
//if (currentLocale_t != 0) freelocale(currentLocale_t);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||
class PIList: public list<Type, Allocator> {
|
||||
public:
|
||||
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||
inline void fill(const Type & t) {list<Type, Allocator>::assign(list<Type, Allocator>::size(), t);}
|
||||
inline void remove(uint num) {list<Type, Allocator>::erase(list<Type, Allocator>::begin() + num);}
|
||||
inline void remove(uint num, uint count) {list<Type, Allocator>::erase(list<Type, Allocator>::begin() + num, list<Type, Allocator>::begin() + num + count);}
|
||||
inline void insert(uint pos, const Type & t) {list<Type, Allocator>::insert(list<Type, Allocator>::begin() + pos, t);}
|
||||
};
|
||||
static piInit __pi_init;
|
||||
static lconv * currentLocale = std::localeconv();
|
||||
|
||||
template<typename Enum>
|
||||
class Flags {
|
||||
private:
|
||||
int flags;
|
||||
public:
|
||||
inline Flags(): flags(0) {;}
|
||||
inline Flags(Enum e): flags(e) {;}
|
||||
inline Flags(const Flags & f): flags(f.flags) {;}
|
||||
inline Flags(const int i): flags(i) {;}
|
||||
inline void operator =(const Flags & f) {flags = f.flags;}
|
||||
inline void operator |=(const Flags & f) {flags = flags | f.flags;}
|
||||
inline void operator |=(const Enum & e) {flags = flags | e;}
|
||||
inline void operator |=(const int i) {flags = flags | i;}
|
||||
inline void operator &=(const Flags & f) {flags = flags & f.flags;}
|
||||
inline void operator &=(const Enum & e) {flags = flags & e;}
|
||||
inline void operator &=(const int i) {flags = flags & i;}
|
||||
inline Flags & operator |(Flags f) const {Flags tf(flags | f.flags); return tf;}
|
||||
inline Flags & operator |(Enum e) const {Flags tf(flags | e); return tf;}
|
||||
inline Flags & operator |(int i) const {Flags tf(flags | i); return tf;}
|
||||
inline Flags & operator &(Flags f) const {Flags tf(flags & f.flags); return tf;}
|
||||
inline Flags & operator &(Enum e) const {Flags tf(flags & e); return tf;}
|
||||
inline Flags & operator &(int i) const {Flags tf(flags & i); return tf;}
|
||||
inline bool operator [](Enum e) {return (flags & e) == e;}
|
||||
inline operator int() const {return flags;}
|
||||
};
|
||||
inline const char * errorString() {return strerror(errno);}
|
||||
|
||||
#ifdef WINDOWS
|
||||
inline int random() {return rand();}
|
||||
@@ -113,6 +114,7 @@ template<typename Type> inline Type piMin(const Type & f, const Type & s) {retur
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;}
|
||||
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
||||
inline ushort letobe_s(ushort v) {return v = (v << 8) | (v >> 8);}
|
||||
inline bool atob(const string & str) { return str == "1" ? true : false;};
|
||||
inline string btos(const bool num) { return num ? "0" : "1";};
|
||||
inline string itos(const int num) {
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
#include "pikbdlistener.h"
|
||||
|
||||
|
||||
bool PIKbdListener::exiting;
|
||||
|
||||
PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
||||
#ifdef __WIN32__
|
||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hIn, &smode);
|
||||
#else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
sterm = term;
|
||||
#endif
|
||||
is_active = true;
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
PIKbdListener::exiting = exit_enabled = false;
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::begin() {
|
||||
//cout << "list begin" << endl;
|
||||
#ifdef __WIN32__
|
||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hIn, &smode);
|
||||
@@ -11,19 +29,8 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
||||
#else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
sterm = term;
|
||||
term.c_lflag &= ~(ECHO | ICANON) | NOFLSH;
|
||||
tcsetattr(0, TCSAFLUSH, &term);
|
||||
#endif
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
PIKbdListener::~PIKbdListener() {
|
||||
#ifdef __WIN32__
|
||||
SetConsoleMode(hIn, smode);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &sterm);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -34,6 +41,16 @@ void PIKbdListener::run() {
|
||||
#else
|
||||
ret = read(0, &rc, 1);
|
||||
#endif
|
||||
if (ret_func != 0 && ret > 0) ret_func(rc, data);
|
||||
if (exit_enabled && rc == exit_key) PIKbdListener::exiting = true;
|
||||
if (ret_func != 0 && ret > 0 && is_active) ret_func(rc, data);
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::end() {
|
||||
//cout << "list end" << endl;
|
||||
#ifdef __WIN32__
|
||||
SetConsoleMode(hIn, smode);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &sterm);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,22 +3,37 @@
|
||||
|
||||
#include "pithread.h"
|
||||
#ifndef __WIN32__
|
||||
#include <termios.h>
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) msleep(1);
|
||||
|
||||
typedef void (*KBFunc)(char, void * );
|
||||
|
||||
class PIKbdListener: public PIThread {
|
||||
friend class PIConsole;
|
||||
public:
|
||||
// slot is any function format "void <func>(char, void * )"
|
||||
PIKbdListener(KBFunc slot = 0, void * data = 0);
|
||||
~PIKbdListener();
|
||||
~PIKbdListener() {terminate(); end();}
|
||||
|
||||
inline void enableExitCapture(char key = 'Q') {exit_enabled = true; exit_key = key;}
|
||||
inline void disableExitCapture() {exit_enabled = false;}
|
||||
inline bool exitCaptured() const {return exit_enabled;}
|
||||
inline char exitKey() const {return exit_key;}
|
||||
inline bool isActive() {return is_active;}
|
||||
inline void setActive(bool yes = true) {is_active = yes;}
|
||||
|
||||
static bool exiting;
|
||||
|
||||
private:
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
|
||||
KBFunc ret_func;
|
||||
char rc;
|
||||
char rc, exit_key, is_active;
|
||||
bool exit_enabled;
|
||||
void * data;
|
||||
#ifdef __WIN32__
|
||||
DWORD ret;
|
||||
|
||||
20
pimath.cpp
20
pimath.cpp
@@ -155,7 +155,7 @@ void fft(complexd * x, int T, bool complement)
|
||||
}
|
||||
|
||||
|
||||
const char Solver::methods_desc[] = "Methods:\
|
||||
const char Solver::methods_desc[] = "b{Methods:}\
|
||||
\n -1 - Global settings\
|
||||
\n 01 - Eyler 1\
|
||||
\n 02 - Eyler 2\
|
||||
@@ -167,15 +167,15 @@ const char Solver::methods_desc[] = "Methods:\
|
||||
\n 34 - Polynomial Approximation 4\
|
||||
\n 35 - Polynomial Approximation 5";
|
||||
|
||||
Solver::Method Solver::method_global = Solver::AdamsBashfortMoulton_4;
|
||||
Solver::Method Solver::method_global = Solver::Eyler_2;
|
||||
|
||||
|
||||
void Solver::solve(double u, double h) {
|
||||
switch (method) {
|
||||
case Global:
|
||||
switch (method_global) {
|
||||
case Eyler1: solveEyler1(u, h); break;
|
||||
case Eyler2: solveEyler2(u, h); break;
|
||||
case Eyler_1: solveEyler1(u, h); break;
|
||||
case Eyler_2: solveEyler2(u, h); break;
|
||||
case RungeKutta_4: solveRK4(u, h); break;
|
||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
|
||||
@@ -186,8 +186,8 @@ void Solver::solve(double u, double h) {
|
||||
case PolynomialApproximation_5: solvePA5(u, h); break;
|
||||
}
|
||||
break;
|
||||
case Eyler1: solveEyler1(u, h); break;
|
||||
case Eyler2: solveEyler2(u, h); break;
|
||||
case Eyler_1: solveEyler1(u, h); break;
|
||||
case Eyler_2: solveEyler2(u, h); break;
|
||||
case RungeKutta_4: solveRK4(u, h); break;
|
||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
|
||||
@@ -273,12 +273,14 @@ void Solver::solveEyler2(double u, double h) {
|
||||
|
||||
|
||||
void Solver::solveRK4(double u, double h) {
|
||||
td = X[0] - F[0][0];
|
||||
k1 = A * X + d * u; xx = k1 * h / 2.; XX = X + xx;
|
||||
k2 = A * (XX + k1 * h / 2.) + d * (u + xx[0]); xx = k2 * h / 2.; XX += xx;
|
||||
k3 = A * (XX + k2 * h / 2.) + d * (u + xx[0]); xx = k3 * h; XX += xx;
|
||||
k4 = A * (XX + k3 * h) + d * (u + xx[0]);
|
||||
k2 = A * (XX + k1 * h / 2.) + d * (u + td/3.); xx = k2 * h / 2.; XX += xx;
|
||||
k3 = A * (XX + k2 * h / 2.) + d * (u + td*2./3.); xx = k3 * h; XX += xx;
|
||||
k4 = A * (XX + k3 * h) + d * (u + td);
|
||||
//cout << k1 << k2 << k3 << k4 << endl;
|
||||
X += (k1 + k2 * 2. + k3 * 2. + k4) * h / 6.;
|
||||
F[0] = X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
59
pimath.h
59
pimath.h
@@ -1,27 +1,52 @@
|
||||
#ifndef PIMATH_H
|
||||
#define PIMATH_H
|
||||
|
||||
#include <complex>
|
||||
#include <stdarg.h>
|
||||
#include "piincludes.h"
|
||||
#include "picontainers.h"
|
||||
#ifndef QNX
|
||||
# include <cmath>
|
||||
# include <cmath>
|
||||
# include <complex>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <math.h>
|
||||
# include <complex.h>
|
||||
#endif
|
||||
|
||||
#define M_2PI 6.28318530717958647692
|
||||
#define M_PI_3 1.04719755119659774615
|
||||
|
||||
using std::complex;
|
||||
|
||||
typedef complex<int> complexi;
|
||||
typedef complex<float> complexf;
|
||||
typedef complex<double> complexd;
|
||||
typedef complex<long double> complexld;
|
||||
const complexld complexld_i(0., 1.);
|
||||
const complexld complexld_0(0.);
|
||||
const complexld complexld_1(1.);
|
||||
const complexd complexd_i(0., 1.);
|
||||
const complexd complexd_0(0.);
|
||||
const complexd complexd_1(1.);
|
||||
|
||||
const double deg2rad = atan(1.) / 45.;
|
||||
const double rad2deg = 45. / atan(1.);
|
||||
|
||||
inline int pow2(int p) {return (int)1 << p;}
|
||||
inline int pow2(int p) {return 1 << p;}
|
||||
inline double sqr(const double & v) {return v * v;}
|
||||
inline double sinc(const double & v) {double t = M_PI * v; return sin(t) / t;}
|
||||
inline complexd atanc(const complexd & c) {return -complexd(-0.5, 1.) * log((complexd_1 + complexd_i * c) / (complexd_1 - complexd_i * c));}
|
||||
inline complexd asinc(const complexd & c) {return -complexd_i * log(complexd_i * c + sqrt(complexd_1 - c * c));}
|
||||
inline complexd acosc(const complexd & c) {return -complexd_i * log(c + complexd_i * sqrt(complexd_1 - c * c));}
|
||||
#ifdef QNX
|
||||
inline complexd tan(const complexd & c) {return sin(c) / cos(c);}
|
||||
inline complexd tanh(const complexd & c) {return sinh(c) / cosh(c);}
|
||||
inline complexd log2(const complexd & c) {return log(c) / M_LN2;}
|
||||
inline complexd log10(const complexd & c) {return log(c) / M_LN10;}
|
||||
inline double j0(const double & v) {v;}
|
||||
inline double j1(const double & v) {v;}
|
||||
inline double jn(const int & n, const double & v) {v;}
|
||||
inline double y0(const double & v) {v;}
|
||||
inline double y1(const double & v) {v;}
|
||||
inline double yn(const int & n, const double & v) {v;}
|
||||
#endif
|
||||
|
||||
template<uint Cols, uint Rows, typename Type>
|
||||
class PIMathMatrixT;
|
||||
@@ -35,13 +60,15 @@ class PIMathVectorT {
|
||||
typedef PIMathVectorT<Size, Type> _CVector;
|
||||
public:
|
||||
PIMathVectorT() {resize(Size);}
|
||||
//PIMathVectorT(Type val) {resize(Size); PIMV_FOR(i, 0) c[i] = val;}
|
||||
PIMathVectorT(Type fval, ...) {resize(Size); c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl);}
|
||||
PIMathVectorT(const PIVector<Type> & val) {resize(Size); PIMV_FOR(i, 0) c[i] = val[i];}
|
||||
PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(Size); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];}
|
||||
PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(Size); set(st, fn);}
|
||||
|
||||
inline uint size() const {return Size;}
|
||||
inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;}
|
||||
inline _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;}
|
||||
inline _CVector & set(const _CVector & st, const _CVector & fn) {PIMV_FOR(i, 0) c[i] = fn[i] - st[i]; return *this;}
|
||||
inline _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;}
|
||||
inline _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;}
|
||||
inline _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;}
|
||||
@@ -71,12 +98,12 @@ public:
|
||||
inline void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];}
|
||||
inline void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;}
|
||||
inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];}
|
||||
inline _CVector operator -() {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;}
|
||||
inline _CVector operator +(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;}
|
||||
inline _CVector operator -(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;}
|
||||
inline _CVector operator *(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;}
|
||||
inline _CVector operator /(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;}
|
||||
inline _CVector operator *(const _CVector & v) {if (Size < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;}
|
||||
inline _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;}
|
||||
inline _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;}
|
||||
inline _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;}
|
||||
inline _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;}
|
||||
inline _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;}
|
||||
inline _CVector operator *(const _CVector & v) const {if (Size > 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;}
|
||||
inline Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;}
|
||||
|
||||
inline operator PIMathMatrixT<1, Size, Type>() {return PIMathMatrixT<1, Size, Type>(c);}
|
||||
@@ -96,6 +123,8 @@ private:
|
||||
|
||||
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;}
|
||||
template<uint Size, typename Type>
|
||||
inline const bool operator ||(const PIMathVectorT<Size, Type> & f, const PIMathVectorT<Size, Type> & s) {return (f * s).isNull();}
|
||||
|
||||
//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;}
|
||||
@@ -637,8 +666,8 @@ class Solver
|
||||
{
|
||||
public:
|
||||
enum Method {Global = -1,
|
||||
Eyler1 = 01,
|
||||
Eyler2 = 02,
|
||||
Eyler_1 = 01,
|
||||
Eyler_2 = 02,
|
||||
EylerKoshi = 03,
|
||||
RungeKutta_4 = 14,
|
||||
AdamsBashfortMoulton_2 = 22,
|
||||
|
||||
@@ -11,6 +11,7 @@ public:
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED);
|
||||
//pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutex_init(&mutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
5
pip.h
5
pip.h
@@ -1,6 +1,7 @@
|
||||
#include "pitimer.h"
|
||||
#include "pivariable.h"
|
||||
#include "piconsole.h"
|
||||
#include "pimath.h"
|
||||
#include "pidir.h"
|
||||
#include "picli.h"
|
||||
#include "pievaluator.h"
|
||||
#include "piprotocol.h"
|
||||
#include "picodec.h"
|
||||
|
||||
47
pip.pro
Normal file
47
pip.pro
Normal file
@@ -0,0 +1,47 @@
|
||||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) ?? ???. 18 21:49:21 2011
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
# Input
|
||||
HEADERS += pibitarray.h \
|
||||
pibytearray.h \
|
||||
pichar.h \
|
||||
piconfig.h \
|
||||
piconsole.h \
|
||||
pidir.h \
|
||||
piethernet.h \
|
||||
pievaluator.h \
|
||||
pifile.h \
|
||||
pigeometry.h \
|
||||
piincludes.h \
|
||||
pikbdlistener.h \
|
||||
pimath.h \
|
||||
pimutex.h \
|
||||
pip.h \
|
||||
piprotocol.h \
|
||||
piserial.h \
|
||||
pistring.h \
|
||||
pithread.h \
|
||||
pitimer.h \
|
||||
pivariable.h
|
||||
SOURCES += main.cpp \
|
||||
pibytearray.cpp \
|
||||
piconfig.cpp \
|
||||
piconsole.cpp \
|
||||
pidir.cpp \
|
||||
piethernet.cpp \
|
||||
pievaluator.cpp \
|
||||
pifile.cpp \
|
||||
pikbdlistener.cpp \
|
||||
pimath.cpp \
|
||||
piprotocol.cpp \
|
||||
piserial.cpp \
|
||||
pistring.cpp \
|
||||
pithread.cpp \
|
||||
pitimer.cpp \
|
||||
pivariable.cpp
|
||||
124
piprocess.cpp
Normal file
124
piprocess.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "piprocess.h"
|
||||
|
||||
|
||||
PIProcess::PIProcess(): PIThread() {
|
||||
exit_code = -1;
|
||||
pid = 0;
|
||||
is_exec = false;
|
||||
g_in = g_out = g_err = false;
|
||||
t_in = t_out = t_err = false;
|
||||
env = PIProcess::currentEnvironment();
|
||||
}
|
||||
|
||||
|
||||
PIProcess::~PIProcess() {
|
||||
if (t_in) f_in.remove();
|
||||
if (t_out) f_out.remove();
|
||||
if (t_err) f_err.remove();
|
||||
}
|
||||
|
||||
|
||||
void PIProcess::exec_() {
|
||||
is_exec = false;
|
||||
startOnce();
|
||||
//cout << "exec wait" << endl;
|
||||
while (!is_exec)
|
||||
msleep(1);
|
||||
//cout << "exec end" << endl;
|
||||
}
|
||||
|
||||
|
||||
void PIProcess::run() {
|
||||
//cout << "run" << endl;
|
||||
string str;
|
||||
/// arguments convertion
|
||||
char * a[args.size_s() + 1];
|
||||
for (int i = 0; i < args.size_s(); ++i) {
|
||||
str = args[i].stdString();
|
||||
a[i] = new char[str.size() + 1];
|
||||
memcpy(a[i], str.c_str(), str.size());
|
||||
a[i][str.size()] = 0;
|
||||
//cout << a[i] << endl;
|
||||
}
|
||||
a[args.size_s()] = 0;
|
||||
/// environment convertion
|
||||
char * e[env.size_s() + 1];
|
||||
for (int i = 0; i < env.size_s(); ++i) {
|
||||
str = env[i].stdString();
|
||||
e[i] = new char[str.size() + 1];
|
||||
memcpy(e[i], str.c_str(), str.size());
|
||||
e[i][str.size()] = 0;
|
||||
//cout << e[i] << endl;
|
||||
}
|
||||
e[env.size_s()] = 0;
|
||||
/// files for stdin/out/err
|
||||
t_in = t_out = t_err = false;
|
||||
if (f_in.path().isEmpty()) {
|
||||
f_in = PIFile::openTemporary(PIFile::New | PIFile::Read);
|
||||
t_in = true;
|
||||
}
|
||||
f_in.open(PIFile::New | PIFile::Read); f_in.close();
|
||||
if (f_out.path().isEmpty()) {
|
||||
f_out = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||
t_out = true;
|
||||
}
|
||||
f_out.open(PIFile::New | PIFile::Write); f_out.close();
|
||||
if (f_err.path().isEmpty()) {
|
||||
f_err = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||
t_err = true;
|
||||
}
|
||||
f_err.open(PIFile::New | PIFile::Write); f_err.close();
|
||||
|
||||
str = args.front().stdString();
|
||||
is_exec = true;
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
FILE * tf;
|
||||
//cout << "exec" << endl;
|
||||
//cout << f_out.path() << endl;
|
||||
if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
|
||||
if (g_out) tf = freopen(f_out.path().data(), "w", stdout);
|
||||
if (g_err) tf = freopen(f_err.path().data(), "w", stderr);
|
||||
if (!wd.isEmpty()) system(("cd " + wd).data());
|
||||
if (execvpe(str.c_str(), a, e) < 0)
|
||||
cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl;
|
||||
} else {
|
||||
msleep(1);
|
||||
//cout << "wait" << endl;
|
||||
wait(&exit_code);
|
||||
pid = 0;
|
||||
//cout << "wait done" << endl;
|
||||
}
|
||||
is_exec = false;
|
||||
for (int i = 0; i < env.size_s(); ++i)
|
||||
delete e[i];
|
||||
for (int i = 0; i < args.size_s(); ++i)
|
||||
delete a[i];
|
||||
//cout << "end" << endl;
|
||||
}
|
||||
|
||||
|
||||
void PIProcess::removeEnvironmentVariable(const PIString & variable) {
|
||||
PIString s;
|
||||
for (int i = 0; i < env.size_s(); ++i) {
|
||||
s = env[i];
|
||||
if (s.left(s.find("=")).trimmed() == variable) {
|
||||
env.remove(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProcess::setEnvironmentVariable(const PIString & variable, const PIString & value) {
|
||||
PIString s, v;
|
||||
for (int i = 0; i < env.size_s(); ++i) {
|
||||
s = env[i];
|
||||
v = s.left(s.find("=")).trimmed();
|
||||
if (v == variable) {
|
||||
env[i] = v + "=" + value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
env << variable + "=" + value;
|
||||
}
|
||||
62
piprocess.h
Normal file
62
piprocess.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef PIPROCESS_H
|
||||
#define PIPROCESS_H
|
||||
|
||||
#include "pithread.h"
|
||||
#include "pifile.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
/// TODO workind dir
|
||||
|
||||
class PIProcess: private PIThread
|
||||
{
|
||||
public:
|
||||
PIProcess();
|
||||
~PIProcess();
|
||||
|
||||
int exitCode() const {return exit_code;}
|
||||
int pID() const {return pid;}
|
||||
|
||||
void setGrabInput(bool yes) {g_in = yes;}
|
||||
void setGrabOutput(bool yes) {g_out = yes;}
|
||||
void setGrabError(bool yes) {g_err = yes;}
|
||||
void setInputFile(const PIString & path) {f_in.setPath(path);}
|
||||
void setOutputFile(const PIString & path) {f_out.setPath(path);}
|
||||
void setErrorFile(const PIString & path) {f_err.setPath(path);}
|
||||
void unsetInputFile() {f_in.setPath("");}
|
||||
void unsetOutputFile() {f_out.setPath("");}
|
||||
void unsetErrorFile() {f_err.setPath("");}
|
||||
void setWorkingDirectory(const PIString & path) {wd = path;}
|
||||
void resetWorkingDirectory() {wd.clear();}
|
||||
void exec(const PIString & program) {args.clear(); args << program; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();}
|
||||
void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();}
|
||||
void exec(const PIString & program, const PIStringList & args_) {args = args_; exec_();}
|
||||
void terminate() {if (is_exec) ::kill(pid, SIGKILL); pid = 0;}
|
||||
bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);}
|
||||
PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();}
|
||||
PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();}
|
||||
|
||||
PIStringList environment() {return env;}
|
||||
void clearEnvironment() {env.clear();}
|
||||
void removeEnvironmentVariable(const PIString & variable);
|
||||
void setEnvironmentVariable(const PIString & variable, const PIString & value);
|
||||
|
||||
static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;}
|
||||
|
||||
private:
|
||||
virtual void run();
|
||||
void exec_();
|
||||
|
||||
PIStringList args, env;
|
||||
PIString wd;
|
||||
PIByteArray out;
|
||||
PIFile f_in, f_out, f_err;
|
||||
bool g_in, g_out, g_err, t_in, t_out, t_err;
|
||||
pid_t pid;
|
||||
int exit_code, sz;
|
||||
bool is_exec;
|
||||
|
||||
};
|
||||
|
||||
#endif // PIPROCESS_H
|
||||
411
piprotocol.cpp
411
piprotocol.cpp
@@ -1,180 +1,327 @@
|
||||
#include "piprotocol.h"
|
||||
|
||||
|
||||
PIProtocol::PIProtocol(PIString devName, int speed, void * headerPtr, int headerSize, void * dataPtr, int dataSize) {
|
||||
init();
|
||||
type = PIProtocol::Serial;
|
||||
serial = new PISerial(devName, this, received);
|
||||
serial->setReadData(headerPtr, headerSize, dataSize);
|
||||
this->devName = devName;
|
||||
this->headerPtr = (unsigned char * )headerPtr;
|
||||
this->headerSize = headerSize;
|
||||
this->dataPtr = (unsigned char * )dataPtr;
|
||||
this->dataSize = dataSize;
|
||||
packet = new char[headerSize + dataSize];
|
||||
}
|
||||
|
||||
|
||||
PIProtocol::PIProtocol(PIString ip, int port, void * dataPtr, int dataSize) {
|
||||
init();
|
||||
type = PIProtocol::Ethernet;
|
||||
ether = new PIEthernet(ip, port, this, received);
|
||||
this->devName = ip + ":" + itos(port);
|
||||
this->dataPtr = (unsigned char * )dataPtr;
|
||||
this->dataSize = dataSize;
|
||||
packet = new char[dataSize];
|
||||
PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_) {
|
||||
init();
|
||||
PIConfig conf(config, PIFile::Read);
|
||||
if (!conf.isOpened()) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
devReceiverState = devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
int ps;
|
||||
bool ok;
|
||||
PIFlags<PISerial::Parameters> pp;
|
||||
PIConfig::Entry b = conf.getValue(name),
|
||||
rb = b.getValue("receiver"),
|
||||
sb = b.getValue("sender");
|
||||
PIString dev;
|
||||
|
||||
/// receiver section
|
||||
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
dev = rb.getValue("ip", "", &ok);
|
||||
if (ok) {
|
||||
ps = rb.getValue("port", 0, &ok);
|
||||
if (!ok) {
|
||||
type_rec = PIProtocol::None;
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
devReceiverName = dev + ":" + PIString::fromNumber(ps);
|
||||
}
|
||||
dev = rb.getValue("device", "", &ok);
|
||||
if (ok) {
|
||||
ps = rb.getValue("speed", 0, &ok);
|
||||
if (!ok) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.speed\" in \"" << config << "\"!" << endl;
|
||||
devReceiverState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (rb.getValue("parity", false)) pp |= PISerial::ParityControl;
|
||||
if (rb.getValue("twoStopBits", false)) pp |= PISerial::TwoStopBits;
|
||||
type_rec = PIProtocol::Serial;
|
||||
ser = new PISerial(dev, this, receiveEvent);
|
||||
ser->setInSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
devReceiverName = dev;
|
||||
}
|
||||
|
||||
/// sender section
|
||||
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
dev = sb.getValue("ip", "", &ok);
|
||||
if (ok) {
|
||||
ps = sb.getValue("port", 0, &ok);
|
||||
if (!ok) {
|
||||
type_send = PIProtocol::None;
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
setSenderAddress(dev, ps);
|
||||
devSenderName = dev + ":" + PIString::fromNumber(ps);
|
||||
}
|
||||
dev = sb.getValue("device", "", &ok);
|
||||
if (ok) {
|
||||
ps = sb.getValue("speed", 0, &ok);
|
||||
if (!ok) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" in \"" << config << "\"!" << endl;
|
||||
devSenderState = "Config error";
|
||||
return;
|
||||
}
|
||||
if (sb.getValue("parity", false)) pp |= PISerial::ParityControl;
|
||||
if (sb.getValue("twoStopBits", false)) pp |= PISerial::TwoStopBits;
|
||||
type_send = PIProtocol::Serial;
|
||||
if (ser == 0) ser = new PISerial(dev, this, receiveEvent);
|
||||
ser->setOutSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
devSenderName = dev;
|
||||
}
|
||||
|
||||
float fr = rb.getValue("frequency", 0.f, &ok);
|
||||
if (ok) setExpectedFrequency(fr);
|
||||
fr = sb.getValue("frequency", 0.f, &ok);
|
||||
if (ok) setSenderFrequency(fr);
|
||||
headerPtr = (uchar * )recHeaderPtr;
|
||||
headerSize = recHeaderSize;
|
||||
dataPtr = (uchar * )recDataPtr;
|
||||
dataSize = recDataSize;
|
||||
sendDataPtr = (uchar * )sendDataPtr_;
|
||||
sendDataSize = sendDataSize_;
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (recHeaderPtr != 0) {
|
||||
dataPtr = (uchar * )recHeaderPtr;
|
||||
dataSize = recHeaderSize + recDataSize;
|
||||
if (dataSize > 0) packet = new char[dataSize];
|
||||
} else if (recDataSize > 0) packet = new char[recDataSize];
|
||||
} else if (recHeaderSize + recDataSize > 0) packet = new char[recHeaderSize + recDataSize];
|
||||
}
|
||||
|
||||
|
||||
PIProtocol::~PIProtocol() {
|
||||
delete sendtimer;
|
||||
if (timer != 0) delete timer;
|
||||
if (type == PIProtocol::Serial) delete serial;
|
||||
if (type == PIProtocol::Ethernet) delete ether;
|
||||
delete diagTimer;
|
||||
delete sendTimer;
|
||||
if (packet != 0) delete packet;
|
||||
if (eth != 0) delete eth;
|
||||
if (ser != 0) delete ser;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::init() {
|
||||
work = false;
|
||||
net_diag = PIProtocol::Unknown;
|
||||
cur_pckt = 0;
|
||||
timer = 0;
|
||||
sendtimer = new PITimer(run, this);
|
||||
wrong_count = receive_count = send_count = 0;
|
||||
immediateFreq = integralFreq = 0.f;
|
||||
headerPtr = dataPtr = sendDataPtr = 0;
|
||||
headerSize = dataSize = sendDataSize = 0;
|
||||
exp_freq = 20.f;
|
||||
devState = "Unknown";
|
||||
work = false;
|
||||
ret_func = 0;
|
||||
net_diag = PIProtocol::Unknown;
|
||||
cur_pckt = 0;
|
||||
diagTimer = 0;
|
||||
packet = 0;
|
||||
sendTimer = new PITimer(sendEvent, this);
|
||||
diagTimer = new PITimer(diagEvent, this);
|
||||
wrong_count = receive_count = send_count = 0;
|
||||
send_freq = -1.f;
|
||||
immediateFreq = integralFreq = exp_freq = 0.f;
|
||||
headerPtr = dataPtr = sendDataPtr = 0;
|
||||
headerSize = dataSize = sendDataSize = 0;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
type_rec = type_send = PIProtocol::None;
|
||||
devSenderState = devReceiverState = "Unknown";
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setDevice(const PIString & dev_ip, int speed_port) {
|
||||
if (type == PIProtocol::Serial) {
|
||||
serial->setDevice(dev_ip);
|
||||
serial->setSpeed(speed_port);
|
||||
devName = dev_ip;
|
||||
}
|
||||
if (type == PIProtocol::Ethernet) {
|
||||
ether->setReadAddress(dev_ip, speed_port);
|
||||
devName = dev_ip + ":" + itos(speed_port);
|
||||
void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed) {
|
||||
if (type_rec == PIProtocol::Serial) {
|
||||
ser->setDevice(device);
|
||||
ser->setSpeed(speed);
|
||||
devReceiverName = device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::setExpectedFrequency(float frequency)
|
||||
{
|
||||
exp_freq = frequency;
|
||||
if (exp_freq < 3.33) pckt_cnt_max = 10;
|
||||
else pckt_cnt_max = 3 * (int)exp_freq;
|
||||
last_packets.resize(pckt_cnt_max);
|
||||
timer = new PITimer(diag_event, this);
|
||||
timer->start(1000. / exp_freq);
|
||||
timer->reset();
|
||||
void PIProtocol::setReceiverDevice(const PIString & ip, int port) {
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
eth->setReadAddress(ip, port);
|
||||
devReceiverName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::startReceive()
|
||||
{
|
||||
if (type == PIProtocol::Serial) serial->start();
|
||||
if (type == PIProtocol::Ethernet) ether->start();
|
||||
void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed) {
|
||||
if (type_send == PIProtocol::Serial) {
|
||||
ser->setDevice(device);
|
||||
ser->setSpeed(speed);
|
||||
devSenderName = device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::stopReceive()
|
||||
{
|
||||
if (type == PIProtocol::Serial) serial->stop();
|
||||
if (type == PIProtocol::Ethernet) ether->stop();
|
||||
void PIProtocol::setSenderDevice(const PIString & ip, int port) {
|
||||
if (type_send == PIProtocol::Ethernet) {
|
||||
eth->setReadAddress(ip, port);
|
||||
devSenderName = ip + ":" + PIString::fromNumber(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PIProtocol::received(void * t, char * data) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
memcpy(p->dataPtr, data, p->dataSize);
|
||||
p->work = true;
|
||||
//p->lock();
|
||||
if (p->validate())
|
||||
{
|
||||
//p->unlock();
|
||||
p->receive_count++;
|
||||
p->cur_pckt = 1;
|
||||
return true;
|
||||
}
|
||||
//p->unlock();
|
||||
p->wrong_count++;
|
||||
return false;
|
||||
void PIProtocol::setExpectedFrequency(float frequency) {
|
||||
exp_freq = frequency;
|
||||
if (exp_freq < 10.f / 3.f) pckt_cnt_max = 10;
|
||||
else pckt_cnt_max = round(3.f * exp_freq);
|
||||
last_packets.resize(pckt_cnt_max);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::diag_event(void * t) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->calc_freq();
|
||||
p->calc_diag();
|
||||
p->check_state();
|
||||
void PIProtocol::startReceive(float exp_frequency) {
|
||||
if (exp_frequency > 0.f) exp_freq = exp_frequency;
|
||||
if (type_rec == PIProtocol::Serial) ser->start();
|
||||
if (type_rec == PIProtocol::Ethernet) eth->start();
|
||||
if (exp_freq <= 0.f) return;
|
||||
setExpectedFrequency(exp_freq);
|
||||
diagTimer->start(1000. / exp_freq);
|
||||
diagTimer->reset();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::startSend(float frequency) {
|
||||
if (frequency > 0.f) send_freq = frequency;
|
||||
if (send_freq <= 0.f) return;
|
||||
sendTimer->start(1000. / send_freq);
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::stopReceive() {
|
||||
if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
diagTimer->stop();
|
||||
}
|
||||
|
||||
|
||||
bool PIProtocol::receiveEvent(void * t, char * data, int size) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
if (!p->receive(data, size)) return false;
|
||||
p->work = true;
|
||||
//p->lock();
|
||||
if (p->validate())
|
||||
{
|
||||
//p->unlock();
|
||||
p->receive_count++;
|
||||
p->cur_pckt = 1;
|
||||
if (p->ret_func != 0) p->ret_func(p);
|
||||
return true;
|
||||
}
|
||||
//p->unlock();
|
||||
p->wrong_count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::diagEvent(void * t) {
|
||||
PIProtocol * p = (PIProtocol * )t;
|
||||
p->calc_freq();
|
||||
p->calc_diag();
|
||||
p->check_state();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_diag() {
|
||||
PIProtocol::Quality diag;
|
||||
if (!work) {
|
||||
diag = PIProtocol::Unknown;
|
||||
return;
|
||||
}
|
||||
if (pckt_cnt < pckt_cnt_max) {
|
||||
last_packets[pckt_cnt] = cur_pckt;
|
||||
pckt_cnt++;
|
||||
} else {
|
||||
packets[(int)last_packets.back()]--;
|
||||
last_packets.pop_back();
|
||||
last_packets.push_front(cur_pckt);
|
||||
}
|
||||
packets[(int)cur_pckt]++;
|
||||
cur_pckt = 0;
|
||||
float good_percents;
|
||||
good_percents = (float)packets[1] / pckt_cnt * 100.0f;
|
||||
if (good_percents == 0.0) diag = PIProtocol::Failure;
|
||||
else if (good_percents <= 20.0) diag = PIProtocol::Bad;
|
||||
else if (good_percents > 20.0 && good_percents <= 80.0) diag = PIProtocol::Average;
|
||||
else diag = PIProtocol::Good;
|
||||
if (diag != net_diag) net_diag = diag;
|
||||
PIProtocol::Quality diag;
|
||||
if (!work) {
|
||||
diag = PIProtocol::Unknown;
|
||||
return;
|
||||
}
|
||||
if (pckt_cnt < pckt_cnt_max) {
|
||||
last_packets[pckt_cnt] = cur_pckt;
|
||||
pckt_cnt++;
|
||||
} else {
|
||||
packets[(int)last_packets.back()]--;
|
||||
last_packets.pop_back();
|
||||
last_packets.push_front(cur_pckt);
|
||||
}
|
||||
packets[(int)cur_pckt]++;
|
||||
cur_pckt = 0;
|
||||
float good_percents;
|
||||
good_percents = (float)packets[1] / pckt_cnt * 100.f;
|
||||
if (good_percents == 0.f) diag = PIProtocol::Failure;
|
||||
else if (good_percents <= 20.f) diag = PIProtocol::Bad;
|
||||
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
||||
else diag = PIProtocol::Good;
|
||||
if (diag != net_diag) net_diag = diag;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_freq() {
|
||||
tf = 1000. / timer->elapsed_m();
|
||||
timer->reset();
|
||||
if (cur_pckt != 1) tf = 0.;
|
||||
immediateFreq = tf;
|
||||
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
|
||||
last_freq.push_back(tf);
|
||||
tf = last_freq[0];
|
||||
for (uint i = 1; i < last_freq.size(); ++i)
|
||||
tf += last_freq[i];
|
||||
integralFreq = tf / last_freq.size();
|
||||
tf = 1000.f / diagTimer->elapsed_m();
|
||||
diagTimer->reset();
|
||||
if (cur_pckt != 1) tf = 0.f;
|
||||
immediateFreq = tf;
|
||||
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
|
||||
last_freq.push_back(tf);
|
||||
tf = last_freq[0];
|
||||
for (uint i = 1; i < last_freq.size(); ++i)
|
||||
tf += last_freq[i];
|
||||
integralFreq = tf / last_freq.size();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::check_state() {
|
||||
if (type == PIProtocol::Serial) {
|
||||
if (serial->initialized()) devState = "Initialized";
|
||||
else devState = "Uninitialized";
|
||||
}
|
||||
if (type == PIProtocol::Ethernet) {
|
||||
if (ether->initialized()) devState = "Initialized";
|
||||
else devState = "Uninitialized";
|
||||
}
|
||||
if (type_send == PIProtocol::Serial) {
|
||||
if (ser->initialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
return;
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet) {
|
||||
if (eth->senderInitialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
return;
|
||||
}
|
||||
if (type_rec == PIProtocol::Serial) {
|
||||
if (ser->initialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
return;
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (eth->receiverInitialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::send(const void * data, int size) {
|
||||
if (data == 0 || size == 0) return;
|
||||
if (!aboutSend()) return;
|
||||
if (type_rec == PIProtocol::Serial)
|
||||
if (ser->send((char * )data, size))
|
||||
send_count++;
|
||||
if (type_rec == PIProtocol::Ethernet)
|
||||
if (eth->send((char * )data, size))
|
||||
send_count++;
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::send() {
|
||||
//lock();
|
||||
memcpy(packet, sendDataPtr, sendDataSize);
|
||||
//unlock();
|
||||
if (type == PIProtocol::Serial)
|
||||
if (serial->send(packet, sendDataSize))
|
||||
send_count++;
|
||||
if (type == PIProtocol::Ethernet)
|
||||
if (ether->send(packet, sendDataSize))
|
||||
send_count++;
|
||||
//lock();
|
||||
//memcpy(packet, sendDataPtr, sendDataSize);
|
||||
//unlock();
|
||||
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||
if (!aboutSend()) return;
|
||||
if (type_rec == PIProtocol::Serial)
|
||||
if (ser->send((char * )sendDataPtr, sendDataSize))
|
||||
send_count++;
|
||||
if (type_rec == PIProtocol::Ethernet)
|
||||
if (eth->send((char * )sendDataPtr, sendDataSize))
|
||||
send_count++;
|
||||
}
|
||||
|
||||
149
piprotocol.h
149
piprotocol.h
@@ -4,77 +4,108 @@
|
||||
#include "piserial.h"
|
||||
#include "piethernet.h"
|
||||
#include "pitimer.h"
|
||||
#include "piconfig.h"
|
||||
#include "math.h"
|
||||
|
||||
typedef void (*ReceiveFunc)(void * );
|
||||
|
||||
class PIProtocol
|
||||
{
|
||||
enum Type {Serial, Ethernet};
|
||||
enum Type {None, Serial, Ethernet};
|
||||
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
||||
|
||||
public:
|
||||
PIProtocol(PIString devName, int speed, void * headerPtr, int headerSize, void * dataPtr, int dataSize); // for RS
|
||||
PIProtocol(PIString ip, int port, void * dataPtr, int dataSize); // for Ethernet
|
||||
~PIProtocol();
|
||||
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
||||
void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config
|
||||
~PIProtocol();
|
||||
|
||||
void startReceive(float exp_frequency = -1.f); // if "frequency = -1" used last passed value
|
||||
void stopReceive();
|
||||
void setExpectedFrequency(float frequency); // for connection quality diagnostic
|
||||
void setReceiverDevice(const PIString & device, PISerial::Speed speed); // for Serial
|
||||
void setReceiverDevice(const PIString & ip, int port); // for Ethernet
|
||||
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize;}
|
||||
void setReceiverAddress(const PIString & ip, int port) {if (type_send == PIProtocol::Ethernet && eth != 0) eth->setSendAddress(ip, port);} // for Ethernet
|
||||
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
|
||||
|
||||
void startSend(float frequency = -1.f); // if "frequency = -1" used last passed value
|
||||
void stopSend() {sendTimer->stop();}
|
||||
void setSenderFrequency(float frequency) {send_freq = frequency;}
|
||||
void setSenderDevice(const PIString & device, PISerial::Speed speed); // for Serial
|
||||
void setSenderDevice(const PIString & ip, int port); // for Ethernet
|
||||
void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;}
|
||||
void setSenderAddress(const PIString & ip, int port) {if (type_send == PIProtocol::Ethernet && eth != 0) eth->setSendAddress(ip, port);} // for Ethernet
|
||||
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
|
||||
|
||||
void send();
|
||||
void send(const void * data, int size);
|
||||
|
||||
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
||||
|
||||
void startReceive(); // start receive
|
||||
void stopReceive(); // stop receive
|
||||
void startSend(float frequency = 20.f) {sendtimer->start(frequency > 0 ? 1000.f / frequency : 1000);} // start sending
|
||||
void stopSend() {sendtimer->stop();} // stop sending
|
||||
void setDevice(const PIString & dev_ip, int speed_port);
|
||||
void setSendData(void * dataPtr, int dataSize) {sendDataPtr = (unsigned char * )dataPtr; sendDataSize = dataSize;}
|
||||
void setReceiveData(void * dataPtr, int dataSize) {this->dataPtr = (unsigned char * )dataPtr; this->dataSize = dataSize;}
|
||||
void setSendAddress(const PIString & ip, int port) {if (type == PIProtocol::Ethernet) ether->setSendAddress(ip, port);} // for Ethernet
|
||||
void setParameters(Flags<PISerial::Parameters> parameters) {if (type == PIProtocol::Serial) serial->setParameters(parameters);} // for RS
|
||||
|
||||
void setExpectedFrequency(float frequency); // for start diagnostic connection quality
|
||||
float * immediateFrequency_ptr() {return &immediateFreq;}
|
||||
float * integralFrequency_ptr() {return &integralFreq;}
|
||||
unsigned long long int * wrongCount_ptr() {return &wrong_count;}
|
||||
unsigned long long int * receiveCount_ptr() {return &receive_count;}
|
||||
unsigned long long int * sendCount_ptr() {return &send_count;}
|
||||
PIProtocol::Quality * quality_ptr() {return &net_diag;}
|
||||
PIString * deviceState_ptr() {return &devState;}
|
||||
PIString deviceName() {return devName;}
|
||||
float immediateFrequency() {return immediateFreq;}
|
||||
float integralFrequency() {return integralFreq;}
|
||||
float * immediateFrequency_ptr() {return &immediateFreq;}
|
||||
float * integralFrequency_ptr() {return &integralFreq;}
|
||||
ullong receiveCount() {return receive_count;}
|
||||
ullong * receiveCount_ptr() {return &receive_count;}
|
||||
ullong wrongCount() {return wrong_count;}
|
||||
ullong * wrongCount_ptr() {return &wrong_count;}
|
||||
ullong sendCount() {return send_count;}
|
||||
ullong * sendCount_ptr() {return &send_count;}
|
||||
PIProtocol::Quality quality() {return net_diag;} // receive quality
|
||||
int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer
|
||||
PIString receiverDeviceName() {return devReceiverName;}
|
||||
PIString senderDeviceName() {return devSenderName;}
|
||||
PIString receiverDeviceState() {return devReceiverState;}
|
||||
PIString * receiverDeviceState_ptr() {return &devReceiverState;}
|
||||
PIString senderDeviceState() {return devSenderState;}
|
||||
PIString * senderDeviceState_ptr() {return &devSenderState;}
|
||||
|
||||
protected:
|
||||
virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct
|
||||
virtual unsigned int checksum(unsigned char * data, int size) // function for checksum
|
||||
{
|
||||
unsigned char c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += data[i];
|
||||
c = ~(c + 1);
|
||||
return c;
|
||||
}
|
||||
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
||||
virtual bool receive(char * data, int size) {memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
|
||||
virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct
|
||||
virtual uint checksum_i(void * data, int size) { // function for checksum (uint)
|
||||
uint c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
c = ~(c + 1);
|
||||
return c;
|
||||
}
|
||||
virtual uchar checksum_c(void * data, int size) { // function for checksum (uchar)
|
||||
uchar c = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
c += ((uchar*)data)[i];
|
||||
c = ~(c + 1);
|
||||
return c;
|
||||
}
|
||||
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
||||
|
||||
void init();
|
||||
void send();
|
||||
void check_state();
|
||||
void calc_freq();
|
||||
void calc_diag();
|
||||
static bool received(void * t, char * data);
|
||||
static void diag_event(void * t);
|
||||
void init();
|
||||
void check_state();
|
||||
void calc_freq();
|
||||
void calc_diag();
|
||||
|
||||
PISerial * serial;
|
||||
PIEthernet * ether;
|
||||
unsigned int dataSize, headerSize, sendDataSize;
|
||||
unsigned char * dataPtr, * headerPtr, * sendDataPtr;
|
||||
PISerial * ser;
|
||||
PIEthernet * eth;
|
||||
uint dataSize, headerSize, sendDataSize;
|
||||
uchar * dataPtr, * headerPtr, * sendDataPtr;
|
||||
|
||||
private:
|
||||
static void run(void * e) {PIProtocol* p = (PIProtocol*)e; if (p->aboutSend()) p->send();}
|
||||
PITimer * timer, * sendtimer;
|
||||
PIProtocol::Type type;
|
||||
PIProtocol::Quality net_diag;
|
||||
deque<float> last_freq;
|
||||
deque<char> last_packets;
|
||||
PIString devState, devName;
|
||||
bool work;
|
||||
float exp_freq, immediateFreq, integralFreq, tf;
|
||||
int packets[2];
|
||||
static void sendEvent(void * e) {((PIProtocol * )e)->send();}
|
||||
static bool receiveEvent(void * t, char * data, int size);
|
||||
static void diagEvent(void * t);
|
||||
ReceiveFunc ret_func;
|
||||
PITimer * diagTimer, * sendTimer;
|
||||
PIProtocol::Type type_send, type_rec;
|
||||
PIProtocol::Quality net_diag;
|
||||
deque<float> last_freq;
|
||||
deque<char> last_packets;
|
||||
PIString devReceiverName, devReceiverState, devSenderName, devSenderState;
|
||||
bool work;
|
||||
float exp_freq, send_freq, immediateFreq, integralFreq, tf;
|
||||
int packets[2];
|
||||
uint pckt_cnt, pckt_cnt_max;
|
||||
char * packet;
|
||||
char cur_pckt;
|
||||
unsigned long long int wrong_count, receive_count, send_count;
|
||||
char * packet, cur_pckt;
|
||||
ullong wrong_count, receive_count, send_count;
|
||||
};
|
||||
|
||||
#endif // PIPROTOCOL_H
|
||||
|
||||
58
piserial.cpp
58
piserial.cpp
@@ -9,19 +9,21 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() {
|
||||
dataSize = headerSize = 0;
|
||||
headerPtr = 0;
|
||||
ret_func = slot;
|
||||
buffer = new char[BUFFER_SIZE];
|
||||
sbuffer = new char[BUFFER_SIZE];
|
||||
//buffer = new char[BUFFER_SIZE];
|
||||
//sbuffer = new char[BUFFER_SIZE];
|
||||
#ifdef WINDOWS
|
||||
hCom = 0;
|
||||
#endif
|
||||
ispeed = ospeed = B115200;
|
||||
ispeed = ospeed = S115200;
|
||||
}
|
||||
|
||||
|
||||
PISerial::~PISerial() {
|
||||
terminate();
|
||||
delete buffer;
|
||||
delete sbuffer;
|
||||
/*if (buffer != 0) delete buffer;
|
||||
buffer = 0;
|
||||
if (sbuffer != 0) delete sbuffer;
|
||||
sbuffer = 0;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +50,24 @@ void PISerial::terminate() {
|
||||
}
|
||||
|
||||
|
||||
int PISerial::convertSpeed(PISerial::Speed speed) {
|
||||
switch (speed) {
|
||||
case S110: return B110;
|
||||
case S300: return B300;
|
||||
case S600: return B600;
|
||||
case S1200: return B1200;
|
||||
case S2400: return B2400;
|
||||
case S4800: return B4800;
|
||||
case S9600: return B9600;
|
||||
case S19200: return B19200;
|
||||
case S38400: return B38400;
|
||||
case S57600: return B57600;
|
||||
case S115200: return B115200;
|
||||
}
|
||||
return B115200;
|
||||
}
|
||||
|
||||
|
||||
void PISerial::begin() {
|
||||
sbuffIndex = 0;
|
||||
startIndex = 0;
|
||||
@@ -89,7 +109,7 @@ void PISerial::run() {
|
||||
{
|
||||
//cout << "vsdfgvb" << endl;
|
||||
memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize);
|
||||
if (ret_func(data, pbuffer))
|
||||
if (ret_func(data, pbuffer, dataSize))
|
||||
{
|
||||
startIndex = 0;
|
||||
sbuffIndex = -1;
|
||||
@@ -143,7 +163,7 @@ void PISerial::run() {
|
||||
b = buffer[i];
|
||||
sbuffer[sbuffIndex] = b;
|
||||
if (sbuffIndex == dataSize - 1) {
|
||||
if (ret_func != 0) ret_func(data, sbuffer);
|
||||
if (ret_func != 0) ret_func(data, sbuffer, dataSize);
|
||||
sbuffIndex = -1;
|
||||
}
|
||||
sbuffIndex++;
|
||||
@@ -163,7 +183,7 @@ bool PISerial::init() {
|
||||
#ifdef WINDOWS
|
||||
hCom = CreateFileA(devName.stdString().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
if(hCom == INVALID_HANDLE_VALUE) {
|
||||
cout << "[PISerial] Unable to open " << devName << endl;
|
||||
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
@@ -174,7 +194,7 @@ bool PISerial::init() {
|
||||
times.WriteTotalTimeoutConstant = 0;
|
||||
times.WriteTotalTimeoutMultiplier = 1;
|
||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||
cout << "[PISerial] Unable to set timeouts for " << devName << endl;
|
||||
cout << "[PISerial] Unable to set timeouts for \"" << devName << "\"" << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
@@ -184,12 +204,12 @@ bool PISerial::init() {
|
||||
GetCommState(hCom, &sdesc);
|
||||
desc = sdesc;
|
||||
desc.DCBlength = sizeof(desc);
|
||||
desc.BaudRate = ispeed;
|
||||
desc.BaudRate = convertSpeed(ispeed);
|
||||
desc.ByteSize = 8;
|
||||
desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1;
|
||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
if (SetCommState(hCom, &desc) == -1) {
|
||||
cout << "[PISerial] Unable to set comm state for " << devName << endl;
|
||||
cout << "[PISerial] Unable to set comm state for \"" << devName << "\"" << endl;
|
||||
CloseHandle(hCom);
|
||||
fd = -1;
|
||||
return false;
|
||||
@@ -197,7 +217,7 @@ bool PISerial::init() {
|
||||
#else
|
||||
fd = open(devName.data(), O_NOCTTY | O_RDWR);
|
||||
if(fd == -1) {
|
||||
cout << "[PISerial] Unable to open " << devName << endl;
|
||||
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||
return false;
|
||||
}
|
||||
fcntl(fd, F_SETFL, 0);
|
||||
@@ -206,16 +226,20 @@ bool PISerial::init() {
|
||||
sdesc = desc;
|
||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
||||
desc.c_cflag = CLOCAL | CREAD | CSIZE;
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag &= CSTOPB;
|
||||
if (params[PISerial::IgnoreParityControl]) desc.c_iflag &= IGNPAR ; // | INPCK | IGNBRK | IGNCR;
|
||||
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
|
||||
if (!params[PISerial::ParityControl]) {
|
||||
desc.c_iflag |= INPCK;
|
||||
desc.c_cflag |= PARENB;
|
||||
if (!params[PISerial::ParityOdd]) desc.c_cflag |= PARODD;
|
||||
}
|
||||
desc.c_cc[VMIN] = 0;
|
||||
desc.c_cc[VTIME] = 1;
|
||||
|
||||
cfsetispeed(&desc, ispeed);
|
||||
cfsetospeed(&desc, ospeed);
|
||||
cfsetispeed(&desc, convertSpeed(ispeed));
|
||||
cfsetospeed(&desc, convertSpeed(ospeed));
|
||||
|
||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
||||
cout << "[PISerial] Can`t set attributes for " << devName << endl;
|
||||
cout << "[PISerial] Can`t set attributes for \"" << devName << "\"" << endl;
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
36
piserial.h
36
piserial.h
@@ -25,23 +25,36 @@
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
typedef bool (*SerialFunc)(void * , char * );
|
||||
typedef bool (*SerialFunc)(void * , char * , int );
|
||||
|
||||
class PISerial: public PIThread
|
||||
{
|
||||
public:
|
||||
// slot is any function format "bool <func>(void*, char*)"
|
||||
// slot is any function format "bool <func>(void*, char*, int)"
|
||||
PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0);
|
||||
~PISerial();
|
||||
|
||||
enum Parameters {IgnoreParityControl = 0x01, TwoStopBits = 0x02};
|
||||
enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04};
|
||||
enum Speed {
|
||||
S110 = 110,
|
||||
S300 = 300,
|
||||
S600 = 600,
|
||||
S1200 = 1200,
|
||||
S2400 = 2400,
|
||||
S4800 = 4800,
|
||||
S9600 = 9600,
|
||||
S19200 = 19200,
|
||||
S38400 = 38400,
|
||||
S57600 = 57600,
|
||||
S115200 = 115200
|
||||
};
|
||||
|
||||
void setSlot(SerialFunc func) {ret_func = func;}
|
||||
void setSpeed(int speed) {ospeed = ispeed = speed;}
|
||||
void setOutSpeed(int speed) {ospeed = speed;}
|
||||
void setInSpeed(int speed) {ispeed = speed;}
|
||||
void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;}
|
||||
void setOutSpeed(PISerial::Speed speed) {ospeed = speed;}
|
||||
void setInSpeed(PISerial::Speed speed) {ispeed = speed;}
|
||||
void setDevice(const PIString & dev) {devName = dev;}
|
||||
void setParameters(Flags<PISerial::Parameters> parameters) {params = parameters;}
|
||||
void setParameters(PIFlags<PISerial::Parameters> parameters) {params = parameters;}
|
||||
void setData(void * d) {data = d;}
|
||||
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr;
|
||||
this->headerSize = headerSize;
|
||||
@@ -53,6 +66,8 @@ public:
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
int convertSpeed(PISerial::Speed speed);
|
||||
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
@@ -65,13 +80,14 @@ private:
|
||||
termios desc, sdesc;
|
||||
uint readed;
|
||||
#endif
|
||||
int fd, ospeed, ispeed;
|
||||
int fd;
|
||||
PISerial::Speed ospeed, ispeed;
|
||||
PIString devName;
|
||||
SerialFunc ret_func;
|
||||
char * buffer, * sbuffer, * hbuffer, * pbuffer;
|
||||
char buffer[BUFFER_SIZE], sbuffer[BUFFER_SIZE], * hbuffer, * pbuffer;
|
||||
void * headerPtr, * data;
|
||||
int dataSize, headerSize, sbuffIndex, startIndex, backIndex;
|
||||
Flags<PISerial::Parameters> params;
|
||||
PIFlags<PISerial::Parameters> params;
|
||||
bool first, tryagain;
|
||||
|
||||
};
|
||||
|
||||
234
pistring.cpp
234
pistring.cpp
@@ -1,14 +1,46 @@
|
||||
#include "pistring.h"
|
||||
|
||||
|
||||
void PIString::appendFromChars(const char * c, int s) {
|
||||
int sz;
|
||||
wchar_t wc;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
if (isascii(c[i])) {
|
||||
push_back(PIChar(c[i]));
|
||||
continue;
|
||||
}
|
||||
sz = mbtowc(&wc, &c[i], 4);
|
||||
switch (sz) {
|
||||
case 4:
|
||||
push_back(PIChar(*(int*)&(c[i])));
|
||||
i += 3;
|
||||
continue;
|
||||
case 3:
|
||||
push_back(PIChar(*(int*)&(c[i])));
|
||||
back().ch &= 0xFFFFFF;
|
||||
i += 2;
|
||||
continue;
|
||||
case 2:
|
||||
push_back(PIChar(*(short * )&(c[i])));
|
||||
++i;
|
||||
continue;
|
||||
default:
|
||||
push_back(PIChar(c[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const char * str) {
|
||||
uint i = 0;
|
||||
while (str[i] != '\0') push_back(str[i++]);
|
||||
int l = 0;
|
||||
while (str[l] != '\0') ++l;
|
||||
appendFromChars(str, l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const string & str) {
|
||||
PIString & PIString::operator +=(const wstring & str) {
|
||||
uint l = str.size();
|
||||
for (uint i = 0; i < l; ++i) push_back(str[i]);
|
||||
return *this;
|
||||
@@ -22,13 +54,6 @@ PIString & PIString::operator +=(const PIString & str) {
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::operator +=(const PIByteArray & ba) {
|
||||
uint l = ba.size();
|
||||
for (uint i = 0; i < l; ++i) push_back(ba[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator ==(const PIString & str) const {
|
||||
uint l = str.size();
|
||||
if (size() != l) return false;
|
||||
@@ -49,6 +74,32 @@ bool PIString::operator !=(const PIString & str) const {
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator <(const PIString & str) const {
|
||||
uint l = str.size();
|
||||
if (size() < l) return true;
|
||||
if (size() > l) return false;
|
||||
for (uint i = 0; i < l; ++i) {
|
||||
if (str[i] == at(i)) continue;
|
||||
if (str[i] < at(i)) return true;
|
||||
else return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PIString::operator >(const PIString & str) const {
|
||||
uint l = str.size();
|
||||
if (size() < l) return false;
|
||||
if (size() > l) return true;
|
||||
for (uint i = 0; i < l; ++i) {
|
||||
if (str[i] == at(i)) continue;
|
||||
if (str[i] < at(i)) return false;
|
||||
else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::mid(const int start, const int len) const {
|
||||
PIString str;
|
||||
int s = start, l = len;
|
||||
@@ -82,24 +133,12 @@ PIString & PIString::cutMid(const int start, const int len) {
|
||||
else {
|
||||
if (l > length() - s)
|
||||
l = length() - s;
|
||||
remove(s, s + l);
|
||||
remove(s, l);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString PIString::trimmed() const {
|
||||
int st = 0, fn = 0;
|
||||
for (int i = 0; i < length(); ++i)
|
||||
if (at(i) != ' ' && at(i) != '\t')
|
||||
{st = i; break;}
|
||||
for (int i = length() - 1; i >= 0; --i)
|
||||
if (at(i) != ' ' && at(i) != '\t')
|
||||
{fn = i; break;}
|
||||
return mid(st, fn - st + 1);
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::trim() {
|
||||
int st = 0, fn = 0;
|
||||
for (int i = 0; i < length(); ++i)
|
||||
@@ -113,9 +152,53 @@ PIString & PIString::trim() {
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIString::split(const PIString & delim) {
|
||||
PIString ts(*this);
|
||||
PIString PIString::trimmed() const {
|
||||
int st = 0, fn = 0;
|
||||
for (int i = 0; i < length(); ++i)
|
||||
if (at(i) != ' ' && at(i) != '\t')
|
||||
{st = i; break;}
|
||||
for (int i = length() - 1; i >= 0; --i)
|
||||
if (at(i) != ' ' && at(i) != '\t')
|
||||
{fn = i; break;}
|
||||
return mid(st, fn - st + 1);
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::replace(int from, int count, const PIString & with) {
|
||||
if (count < length() - from) remove(from, count);
|
||||
else remove(from, length() - from);
|
||||
uint c = with.length();
|
||||
for (uint i = 0; i < c; ++i) insert(from + i, with[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) {
|
||||
int s = find(what);
|
||||
if (s >= 0) replace(s, what.length(), with);
|
||||
if (ok != 0) *ok = (s >= 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
|
||||
bool ok = true;
|
||||
while (ok) replace(what, with, &ok);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIString & PIString::insert(int index, const PIString & str) {
|
||||
uint c = str.length();
|
||||
for (uint i = 0; i < c; ++i) insert(index + i, str[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIString::split(const PIString & delim) const {
|
||||
PIStringList sl;
|
||||
if (isEmpty() || delim.isEmpty()) return sl;
|
||||
PIString ts(*this);
|
||||
int ci = ts.find(delim);
|
||||
while (ci >= 0) {
|
||||
sl << ts.left(ci);
|
||||
@@ -127,7 +210,7 @@ PIStringList PIString::split(const PIString & delim) {
|
||||
}
|
||||
|
||||
|
||||
int PIString::find(const char str, const int start) {
|
||||
int PIString::find(const char str, const int start) const {
|
||||
for (int i = start; i < length(); ++i)
|
||||
if (at(i) == str)
|
||||
return i;
|
||||
@@ -135,7 +218,7 @@ int PIString::find(const char str, const int start) {
|
||||
}
|
||||
|
||||
|
||||
int PIString::find(const PIString str, const int start) {
|
||||
int PIString::find(const PIString str, const int start) const {
|
||||
int l = str.length();
|
||||
for (int i = start; i < length() - l + 1; ++i)
|
||||
if (mid(i, l) == str)
|
||||
@@ -144,7 +227,7 @@ int PIString::find(const PIString str, const int start) {
|
||||
}
|
||||
|
||||
|
||||
int PIString::findLast(const char str, const int start) {
|
||||
int PIString::findLast(const char str, const int start) const {
|
||||
for (int i = length() - 1; i >= start; --i)
|
||||
if (at(i) == str)
|
||||
return i;
|
||||
@@ -152,7 +235,7 @@ int PIString::findLast(const char str, const int start) {
|
||||
}
|
||||
|
||||
|
||||
int PIString::findLast(const PIString str, const int start) {
|
||||
int PIString::findLast(const PIString str, const int start) const {
|
||||
int l = str.length();
|
||||
for (int i = length() - l; i >= start; --i)
|
||||
if (mid(i, l) == str)
|
||||
@@ -164,7 +247,7 @@ int PIString::findLast(const PIString str, const int start) {
|
||||
PIString PIString::toUpperCase() const {
|
||||
PIString str(*this);
|
||||
int l = str.size();
|
||||
for (int i = 0; i < l; ++i) str[i] = chrUpr(str[i]);
|
||||
for (int i = 0; i < l; ++i) str[i] = str[i].toUpper();
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -172,11 +255,78 @@ PIString PIString::toUpperCase() const {
|
||||
PIString PIString::toLowerCase() const {
|
||||
PIString str(*this);
|
||||
int l = str.size();
|
||||
for (int i = 0; i < l; ++i) str[i] = chrLwr(str[i]);
|
||||
for (int i = 0; i < l; ++i) str[i] = str[i].toLower();
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
string PIString::convertToStd() const {
|
||||
string s;
|
||||
if (size() > 0) {
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
if (at(i).isAscii())
|
||||
s.push_back(at(i).toAscii());
|
||||
else {
|
||||
s.push_back(at(i).toCharPtr()[0]);
|
||||
s.push_back(at(i).toCharPtr()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
char PIString::toChar() const {
|
||||
PIString s(toNativeDecimalPoints());
|
||||
char v;
|
||||
sscanf(s.data(), "%c", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
short PIString::toShort() const {
|
||||
PIString s(trimmed().toNativeDecimalPoints());
|
||||
int i;
|
||||
short v;
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (short)i;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (short)i;}
|
||||
sscanf(s.data(), "%hd", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
int PIString::toInt() const {
|
||||
PIString s(trimmed().toNativeDecimalPoints());
|
||||
int v;
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%x", &v); return v;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%o", &v); return v;}
|
||||
sscanf(s.data(), "%d", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
long PIString::toLong() const {
|
||||
PIString s(trimmed().toNativeDecimalPoints());
|
||||
int i;
|
||||
long v;
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (long)i;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (long)i;}
|
||||
sscanf(s.data(), "%ld", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
llong PIString::toLLong() const {
|
||||
PIString s(trimmed().toNativeDecimalPoints());
|
||||
int i;
|
||||
llong v;
|
||||
if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (llong)i;}
|
||||
if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (llong)i;}
|
||||
sscanf(s.data(), "%Ld", &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
char chrUpr(char c) {
|
||||
if (c >= 'a' && c <= 'z') return c + 'A' - 'a';
|
||||
//if (c >= 'а' && c <= 'я') return c + 'А' - 'а';
|
||||
@@ -189,3 +339,25 @@ char chrLwr(char c) {
|
||||
//if (c >= 'А' && c <= 'Я') return c + 'а' - 'А';
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
PIStringList& PIStringList::removeDuplicates() {
|
||||
PIStringList l;
|
||||
PIString s;
|
||||
bool ae;
|
||||
for (uint i = 0; i < size(); ++i) {
|
||||
ae = false;
|
||||
s = at(i);
|
||||
for (uint j = 0; j < l.size(); ++j) {
|
||||
if (s != l[j]) continue;
|
||||
ae = true; break;
|
||||
}
|
||||
if (!ae) {
|
||||
l << s;
|
||||
continue;
|
||||
}
|
||||
remove(i);
|
||||
--i;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
236
pistring.h
236
pistring.h
@@ -2,112 +2,179 @@
|
||||
#define PISTRING_H
|
||||
|
||||
#include "pibytearray.h"
|
||||
#include "pichar.h"
|
||||
|
||||
class PIStringList;
|
||||
|
||||
class PIString: public PIVector<char>
|
||||
class PIString: public PIVector<PIChar>
|
||||
{
|
||||
public:
|
||||
PIString() {;}
|
||||
PIString(const char & c) {*this += c;}
|
||||
|
||||
//inline PIString & operator +=(const char c) {push_back(c); return *this;}
|
||||
PIString & operator +=(const PIChar c) {push_back(c); return *this;}
|
||||
PIString & operator +=(const char * str);
|
||||
PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;}
|
||||
PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s()); return *this;}
|
||||
PIString & operator +=(const PIString & str);
|
||||
PIString & operator +=(const wstring & str);
|
||||
|
||||
//PIString(const char c) {*this += c;}
|
||||
PIString(const PIChar c) {*this += c;}
|
||||
PIString(const char * str) {*this += str;}
|
||||
PIString(const string & str) {*this += str;}
|
||||
PIString(const wstring & str) {*this += str;}
|
||||
PIString(const PIString & str) {*this += str;}
|
||||
PIString(const PIByteArray & ba) {*this += ba;}
|
||||
PIString(const int len, const char c = ' ') {for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const char * str, const int len) {*this += string(str, len);}
|
||||
PIString(const int len, const char c) {for (int i = 0; i < len; ++i) push_back(c);}
|
||||
PIString(const int len, const PIChar & c) {for (int i = 0; i < len; ++i) push_back(c);}
|
||||
|
||||
operator const char*() {return data();}
|
||||
operator const string() {return (size() == 0) ? string() : string(&at(0), size());}
|
||||
inline char & operator [](const int pos) {return at(pos);}
|
||||
inline const char operator [](const int pos) const {return at(pos);}
|
||||
|
||||
PIString & operator +=(const PIString & str);
|
||||
PIString & operator +=(const PIByteArray & ba);
|
||||
inline PIString & operator +=(const char & c) {push_back(c); return *this;}
|
||||
PIString & operator +=(const char * str);
|
||||
PIString & operator +=(const string & str);
|
||||
operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;}
|
||||
#ifdef WINDOWS
|
||||
PIChar operator [](const int pos) const __attribute__ ((optimize(0))) {return at(pos);}
|
||||
#else
|
||||
PIChar operator [](const int pos) const {return at(pos);}
|
||||
#endif
|
||||
PIChar & operator [](const int pos) {return at(pos);}
|
||||
|
||||
bool operator ==(const PIString & str) const;
|
||||
inline bool operator ==(const PIByteArray & ba) const {return *this == PIString(ba);}
|
||||
inline bool operator ==(const char & c) const {return *this == PIString(c);}
|
||||
inline bool operator ==(const char * str) const {return *this == PIString(str);}
|
||||
inline bool operator ==(const string & str) const {return *this == PIString(str);}
|
||||
bool operator ==(const PIChar c) const {return *this == PIString(c);}
|
||||
//inline bool operator ==(const char c) const {return *this == PIString(c);}
|
||||
bool operator ==(const char * str) const {return *this == PIString(str);}
|
||||
bool operator ==(const string & str) const {return *this == PIString(str);}
|
||||
|
||||
bool operator !=(const PIString & str) const;
|
||||
inline bool operator !=(const PIByteArray & ba) const {return *this != PIString(ba);}
|
||||
inline bool operator !=(const char & c) const {return *this != PIString(c);}
|
||||
inline bool operator !=(const char * str) const {return *this != PIString(str);}
|
||||
inline bool operator !=(const string & str) const {return *this != PIString(str);}
|
||||
bool operator !=(const PIChar c) const {return *this != PIString(c);}
|
||||
//inline bool operator !=(const char c) const {return *this != PIString(c);}
|
||||
bool operator !=(const char * str) const {return *this != PIString(str);}
|
||||
bool operator !=(const string & str) const {return *this != PIString(str);}
|
||||
|
||||
inline PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
||||
inline PIString & operator <<(const PIByteArray & ba) {*this += ba; return *this;}
|
||||
inline PIString & operator <<(const char & c) {*this += c; return *this;}
|
||||
inline PIString & operator <<(const char * str) {*this += str; return *this;}
|
||||
inline PIString & operator <<(const string & str) {*this += str; return *this;}
|
||||
inline PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
inline PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
inline PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
inline PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
inline PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
bool operator <(const PIString & str) const;
|
||||
bool operator <(const PIChar c) const {return *this < PIString(c);}
|
||||
//inline bool operator <(const char c) const {return *this < PIString(c);}
|
||||
bool operator <(const char * str) const {return *this < PIString(str);}
|
||||
bool operator <(const string & str) const {return *this < PIString(str);}
|
||||
|
||||
bool operator >(const PIString & str) const;
|
||||
bool operator >(const PIChar c) const {return *this > PIString(c);}
|
||||
//inline bool operator >(const char c) const {return *this > PIString(c);}
|
||||
bool operator >(const char * str) const {return *this > PIString(str);}
|
||||
bool operator >(const string & str) const {return *this > PIString(str);}
|
||||
|
||||
bool operator <=(const PIString & str) const {return !(*this > str);}
|
||||
bool operator <=(const PIChar c) const {return *this <= PIString(c);}
|
||||
//inline bool operator <=(const char c) const {return *this <= PIString(c);}
|
||||
bool operator <=(const char * str) const {return *this <= PIString(str);}
|
||||
bool operator <=(const string & str) const {return *this <= PIString(str);}
|
||||
|
||||
bool operator >=(const PIString & str) const {return !(*this < str);}
|
||||
bool operator >=(const PIChar c) const {return *this >= PIString(c);}
|
||||
//inline bool operator >=(const char c) const {return *this >= PIString(c);}
|
||||
bool operator >=(const char * str) const {return *this >= PIString(str);}
|
||||
bool operator >=(const string & str) const {return *this >= PIString(str);}
|
||||
|
||||
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
||||
//inline PIString & operator <<(const char c) {*this += c; return *this;}
|
||||
PIString & operator <<(const PIChar c) {*this += c; return *this;}
|
||||
PIString & operator <<(const char * str) {*this += str; return *this;}
|
||||
PIString & operator <<(const string & str) {*this += str; return *this;}
|
||||
PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
||||
|
||||
PIString mid(const int start, const int len = -1) const;
|
||||
inline PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
||||
inline PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
||||
PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
||||
PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
||||
PIString & cutMid(const int start, const int len);
|
||||
inline PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
|
||||
inline PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
||||
PIString trimmed() const;
|
||||
PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
|
||||
PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
||||
PIString & trim();
|
||||
const char * data() const {return stdString().c_str();}
|
||||
string stdString() const {return (size() == 0) ? string() : string(&at(0), size());}
|
||||
PIStringList split(const PIString & delim);
|
||||
PIString trimmed() const;
|
||||
PIString & replace(const int from, const int count, const PIString & with);
|
||||
PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;}
|
||||
PIString & replace(const PIString & what, const PIString & with, bool * ok = 0);
|
||||
PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;}
|
||||
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 & insert(const int index, const PIChar & c) {PIVector<PIChar>::insert(index, c); return *this;}
|
||||
PIString & insert(const int index, const char & c) {return insert(index, PIChar(c));}
|
||||
PIString & insert(const int index, const PIString & str);
|
||||
PIString & insert(const int index, const char * c) {return insert(index, PIString(c));}
|
||||
PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;}
|
||||
PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;}
|
||||
|
||||
const char * data() {std_string = convertToStd(); return std_string.c_str();}
|
||||
const string stdString() const {return convertToStd();}
|
||||
wstring stdWString() const {return convertToWString();}
|
||||
PIByteArray toByteArray() {convertToStd(); return PIByteArray(std_string.c_str(), std_string.length());}
|
||||
PIStringList split(const PIString & delim) const;
|
||||
|
||||
PIString toUpperCase() const;
|
||||
PIString toLowerCase() const;
|
||||
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);}
|
||||
|
||||
int find(const char str, const int start = 0);
|
||||
int find(const PIString str, const int start = 0);
|
||||
inline int find(const char * str, const int start = 0) {return find(PIString(str), start);}
|
||||
inline int find(const string str, const int start = 0) {return find(PIString(str), start);}
|
||||
int findLast(const char str, const int start = 0);
|
||||
int findLast(const PIString str, const int start = 0);
|
||||
inline int findLast(const char * str, const int start = 0) {return findLast(PIString(str), start);}
|
||||
inline int findLast(const string str, const int start = 0) {return findLast(PIString(str), start);}
|
||||
int find(const char str, const int start = 0) const;
|
||||
int find(const PIString str, const int start = 0) const;
|
||||
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
|
||||
int find(const string str, const int start = 0) const {return find(PIString(str), start);}
|
||||
int findLast(const char str, const int start = 0) const;
|
||||
int findLast(const PIString str, const int start = 0) const;
|
||||
int findLast(const char * 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);}
|
||||
|
||||
inline int length() const {return size();}
|
||||
inline bool isEmpty() const {return size() == 0;}
|
||||
int length() const {return size();}
|
||||
bool isEmpty() const {return (size() == 0 || *this == "");}
|
||||
|
||||
int toInt() const {return atoi(data());}
|
||||
short toShort() const {return (short)atoi(data());}
|
||||
long toLong() const {return atol(data());}
|
||||
float toFloat() const {return (float)atof(data());}
|
||||
double toDouble() const {return atof(data());}
|
||||
inline PIByteArray toBase64() {return PIByteArray(data(), size()).toBase64();}
|
||||
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;}
|
||||
char toChar() const;
|
||||
short toShort() const;
|
||||
int toInt() const;
|
||||
long toLong() const;
|
||||
llong toLLong() const;
|
||||
float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());}
|
||||
double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());}
|
||||
|
||||
inline PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
|
||||
inline PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
|
||||
inline PIString & setNumber(const long value) {clear(); *this += ltos(value); return *this;}
|
||||
inline PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;}
|
||||
inline PIString & setNumber(const double value) {clear(); *this += dtos(value); return *this;}
|
||||
//inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
|
||||
PIString & setNumber(const long value) {clear(); *this += ltos(value); return *this;}
|
||||
PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;}
|
||||
PIString & setNumber(const double value) {clear(); *this += dtos(value); return *this;}
|
||||
PIString & setNumber(const ldouble value) {clear(); *this += dtos(value); return *this;}
|
||||
|
||||
inline static PIString fromNumber(const int value) {return PIString(itos(value));}
|
||||
inline static PIString fromNumber(const uint value) {return PIString(itos(value));}
|
||||
inline static PIString fromNumber(const short value) {return PIString(itos(value));}
|
||||
inline static PIString fromNumber(const long value) {return PIString(ltos(value));}
|
||||
inline static PIString fromNumber(const float value) {return PIString(ftos(value));}
|
||||
inline static PIString fromNumber(const double value) {return PIString(dtos(value));}
|
||||
//inline static PIString fromNumber(const char value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const int value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const uint value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const short value) {return PIString(itos(value));}
|
||||
static PIString fromNumber(const long value) {return PIString(ltos(value));}
|
||||
static PIString fromNumber(const float value) {return PIString(ftos(value));}
|
||||
static PIString fromNumber(const double value) {return PIString(dtos(value));}
|
||||
static PIString fromNumber(const ldouble value) {return PIString(dtos(value));}
|
||||
static PIString fromBool(const bool value) {return PIString(value ? "true" : "false");}
|
||||
|
||||
private:
|
||||
void appendFromChars(const char * c, int s);
|
||||
string convertToStd() const;
|
||||
wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;}
|
||||
|
||||
string std_string;
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;}
|
||||
|
||||
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
|
||||
|
||||
inline PIString operator +(const PIString & f, const PIByteArray & ba) {PIString s(f); s += ba; return s;}
|
||||
inline PIString operator +(const PIString & f, const char & c) {PIString s(f); s.push_back(c); return s;}
|
||||
//inline PIString operator +(const PIString & f, const char c) {PIString s(f); s.push_back(c); return s;}
|
||||
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
|
||||
inline PIString operator +(const PIString & f, const string & str) {PIString s(f); s += str; return s;}
|
||||
|
||||
inline PIString operator +(const PIByteArray & ba, const PIString & f) {return PIString(ba) + f;}
|
||||
inline PIString operator +(const char & c, const PIString & f) {return PIString(c) + f;}
|
||||
//inline PIString operator +(const char c, const PIString & f) {return PIString(c) + f;}
|
||||
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
|
||||
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
|
||||
|
||||
@@ -119,20 +186,29 @@ class PIStringList: public PIVector<PIString>
|
||||
public:
|
||||
PIStringList() {;}
|
||||
PIStringList(const PIString & str) {push_back(str);}
|
||||
PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);}
|
||||
PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);}
|
||||
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);}
|
||||
|
||||
inline PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}
|
||||
PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}
|
||||
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, uint count) {PIVector<PIString>::remove(num, count); return *this;}
|
||||
PIStringList & removeDuplicates();
|
||||
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
||||
|
||||
inline PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
|
||||
inline PIStringList & operator <<(const PIByteArray & ba) {push_back(ba); return *this;}
|
||||
inline PIStringList & operator <<(const char & c) {push_back(PIString(c)); return *this;}
|
||||
inline PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;}
|
||||
inline PIStringList & operator <<(const string & str) {push_back(str); return *this;}
|
||||
inline PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
inline PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
inline PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
inline PIStringList & operator <<(const float & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
inline PIStringList & operator <<(const double & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
|
||||
//inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;}
|
||||
PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;}
|
||||
PIStringList & operator <<(const string & str) {push_back(str); return *this;}
|
||||
PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
PIStringList & operator <<(const float & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
PIStringList & operator <<(const double & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << '\"' << v[i] << '\"'; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||
|
||||
#endif // PISTRING_H
|
||||
|
||||
61
pithread.cpp
61
pithread.cpp
@@ -17,7 +17,7 @@ PIThread::~PIThread() {
|
||||
|
||||
bool PIThread::start(int timer_delay) {
|
||||
pthread_attr_t attr;
|
||||
terminating = false;
|
||||
terminating = running = false;
|
||||
timer = timer_delay;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedparam(&attr, &sparam);
|
||||
@@ -29,13 +29,25 @@ bool PIThread::start(int timer_delay) {
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::startOnce() {
|
||||
pthread_attr_t attr;
|
||||
terminating = running = false;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedparam(&attr, &sparam);
|
||||
if (pthread_create(&thread, &attr, thread_function_once, this) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void * PIThread::thread_function(void * t) {
|
||||
PIThread * ct = (PIThread * )t;
|
||||
ct->running = true;
|
||||
ct->begin();
|
||||
while (!ct->terminating) {
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->lockRun) ct->mutex_.unlock();;
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
if (ct->timer > 0) msleep(ct->timer);
|
||||
}
|
||||
ct->end();
|
||||
@@ -46,9 +58,24 @@ void * PIThread::thread_function(void * t) {
|
||||
}
|
||||
|
||||
|
||||
void * PIThread::thread_function_once(void * t) {
|
||||
PIThread * ct = (PIThread * )t;
|
||||
ct->running = true;
|
||||
ct->begin();
|
||||
if (ct->lockRun) ct->mutex_.lock();
|
||||
ct->run();
|
||||
if (ct->lockRun) ct->mutex_.unlock();
|
||||
ct->end();
|
||||
ct->running = false;
|
||||
//cout << "thread " << t << " exiting ... " << endl;
|
||||
pthread_exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PIThread::setPriority(PIThread::Priority prior) {
|
||||
priority_ = prior;
|
||||
#if __QNX__ || __WIN32__
|
||||
#ifndef LINUX
|
||||
sparam.sched_priority = (int)priority_;
|
||||
#else
|
||||
sparam.__sched_priority = (int)priority_;
|
||||
@@ -59,3 +86,31 @@ void PIThread::setPriority(PIThread::Priority prior) {
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::waitForFinish(int timeout_msecs) {
|
||||
if (timeout_msecs < 0) {
|
||||
while (running)
|
||||
msleep(1);
|
||||
return true;
|
||||
}
|
||||
int cnt = 0;
|
||||
while (running && cnt < timeout_msecs) {
|
||||
msleep(1);
|
||||
++cnt;
|
||||
}
|
||||
return cnt < timeout_msecs;
|
||||
}
|
||||
|
||||
|
||||
bool PIThread::waitForStart(int timeout_msecs) {
|
||||
if (timeout_msecs < 0) {
|
||||
while (!running)
|
||||
msleep(1);
|
||||
return true;
|
||||
}
|
||||
int cnt = 0;
|
||||
while (!running && cnt < timeout_msecs) {
|
||||
msleep(1);
|
||||
++cnt;
|
||||
}
|
||||
return cnt < timeout_msecs;
|
||||
}
|
||||
|
||||
16
pithread.h
16
pithread.h
@@ -2,13 +2,13 @@
|
||||
#define PITHREAD_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "piincludes.h"
|
||||
#include <signal.h>
|
||||
#include "pimutex.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
inline void msleep(int msecs) {Sleep(msecs);}
|
||||
inline void msleep(int msecs) {Sleep(msecs);}
|
||||
#else
|
||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||
#endif
|
||||
|
||||
class PIThread {
|
||||
@@ -31,13 +31,16 @@ public:
|
||||
#endif
|
||||
|
||||
bool start(int timer_delay = -1);
|
||||
void stop() {terminating = true;}
|
||||
bool startOnce();
|
||||
void stop(bool wait = false) {terminating = true; if (wait) waitForFinish();}
|
||||
void terminate() {kill(thread, SIGKILL); end(); running = false;}
|
||||
void setPriority(PIThread::Priority prior);
|
||||
PIThread::Priority priority() const {return priority_;}
|
||||
bool isRunning() const {return running;}
|
||||
void waitForFinish() {while (running) msleep(1);}
|
||||
bool waitForFinish(int timeout_msecs = -1);
|
||||
bool waitForStart(int timeout_msecs = -1);
|
||||
void needLockRun(bool need) {lockRun = need;}
|
||||
void lock() {mutex_.lock();;}
|
||||
void lock() {mutex_.lock();}
|
||||
void unlock() {mutex_.unlock();}
|
||||
PIMutex & mutex() {return mutex_;}
|
||||
|
||||
@@ -48,6 +51,7 @@ private:
|
||||
|
||||
protected:
|
||||
static void * thread_function(void * t);
|
||||
static void * thread_function_once(void * t);
|
||||
|
||||
volatile bool terminating, running, lockRun;
|
||||
int timer, policy;
|
||||
|
||||
52
pitimer.cpp
52
pitimer.cpp
@@ -4,19 +4,20 @@
|
||||
PITimer::PITimer(TimerEvent slot, void * data_) {
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
#ifndef __WIN32__
|
||||
#ifndef WINDOWS
|
||||
ti = -1;
|
||||
running = false;
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = this;
|
||||
se.sigev_notify_function = timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
#ifndef __WIN32__
|
||||
#ifndef WINDOWS
|
||||
void PITimer::start(double msecs) {
|
||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(msecs / 1000);
|
||||
@@ -29,13 +30,17 @@ void PITimer::start(double msecs) {
|
||||
|
||||
void PITimer::timer_event(sigval e) {
|
||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data);
|
||||
if (ct->ret_func != 0) {
|
||||
if (ct->lockRun) ct->lock();
|
||||
ct->ret_func(ct->data);
|
||||
if (ct->lockRun) ct->unlock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
double PITimer::elapsed_n() {
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000000. - t_st * 1000000.);
|
||||
#else
|
||||
@@ -47,7 +52,7 @@ double PITimer::elapsed_n() {
|
||||
|
||||
|
||||
double PITimer::elapsed_u() {
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000. - t_st * 1000.);
|
||||
#else
|
||||
@@ -59,7 +64,7 @@ double PITimer::elapsed_u() {
|
||||
|
||||
|
||||
double PITimer::elapsed_m() {
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
#else
|
||||
@@ -71,7 +76,7 @@ double PITimer::elapsed_m() {
|
||||
|
||||
|
||||
double PITimer::elapsed_s() {
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur / 1000. - t_st / 1000.);
|
||||
#else
|
||||
@@ -104,25 +109,26 @@ PIDate currentDate() {
|
||||
}
|
||||
|
||||
|
||||
string time2string(const PITime & time, const string & format) {
|
||||
string ts = format;
|
||||
int i = ts.find_first_of('h');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.hours));
|
||||
i = ts.find_first_of('m');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.minutes));
|
||||
i = ts.find_first_of('s');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.seconds));
|
||||
PIString time2string(const PITime & time, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(time.hours));
|
||||
ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(time.minutes));
|
||||
ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(time.seconds));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
string date2string(const PIDate & date, const string & format) {
|
||||
string ts = format;
|
||||
int i = ts.find_first_of('y');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.year));
|
||||
i = ts.find_first_of('m');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.month));
|
||||
i = ts.find_first_of('d');
|
||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.day));
|
||||
PIString date2string(const PIDate & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(date.year));
|
||||
ts.replace("mm", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
16
pitimer.h
16
pitimer.h
@@ -4,6 +4,7 @@
|
||||
#include <ctime>
|
||||
#include <csignal>
|
||||
#include "pithread.h"
|
||||
#include "pistring.h"
|
||||
|
||||
typedef void (*TimerEvent)(void * );
|
||||
|
||||
@@ -20,20 +21,23 @@ struct PIDate {
|
||||
};
|
||||
|
||||
class PITimer
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
: public PIThread
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
PITimer(TimerEvent slot = 0, void * data = 0);
|
||||
~PITimer() {stop();}
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
void reset() {t_st = GetCurrentTime();}
|
||||
#else
|
||||
void reset() {clock_gettime(0, &t_st);}
|
||||
void start(double msecs);
|
||||
void stop() {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
|
||||
bool isRunning() const {return running;}
|
||||
void needLockRun(bool need) {lockRun = need;}
|
||||
void lock() {mutex_.lock();}
|
||||
void unlock() {mutex_.unlock();}
|
||||
#endif
|
||||
double elapsed_n(); // nanoseconds
|
||||
double elapsed_u(); // microseconds
|
||||
@@ -41,7 +45,7 @@ public:
|
||||
double elapsed_s(); // seconds
|
||||
|
||||
private:
|
||||
#ifdef __WIN32__
|
||||
#ifdef WINDOWS
|
||||
void run() {if (ret_func != 0) ret_func(data);}
|
||||
|
||||
long int t_st, t_cur;
|
||||
@@ -49,6 +53,8 @@ private:
|
||||
static void timer_event(sigval e);
|
||||
|
||||
bool running;
|
||||
volatile bool lockRun;
|
||||
PIMutex mutex_;
|
||||
int ti;
|
||||
itimerspec spec;
|
||||
timespec t_st, t_cur;
|
||||
@@ -63,7 +69,7 @@ private:
|
||||
|
||||
PITime currentTime();
|
||||
PIDate currentDate();
|
||||
string time2string(const PITime & time, const string & format = "h:m:s");
|
||||
string date2string(const PIDate & date, const string & format = "d.m.y");
|
||||
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss");
|
||||
PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy");
|
||||
|
||||
#endif // PITIMER_H
|
||||
|
||||
246
pivariable.cpp
246
pivariable.cpp
@@ -1,111 +1,195 @@
|
||||
#include "pivariable.h"
|
||||
|
||||
|
||||
void PIVariable::setVariable(const PIString & str) {
|
||||
type_ = PIVariable::fromString(str);
|
||||
size_ = PIVariable::variableSize(type_);
|
||||
bool PIVariant::operator ==(const PIVariant & v) const {
|
||||
if (type != v.type) return false;
|
||||
switch (type) {
|
||||
case PIVariant::Bool: return vBool == v.vBool;
|
||||
case PIVariant::Char: return vChar == v.vChar;
|
||||
case PIVariant::Short: return vShort == v.vShort;
|
||||
case PIVariant::Int: return vInt == v.vInt;
|
||||
case PIVariant::Long: return vLong == v.vLong;
|
||||
case PIVariant::LLong: return vLLong == v.vLLong;
|
||||
case PIVariant::UChar: return vUChar == v.vUChar;
|
||||
case PIVariant::UShort: return vUShort == v.vUShort;
|
||||
case PIVariant::UInt: return vUInt == v.vUInt;
|
||||
case PIVariant::ULong: return vULong == v.vULong;
|
||||
case PIVariant::ULLong: return vULLong == v.vULLong;
|
||||
case PIVariant::Float: return vFloat == v.vFloat;
|
||||
case PIVariant::Double: return vDouble == v.vDouble;
|
||||
case PIVariant::LDouble: return vLDouble == v.vLDouble;
|
||||
case PIVariant::String: return vString == v.vString;
|
||||
case PIVariant::StringList: return vStringList == v.vStringList;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PIVariable::Type PIVariable::fromString(const PIString & str) {
|
||||
PIString s = str.trimmed().toLowerCase();
|
||||
if (s == "char" || s == "sbyte") return PIVariable::Char;
|
||||
if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariable::Short;
|
||||
if (s == "int" || s == "signed" || s == "signed int") return PIVariable::Int;
|
||||
if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariable::Long;
|
||||
if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariable::LLong;
|
||||
if (s == "uchar" || s == "byte") return PIVariable::UChar;
|
||||
if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariable::UShort;
|
||||
if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariable::UInt;
|
||||
if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariable::ULong;
|
||||
if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariable::ULLong;
|
||||
if (s == "float") return PIVariable::Float;
|
||||
if (s == "double" || s == "real") return PIVariable::Double;
|
||||
if (s == "ldouble" || s == "long double") return PIVariable::LDouble;
|
||||
if (s == "bool") return PIVariable::Bool;
|
||||
return PIVariable::Double;
|
||||
void PIVariant::setValueOnly(const PIString & s) {
|
||||
switch (type) {
|
||||
case PIVariant::Bool: vBool = s.toBool(); break;
|
||||
case PIVariant::Char: vChar = s.toChar(); break;
|
||||
case PIVariant::Short: vShort = s.toShort(); break;
|
||||
case PIVariant::Int: vInt = s.toInt(); break;
|
||||
case PIVariant::Long: vLong = s.toLong(); break;
|
||||
case PIVariant::LLong: vLLong = s.toLLong(); break;
|
||||
case PIVariant::UChar: vUChar = s.toChar(); break;
|
||||
case PIVariant::UShort: vUShort = s.toShort(); break;
|
||||
case PIVariant::UInt: vUInt = s.toInt(); break;
|
||||
case PIVariant::ULong: vULong = s.toLong(); break;
|
||||
case PIVariant::ULLong: vULLong = s.toLLong(); break;
|
||||
case PIVariant::Float: vFloat = s.toFloat(); break;
|
||||
case PIVariant::Double: vDouble = s.toDouble(); break;
|
||||
case PIVariant::LDouble: vLDouble = s.toLDouble(); break;
|
||||
case PIVariant::String: vString = s; break;
|
||||
case PIVariant::StringList: vStringList = s.split("%|%"); break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariable::toString(const PIVariable::Type & var) {
|
||||
PIString PIVariant::stringValue() const {
|
||||
switch (type) {
|
||||
case PIVariant::Bool: return (vBool ? "true" : "false");
|
||||
case PIVariant::Char: return PIString::fromNumber(vChar);
|
||||
case PIVariant::Short: return PIString::fromNumber(vShort);
|
||||
case PIVariant::Int: return PIString::fromNumber(vInt);
|
||||
case PIVariant::Long: return PIString::fromNumber(vLong);
|
||||
case PIVariant::LLong: return PIString::fromNumber(static_cast<long>(vLLong));
|
||||
case PIVariant::UChar: return PIString::fromNumber(vUChar);
|
||||
case PIVariant::UShort: return PIString::fromNumber(vUShort);
|
||||
case PIVariant::UInt: return PIString::fromNumber(vUInt);
|
||||
case PIVariant::ULong: return PIString::fromNumber(static_cast<long>(vULong));
|
||||
case PIVariant::ULLong: return PIString::fromNumber(static_cast<long>(vULLong));
|
||||
case PIVariant::Float: return PIString::fromNumber(vFloat);
|
||||
case PIVariant::Double: return PIString::fromNumber(vDouble);
|
||||
case PIVariant::LDouble: return PIString::fromNumber(vLDouble);
|
||||
case PIVariant::String: return vString;
|
||||
case PIVariant::StringList: return vStringList.join("%|%");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PIVariant PIVariant::readFromString(const PIString & s) {
|
||||
int i = s.find(':');
|
||||
if (i < 0 || s.length() < 2) return PIVariant(s);
|
||||
PIVariant ret;
|
||||
ret.type = PIVariant::fromString(s.left(i));
|
||||
ret.setValueOnly(s.right(s.length() - i - 1));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIVariant::Type PIVariant::fromString(const PIString & str) {
|
||||
PIString s = str.trimmed().toLowerCase().replace(" ", "");
|
||||
if (s == "bool") return PIVariant::Bool;
|
||||
if (s == "char" || s == "sbyte") return PIVariant::Char;
|
||||
if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariant::Short;
|
||||
if (s == "int" || s == "signed" || s == "signed int") return PIVariant::Int;
|
||||
if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariant::Long;
|
||||
if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariant::LLong;
|
||||
if (s == "uchar" || s == "byte") return PIVariant::UChar;
|
||||
if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariant::UShort;
|
||||
if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariant::UInt;
|
||||
if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariant::ULong;
|
||||
if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariant::ULLong;
|
||||
if (s == "float") return PIVariant::Float;
|
||||
if (s == "double" || s == "real") return PIVariant::Double;
|
||||
if (s == "ldouble" || s == "long double") return PIVariant::LDouble;
|
||||
if (s == "pistring" || s == "string") return PIVariant::String;
|
||||
if (s == "pistringlist" || s == "vector<string>" || s == "vector<pistring>" || s == "pivector<string>" || s == "pivector<pistring>") return PIVariant::StringList;
|
||||
return PIVariant::Double;
|
||||
}
|
||||
|
||||
|
||||
PIString PIVariant::toString(const PIVariant::Type & var) {
|
||||
switch (var) {
|
||||
case PIVariable::Char: return "char";
|
||||
case PIVariable::Short: return "short";
|
||||
case PIVariable::Int: return "int";
|
||||
case PIVariable::Long: return "long";
|
||||
case PIVariable::LLong: return "llong";
|
||||
case PIVariable::UChar: return "uchar";
|
||||
case PIVariable::UShort: return "ushort";
|
||||
case PIVariable::UInt: return "uint";
|
||||
case PIVariable::ULong: return "ulong";
|
||||
case PIVariable::ULLong: return "ullong";
|
||||
case PIVariable::Float: return "float";
|
||||
case PIVariable::Double: return "double";
|
||||
case PIVariable::LDouble: return "ldouble";
|
||||
case PIVariable::Bool: return "bool";
|
||||
case PIVariant::Bool: return "bool";
|
||||
case PIVariant::Char: return "char";
|
||||
case PIVariant::Short: return "short";
|
||||
case PIVariant::Int: return "int";
|
||||
case PIVariant::Long: return "long";
|
||||
case PIVariant::LLong: return "llong";
|
||||
case PIVariant::UChar: return "uchar";
|
||||
case PIVariant::UShort: return "ushort";
|
||||
case PIVariant::UInt: return "uint";
|
||||
case PIVariant::ULong: return "ulong";
|
||||
case PIVariant::ULLong: return "ullong";
|
||||
case PIVariant::Float: return "float";
|
||||
case PIVariant::Double: return "double";
|
||||
case PIVariant::LDouble: return "ldouble";
|
||||
case PIVariant::String: return "string";
|
||||
case PIVariant::StringList: return "stringlist";
|
||||
}
|
||||
return "double";
|
||||
}
|
||||
|
||||
|
||||
uint PIVariable::variableSize(const PIVariable::Type & var) {
|
||||
uint PIVariant::variableSize(const PIVariant::Type & var) {
|
||||
switch (var) {
|
||||
case PIVariable::Char: return sizeof(char);
|
||||
case PIVariable::Short: return sizeof(short);
|
||||
case PIVariable::Int: return sizeof(int);
|
||||
case PIVariable::Long: return sizeof(long);
|
||||
case PIVariable::LLong: return sizeof(llong);
|
||||
case PIVariable::UChar: return sizeof(uchar);
|
||||
case PIVariable::UShort: return sizeof(ushort);
|
||||
case PIVariable::UInt: return sizeof(uint);
|
||||
case PIVariable::ULong: return sizeof(ulong);
|
||||
case PIVariable::ULLong: return sizeof(ullong);
|
||||
case PIVariable::Float: return sizeof(float);
|
||||
case PIVariable::Double: return sizeof(double);
|
||||
case PIVariable::LDouble: return sizeof(ldouble);
|
||||
case PIVariable::Bool: return sizeof(bool);
|
||||
case PIVariant::Bool: return sizeof(bool);
|
||||
case PIVariant::Char: return sizeof(char);
|
||||
case PIVariant::Short: return sizeof(short);
|
||||
case PIVariant::Int: return sizeof(int);
|
||||
case PIVariant::Long: return sizeof(long);
|
||||
case PIVariant::LLong: return sizeof(llong);
|
||||
case PIVariant::UChar: return sizeof(uchar);
|
||||
case PIVariant::UShort: return sizeof(ushort);
|
||||
case PIVariant::UInt: return sizeof(uint);
|
||||
case PIVariant::ULong: return sizeof(ulong);
|
||||
case PIVariant::ULLong: return sizeof(ullong);
|
||||
case PIVariant::Float: return sizeof(float);
|
||||
case PIVariant::Double: return sizeof(double);
|
||||
case PIVariant::LDouble: return sizeof(ldouble);
|
||||
default: break;
|
||||
}
|
||||
return sizeof(double);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
double PIVariable::variableValue(const char * var_ptr, const PIVariable::Type & var) {
|
||||
double PIVariant::variableValue(const char * var_ptr, const PIVariant::Type & var) {
|
||||
switch (var) {
|
||||
case PIVariable::Char: return (double)(*((char * )var_ptr));
|
||||
case PIVariable::Short: return (double)(*((short * )var_ptr));
|
||||
case PIVariable::Int: return (double)(*((int * )var_ptr));
|
||||
case PIVariable::Long: return (double)(*((long * )var_ptr));
|
||||
case PIVariable::LLong: return (double)(*((llong * )var_ptr));
|
||||
case PIVariable::UChar: return (double)(*((uchar * )var_ptr));
|
||||
case PIVariable::UShort: return (double)(*((ushort * )var_ptr));
|
||||
case PIVariable::UInt: return (double)(*((uint * )var_ptr));
|
||||
case PIVariable::ULong: return (double)(*((ulong * )var_ptr));
|
||||
case PIVariable::ULLong: return (double)(*((ullong * )var_ptr));
|
||||
case PIVariable::Float: return (double)(*((float * )var_ptr));
|
||||
case PIVariable::Double: return (double)(*((double * )var_ptr));
|
||||
case PIVariable::LDouble: return (ldouble)(*((ldouble * )var_ptr));
|
||||
case PIVariable::Bool: return (double)(*((bool * )var_ptr));
|
||||
case PIVariant::Bool: return (double)(*((bool * )var_ptr));
|
||||
case PIVariant::Char: return (double)(*((char * )var_ptr));
|
||||
case PIVariant::Short: return (double)(*((short * )var_ptr));
|
||||
case PIVariant::Int: return (double)(*((int * )var_ptr));
|
||||
case PIVariant::Long: return (double)(*((long * )var_ptr));
|
||||
case PIVariant::LLong: return (double)(*((llong * )var_ptr));
|
||||
case PIVariant::UChar: return (double)(*((uchar * )var_ptr));
|
||||
case PIVariant::UShort: return (double)(*((ushort * )var_ptr));
|
||||
case PIVariant::UInt: return (double)(*((uint * )var_ptr));
|
||||
case PIVariant::ULong: return (double)(*((ulong * )var_ptr));
|
||||
case PIVariant::ULLong: return (double)(*((ullong * )var_ptr));
|
||||
case PIVariant::Float: return (double)(*((float * )var_ptr));
|
||||
case PIVariant::Double: return (double)(*((double * )var_ptr));
|
||||
case PIVariant::LDouble: return (ldouble)(*((ldouble * )var_ptr));
|
||||
default: break;
|
||||
}
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
void PIVariable::setVariable(const PIString & str) {
|
||||
type_ = PIVariant::fromString(str);
|
||||
size_ = PIVariant::variableSize(type_);
|
||||
}
|
||||
|
||||
|
||||
void PIVariable::writeVariable(char * dest) {
|
||||
switch (type_) {
|
||||
case PIVariable::Char: *((char * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Short: *((short * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Int: *((int * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Long: *((long * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::LLong: *((llong * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::UChar: *((uchar * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::UShort: *((ushort * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::UInt: *((uint * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::ULong: *((ulong * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::ULLong: *((ullong * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Float: *((float * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Double: *((double * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::LDouble: *((ldouble * )((int)dest + offset)) = value_; return;
|
||||
case PIVariable::Bool: *((bool * )((int)dest + offset)) = value_; return;
|
||||
case PIVariant::Bool: *((bool * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Char: *((char * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Short: *((short * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Int: *((int * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Long: *((long * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::LLong: *((llong * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::UChar: *((uchar * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::UShort: *((ushort * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::UInt: *((uint * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::ULong: *((ulong * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::ULLong: *((ullong * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Float: *((float * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::Double: *((double * )((long)dest + offset)) = value_; return;
|
||||
case PIVariant::LDouble: *((ldouble * )((long)dest + offset)) = value_; return;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +200,7 @@ void PIStruct::parseFile(const PIString & file) {
|
||||
PIString ts;
|
||||
uint sz = 0;
|
||||
vars.clear();
|
||||
for (int i = 0; i < conf.numValues(); ++i) {
|
||||
for (int i = 0; i < conf.entriesCount(); ++i) {
|
||||
var.setVariable(conf.getValue(i));
|
||||
var.setName(conf.getName(i));
|
||||
var.offset = sz;
|
||||
|
||||
142
pivariable.h
142
pivariable.h
@@ -3,6 +3,111 @@
|
||||
|
||||
#include "piconfig.h"
|
||||
|
||||
class PIVariant {
|
||||
friend class PIVariable;
|
||||
public:
|
||||
enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
|
||||
|
||||
PIVariant() {setValue(0.);}
|
||||
PIVariant(const char * v) {setValue(v);}
|
||||
PIVariant(const bool & v) {setValue(v);}
|
||||
PIVariant(const char & v) {setValue(v);}
|
||||
PIVariant(const short & v) {setValue(v);}
|
||||
PIVariant(const int & v) {setValue(v);}
|
||||
PIVariant(const long & v) {setValue(v);}
|
||||
PIVariant(const llong & v) {setValue(v);}
|
||||
PIVariant(const uchar & v) {setValue(v);}
|
||||
PIVariant(const ushort & v) {setValue(v);}
|
||||
PIVariant(const uint & v) {setValue(v);}
|
||||
PIVariant(const ulong & v) {setValue(v);}
|
||||
PIVariant(const ullong & v) {setValue(v);}
|
||||
PIVariant(const float & v) {setValue(v);}
|
||||
PIVariant(const double & v) {setValue(v);}
|
||||
PIVariant(const ldouble & v) {setValue(v);}
|
||||
PIVariant(const PIString & v) {setValue(v);}
|
||||
PIVariant(const PIStringList & v) {setValue(v);}
|
||||
|
||||
inline void setValue(const char * v) {setValue(PIString(v));}
|
||||
inline void setValue(const bool & v) {type = PIVariant::Bool; vBool = v;}
|
||||
inline void setValue(const char & v) {type = PIVariant::Char; vChar = v;}
|
||||
inline void setValue(const short & v) {type = PIVariant::Short; vShort = v;}
|
||||
inline void setValue(const int & v) {type = PIVariant::Int; vInt = v;}
|
||||
inline void setValue(const long & v) {type = PIVariant::Long; vLong = v;}
|
||||
inline void setValue(const llong & v) {type = PIVariant::LLong; vLLong = v;}
|
||||
inline void setValue(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
|
||||
inline void setValue(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
|
||||
inline void setValue(const uint & v) {type = PIVariant::UInt; vUInt = v;}
|
||||
inline void setValue(const ulong & v) {type = PIVariant::ULong; vULong = v;}
|
||||
inline void setValue(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
|
||||
inline void setValue(const float & v) {type = PIVariant::Float; vFloat = v;}
|
||||
inline void setValue(const double & v) {type = PIVariant::Double; vDouble = v;}
|
||||
inline void setValue(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
|
||||
inline void setValue(const PIString & v) {type = PIVariant::String; vString = v;}
|
||||
inline void setValue(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
|
||||
void setValueOnly(const PIString & v);
|
||||
inline PIString typeName() const {return PIVariant::toString(type);}
|
||||
inline double doubleValue() const {return PIVariant::variableValue(&vChar, type);}
|
||||
PIString stringValue() const;
|
||||
inline void typeFromString(const PIString & str) {type = PIVariant::fromString(str);}
|
||||
inline PIString typeToString() const {return PIVariant::toString(type);}
|
||||
inline uint size() {if (type != PIVariant::String && type != PIVariant::StringList) return PIVariant::variableSize(type); if (type == PIVariant::String) return vString.size(); else return vStringList.contentSize();}
|
||||
inline PIString writeToString() const {return typeName() + ":" + stringValue();}
|
||||
|
||||
#ifdef QNX
|
||||
inline void operator =(const PIVariant & v) {type = v.type; vLDouble = v.vLDouble; vString = v.vString; vStringList = v.vStringList;}
|
||||
#endif
|
||||
inline void operator =(const char * v) {setValue(PIString(v));}
|
||||
inline void operator =(const bool & v) {type = PIVariant::Bool; vBool = v;}
|
||||
inline void operator =(const char & v) {type = PIVariant::Char; vChar = v;}
|
||||
inline void operator =(const short & v) {type = PIVariant::Short; vShort = v;}
|
||||
inline void operator =(const int & v) {type = PIVariant::Int; vInt = v;}
|
||||
inline void operator =(const long & v) {type = PIVariant::Long; vLong = v;}
|
||||
inline void operator =(const llong & v) {type = PIVariant::LLong; vLLong = v;}
|
||||
inline void operator =(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
|
||||
inline void operator =(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
|
||||
inline void operator =(const uint & v) {type = PIVariant::UInt; vUInt = v;}
|
||||
inline void operator =(const ulong & v) {type = PIVariant::ULong; vULong = v;}
|
||||
inline void operator =(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
|
||||
inline void operator =(const float & v) {type = PIVariant::Float; vFloat = v;}
|
||||
inline void operator =(const double & v) {type = PIVariant::Double; vDouble = v;}
|
||||
inline void operator =(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
|
||||
inline void operator =(const PIString & v) {type = PIVariant::String; vString = v;}
|
||||
inline void operator =(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
|
||||
|
||||
bool operator ==(const PIVariant & v) const;
|
||||
inline bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
||||
|
||||
PIVariant::Type type;
|
||||
union {
|
||||
bool vBool;
|
||||
char vChar;
|
||||
short vShort;
|
||||
int vInt;
|
||||
long vLong;
|
||||
llong vLLong;
|
||||
uchar vUChar;
|
||||
ushort vUShort;
|
||||
uint vUInt;
|
||||
ulong vULong;
|
||||
ullong vULLong;
|
||||
float vFloat;
|
||||
double vDouble;
|
||||
ldouble vLDouble;
|
||||
};
|
||||
PIString vString;
|
||||
PIStringList vStringList;
|
||||
|
||||
static PIVariant readFromString(const PIString & s);
|
||||
|
||||
private:
|
||||
static PIVariant::Type fromString(const PIString & str);
|
||||
static PIString toString(const PIVariant::Type & var);
|
||||
static uint variableSize(const PIVariant::Type & var);
|
||||
static double variableValue(const char * var_ptr, const PIVariant::Type & var);
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
|
||||
|
||||
class PIVariable {
|
||||
public:
|
||||
@@ -10,31 +115,10 @@ public:
|
||||
PIVariable(const PIString & str) {setVariable(str);}
|
||||
~PIVariable() {;}
|
||||
|
||||
enum Type {Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, Bool};
|
||||
typedef struct {
|
||||
union {
|
||||
char vChar;
|
||||
short vShort;
|
||||
int vInt;
|
||||
long vLong;
|
||||
llong vLLong;
|
||||
uchar vUChar;
|
||||
ushort vUShort;
|
||||
uint vUInt;
|
||||
ulong vULong;
|
||||
ullong vULLong;
|
||||
float vFloat;
|
||||
double vDouble;
|
||||
ldouble vLDouble;
|
||||
bool vBool;
|
||||
};
|
||||
PIVariable::Type type;
|
||||
} PIVariant;
|
||||
|
||||
void setVariable(const PIString & str);
|
||||
void writeVariable(char * dest);
|
||||
inline void readVariable(const char * var_ptr) {value_ = PIVariable::variableValue((char * )((int)var_ptr + offset), type_);}
|
||||
inline PIVariable::Type type() const {return type_;}
|
||||
inline void readVariable(const char * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
|
||||
inline PIVariant::Type type() const {return type_;}
|
||||
inline uint size() const {return size_;}
|
||||
inline const PIString & name() {return name_;}
|
||||
inline void setName(const PIString & str) {name_ = str;}
|
||||
@@ -43,13 +127,8 @@ public:
|
||||
|
||||
int offset;
|
||||
|
||||
static PIVariable::Type fromString(const PIString & str);
|
||||
static PIString toString(const PIVariable::Type & var);
|
||||
static uint variableSize(const PIVariable::Type & var);
|
||||
static double variableValue(const char * var_ptr, const PIVariable::Type & var);
|
||||
|
||||
private:
|
||||
PIVariable::Type type_;
|
||||
PIVariant::Type type_;
|
||||
uint size_;
|
||||
PIString name_;
|
||||
double value_;
|
||||
@@ -95,3 +174,8 @@ private:
|
||||
};
|
||||
|
||||
#endif // PIVARIABLE_H
|
||||
|
||||
#/** PhEDIT attribute block
|
||||
#-11:16777215
|
||||
#0:7338:monospace10:-3:-3:0
|
||||
#** PhEDIT attribute block ends (-0000117)**/
|
||||
|
||||
Reference in New Issue
Block a user