29.07.2011 - fundamental new

This commit is contained in:
peri4
2011-07-29 08:17:24 +04:00
parent b21a0496cd
commit 29190ea465
49 changed files with 4704 additions and 1052 deletions

28
.kdev4/_custom.kdev4 Normal file
View 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

View File

@@ -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

View File

@@ -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
View 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:

View File

@@ -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
View 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

View File

@@ -1,7 +1,7 @@
#ifndef PIBITARRAY_H
#define PIBITARRAY_H
#include "piincludes.h"
#include "picontainers.h"
class PIBitArray {
public:

View File

@@ -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
View 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
View 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
View 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
View 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
View 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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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}

View File

@@ -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
View 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
View File

@@ -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
View File

@@ -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

View File

@@ -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_));

View File

@@ -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
View 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
View 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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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
View File

@@ -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
View 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
View 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
View 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

View File

@@ -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++;
}

View File

@@ -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

View File

@@ -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, &times) == -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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)**/