29.07.2011 - fundamental new
This commit is contained in:
28
.kdev4/_custom.kdev4
Normal file
28
.kdev4/_custom.kdev4
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
[Containments][1]
|
||||||
|
ActionPluginsSource=Global
|
||||||
|
ExpandAllApplets=false
|
||||||
|
activity=pip
|
||||||
|
activityId=
|
||||||
|
desktop=-1
|
||||||
|
formfactor=0
|
||||||
|
immutability=1
|
||||||
|
lastDesktop=-1
|
||||||
|
lastScreen=0
|
||||||
|
location=0
|
||||||
|
orientation=2
|
||||||
|
plugin=newspaper
|
||||||
|
screen=0
|
||||||
|
wallpaperplugin=color
|
||||||
|
wallpaperpluginmode=
|
||||||
|
|
||||||
|
[Containments][1][Wallpaper][color]
|
||||||
|
backgroundMode=0
|
||||||
|
color1=255,255,255
|
||||||
|
color2=0,0,0
|
||||||
|
|
||||||
|
[General]
|
||||||
|
immutability=1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Manager=KDevCMakeManager
|
||||||
|
Name=pip
|
||||||
@@ -24,7 +24,10 @@ Arguments=
|
|||||||
Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00p\x00i\x00p)
|
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
|
Dependency Action=Build
|
||||||
EnvironmentGroup=default
|
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=
|
Working Directory=
|
||||||
isExecutable=false
|
isExecutable=false
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
project(pip)
|
project(pip)
|
||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||||
file(GLOB CPPS "*.cpp")
|
file(GLOB CPPS "pi*.cpp")
|
||||||
add_definitions(-O2 -g3 -Wall)
|
add_definitions(-O2 -g3 -Wall)
|
||||||
add_executable(pip ${CPPS})
|
add_library(pip SHARED ${CPPS})
|
||||||
if (${WIN32})
|
if (${WIN32})
|
||||||
target_link_libraries(pip pthread ws2_32)
|
target_link_libraries(pip pthread ws2_32)
|
||||||
else (${WIN32})
|
else (${WIN32})
|
||||||
target_link_libraries(pip pthread rt)
|
target_link_libraries(pip pthread rt)
|
||||||
endif (${WIN32})
|
endif (${WIN32})
|
||||||
|
add_executable(pip_test "main.cpp")
|
||||||
|
if (${WIN32})
|
||||||
|
target_link_libraries(pip_test pip pthread ws2_32)
|
||||||
|
else (${WIN32})
|
||||||
|
target_link_libraries(pip_test pip pthread rt)
|
||||||
|
endif (${WIN32})
|
||||||
|
|||||||
240
Makefile_qnx
Normal file
240
Makefile_qnx
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
####### Compiler, tools and options
|
||||||
|
|
||||||
|
TARGET = pip
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
CFLAGS = -pipe -D_REENTRANT
|
||||||
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
INCPATH = -I.
|
||||||
|
LINK = g++
|
||||||
|
LFLAGS = -Wl,-O2
|
||||||
|
LIBS = -lsocket
|
||||||
|
DEL_FILE = rm -f
|
||||||
|
DEL_DIR = rmdir
|
||||||
|
|
||||||
|
####### Output directory
|
||||||
|
|
||||||
|
OBJECTS_DIR = ./
|
||||||
|
|
||||||
|
####### Files
|
||||||
|
|
||||||
|
SOURCES = main.cpp \
|
||||||
|
pibytearray.cpp \
|
||||||
|
piconfig.cpp \
|
||||||
|
piconsole.cpp \
|
||||||
|
pidir.cpp \
|
||||||
|
piethernet.cpp \
|
||||||
|
pievaluator.cpp \
|
||||||
|
pifile.cpp \
|
||||||
|
pikbdlistener.cpp \
|
||||||
|
pimath.cpp \
|
||||||
|
piprotocol.cpp \
|
||||||
|
piserial.cpp \
|
||||||
|
pistring.cpp \
|
||||||
|
pithread.cpp \
|
||||||
|
pitimer.cpp \
|
||||||
|
pivariable.cpp
|
||||||
|
OBJECTS = main.o \
|
||||||
|
pibytearray.o \
|
||||||
|
piconfig.o \
|
||||||
|
piconsole.o \
|
||||||
|
pidir.o \
|
||||||
|
piethernet.o \
|
||||||
|
pievaluator.o \
|
||||||
|
pifile.o \
|
||||||
|
pikbdlistener.o \
|
||||||
|
pimath.o \
|
||||||
|
piprotocol.o \
|
||||||
|
piserial.o \
|
||||||
|
pistring.o \
|
||||||
|
pithread.o \
|
||||||
|
pitimer.o \
|
||||||
|
pivariable.o
|
||||||
|
|
||||||
|
first: all
|
||||||
|
####### Implicit rules
|
||||||
|
|
||||||
|
.SUFFIXES: .o .c .cpp .cc .cxx .C
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||||
|
|
||||||
|
.cxx.o:
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||||
|
|
||||||
|
.C.o:
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
|
||||||
|
|
||||||
|
####### Build rules
|
||||||
|
|
||||||
|
all: Makefile $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
|
||||||
|
|
||||||
|
clean:compiler_clean
|
||||||
|
-$(DEL_FILE) $(OBJECTS)
|
||||||
|
-$(DEL_FILE) *~ core *.core
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
-$(DEL_FILE) $(TARGET)
|
||||||
|
-$(DEL_FILE) Makefile
|
||||||
|
|
||||||
|
compiler_clean:
|
||||||
|
|
||||||
|
####### Compile
|
||||||
|
|
||||||
|
main.o: main.cpp pip.h \
|
||||||
|
pitimer.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h \
|
||||||
|
pivariable.h \
|
||||||
|
piconfig.h \
|
||||||
|
pifile.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h \
|
||||||
|
piconsole.h \
|
||||||
|
pikbdlistener.h \
|
||||||
|
pievaluator.h \
|
||||||
|
pimath.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp
|
||||||
|
|
||||||
|
pibytearray.o: pibytearray.cpp pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
piincludes.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pibytearray.o pibytearray.cpp
|
||||||
|
|
||||||
|
piconfig.o: piconfig.cpp piconfig.h \
|
||||||
|
pifile.h \
|
||||||
|
piincludes.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piconfig.o piconfig.cpp
|
||||||
|
|
||||||
|
piconsole.o: piconsole.cpp piconsole.h \
|
||||||
|
pikbdlistener.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piconsole.o piconsole.cpp
|
||||||
|
|
||||||
|
pidir.o: pidir.cpp pidir.h \
|
||||||
|
pifile.h \
|
||||||
|
piincludes.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pidir.o pidir.cpp
|
||||||
|
|
||||||
|
piethernet.o: piethernet.cpp piethernet.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piethernet.o piethernet.cpp
|
||||||
|
|
||||||
|
pievaluator.o: pievaluator.cpp pievaluator.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
piincludes.h \
|
||||||
|
pichar.h \
|
||||||
|
pimath.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pievaluator.o pievaluator.cpp
|
||||||
|
|
||||||
|
pifile.o: pifile.cpp pifile.h \
|
||||||
|
piincludes.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pifile.o pifile.cpp
|
||||||
|
|
||||||
|
pikbdlistener.o: pikbdlistener.cpp pikbdlistener.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pikbdlistener.o pikbdlistener.cpp
|
||||||
|
|
||||||
|
pimath.o: pimath.cpp pimath.h \
|
||||||
|
piincludes.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pimath.o pimath.cpp
|
||||||
|
|
||||||
|
piprotocol.o: piprotocol.cpp piprotocol.h \
|
||||||
|
piserial.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h \
|
||||||
|
piethernet.h \
|
||||||
|
pitimer.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piprotocol.o piprotocol.cpp
|
||||||
|
|
||||||
|
piserial.o: piserial.cpp piserial.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o piserial.o piserial.cpp
|
||||||
|
|
||||||
|
pistring.o: pistring.cpp pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
piincludes.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pistring.o pistring.cpp
|
||||||
|
|
||||||
|
pithread.o: pithread.cpp pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pithread.o pithread.cpp
|
||||||
|
|
||||||
|
pitimer.o: pitimer.cpp pitimer.h \
|
||||||
|
pithread.h \
|
||||||
|
piincludes.h \
|
||||||
|
pimutex.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pitimer.o pitimer.cpp
|
||||||
|
|
||||||
|
pivariable.o: pivariable.cpp pivariable.h \
|
||||||
|
piconfig.h \
|
||||||
|
pifile.h \
|
||||||
|
piincludes.h \
|
||||||
|
pistring.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pibitarray.h \
|
||||||
|
pichar.h
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o pivariable.o pivariable.cpp
|
||||||
|
|
||||||
|
####### Install
|
||||||
|
|
||||||
|
install: FORCE
|
||||||
|
|
||||||
|
uninstall: FORCE
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
41
main.cpp
41
main.cpp
@@ -1,26 +1,21 @@
|
|||||||
#include "pip.h"
|
#include <pip.h>
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
/*PIString s("I love Kusia! <3");
|
PIString s("sos№⚒№хуй"/*☢⚒SOŮ*/);
|
||||||
PIByteArray c(s.data(), s.size());
|
/*cout << s << endl;
|
||||||
c.compressHuffman();
|
cout << s.length() << endl;
|
||||||
cout << s << endl << c << endl;
|
cout << s.stdWString().length() << endl;*/
|
||||||
//c.decompressRLE(128);
|
//system("cd /");
|
||||||
cout << c << endl;*/
|
PIProcess p;
|
||||||
PIBitArray a(0xFFF00Fu);
|
//p.setWorkingDirectory("/");
|
||||||
//cout << a << endl;
|
//p.setEnvironmentVariable("PWD", "/");
|
||||||
a.setBit(31);
|
//cout << p.environment().join("\n") << endl;
|
||||||
cout << a << endl;
|
p.exec("cd");
|
||||||
a.push_back(true);
|
p.waitForFinish();
|
||||||
cout << a << endl;
|
|
||||||
a.push_front(true);
|
//cout << s << endl;
|
||||||
cout << a << endl;
|
/*wchar_t wc;
|
||||||
a.push_front(false);
|
cout << (int)(uchar)("№"[0]) << ", " << (int)(uchar)("№"[1]) << endl;
|
||||||
cout << a << endl;
|
cout << isascii("№"[0]) << endl;
|
||||||
a.pop_front();
|
cout << mbtowc(&wc, "№", 4) << endl;*/
|
||||||
cout << a << endl;
|
|
||||||
a.pop_front();
|
|
||||||
cout << a << endl;
|
|
||||||
a.pop_front();
|
|
||||||
cout << a << endl;
|
|
||||||
};
|
};
|
||||||
|
|||||||
8
make_install.sh
Executable file
8
make_install.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
cmake .
|
||||||
|
make -j3
|
||||||
|
if [ $@ != "" ] ; then
|
||||||
|
chown -v $@ /usr/lib/ /usr/include/
|
||||||
|
fi
|
||||||
|
cp -vf *.h /usr/include/
|
||||||
|
cp -vf libpip.so /usr/lib/libpip.so
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef PIBITARRAY_H
|
#ifndef PIBITARRAY_H
|
||||||
#define PIBITARRAY_H
|
#define PIBITARRAY_H
|
||||||
|
|
||||||
#include "piincludes.h"
|
#include "picontainers.h"
|
||||||
|
|
||||||
class PIBitArray {
|
class PIBitArray {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ private:
|
|||||||
class PIByteArray: public PIVector<uchar> {
|
class PIByteArray: public PIVector<uchar> {
|
||||||
public:
|
public:
|
||||||
PIByteArray() {;}
|
PIByteArray() {;}
|
||||||
PIByteArray(const char * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
PIByteArray(const uint size) {resize(size);}
|
||||||
PIByteArray(const uchar * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
|
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 & convertToBase64();
|
||||||
PIByteArray & convertFromBase64();
|
PIByteArray & convertFromBase64();
|
||||||
|
|||||||
102
pichar.h
Normal file
102
pichar.h
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#ifndef PICHAR_H
|
||||||
|
#define PICHAR_H
|
||||||
|
|
||||||
|
#include "piincludes.h"
|
||||||
|
|
||||||
|
class PIChar
|
||||||
|
{
|
||||||
|
friend class PIString;
|
||||||
|
public:
|
||||||
|
PIChar(const char c) {ch = c; ch &= 0xFF;}
|
||||||
|
PIChar(const short c) {ch = c; ch &= 0xFFFF;}
|
||||||
|
PIChar(const int c = 0) {ch = c;}
|
||||||
|
PIChar(const uchar c) {ch = c; ch &= 0xFF;}
|
||||||
|
PIChar(const ushort c) {ch = c; ch &= 0xFFFF;}
|
||||||
|
PIChar(const uint c) {ch = c;}
|
||||||
|
PIChar(const char * c) {ch = *reinterpret_cast<const int * >(c);}
|
||||||
|
|
||||||
|
//inline operator const int() {return static_cast<const int>(ch);}
|
||||||
|
//inline operator const char() {return toAscii();}
|
||||||
|
|
||||||
|
inline PIChar & operator =(const char v) {ch = v; return *this;}
|
||||||
|
/*inline PIChar & operator =(const short v) {ch = v; return *this;}
|
||||||
|
inline PIChar & operator =(const int v) {ch = v; return *this;}
|
||||||
|
inline PIChar & operator =(const uchar v) {ch = v; return *this;}
|
||||||
|
inline PIChar & operator =(const ushort v) {ch = v; return *this;}
|
||||||
|
inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
|
||||||
|
|
||||||
|
inline bool operator ==(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) == 0;}
|
||||||
|
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
|
||||||
|
if (isAscii()) return (o.toAscii() == toAscii());
|
||||||
|
return (o.toInt() == toInt());}
|
||||||
|
inline bool operator ==(const char o) const {return (PIChar(o) == *this);}
|
||||||
|
inline bool operator ==(const short o) const {return (PIChar(o) == *this);}
|
||||||
|
inline bool operator ==(const int o) const {return (PIChar(o) == *this);}
|
||||||
|
inline bool operator ==(const uchar o) const {return (PIChar(o) == *this);}
|
||||||
|
inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
|
||||||
|
inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
|
||||||
|
|
||||||
|
inline bool operator !=(const PIChar & o) const {return !(o == *this);}
|
||||||
|
/*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
|
||||||
|
inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
|
||||||
|
inline bool operator !=(const int o) const {return (PIChar(o) != *this);}
|
||||||
|
inline bool operator !=(const uchar o) const {return (PIChar(o) != *this);}
|
||||||
|
inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
|
||||||
|
inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
|
||||||
|
|
||||||
|
inline bool operator >(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) < 0;}
|
||||||
|
inline bool operator <(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) > 0;}
|
||||||
|
inline bool operator >=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) <= 0;}
|
||||||
|
inline bool operator <=(const PIChar & o) const {return strcmp(o.toCharPtr(), toCharPtr()) >= 0;}
|
||||||
|
|
||||||
|
inline bool isDigit() const {return isdigit(ch);}
|
||||||
|
inline bool isHex() const {return isxdigit(ch);}
|
||||||
|
inline bool isGraphical() const {return isgraph(ch);}
|
||||||
|
inline bool isControl() const {return iscntrl(ch);}
|
||||||
|
inline bool isLower() const {return islower(ch);}
|
||||||
|
inline bool isUpper() const {return isupper(ch);}
|
||||||
|
inline bool isPrint() const {return isprint(ch);}
|
||||||
|
inline bool isSpace() const {return isspace(ch);}
|
||||||
|
inline bool isAlpha() const {return isalpha(ch);}
|
||||||
|
inline bool isAscii() const {return isascii(ch);}
|
||||||
|
|
||||||
|
inline int toInt() const {return static_cast<const int>(ch);}
|
||||||
|
inline const wchar_t * toWCharPtr() const {return &ch;}
|
||||||
|
inline const char * toCharPtr() const {return reinterpret_cast<const char * >(&ch);}
|
||||||
|
inline const wchar_t toWChar() const {return ch;}
|
||||||
|
inline char toAscii() const {return ch % 256;}
|
||||||
|
inline int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));}
|
||||||
|
inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));}
|
||||||
|
#else
|
||||||
|
inline PIChar toUpper() const {return PIChar(toupper(ch));}
|
||||||
|
inline PIChar toLower() const {return PIChar(tolower(ch));}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
wchar_t ch;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||||
|
|
||||||
|
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
|
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
|
inline bool operator ==(const int v, const PIChar & c) {return (PIChar(v) == c);}
|
||||||
|
inline bool operator >(const int v, const PIChar & c) {return (PIChar(v) > c);}
|
||||||
|
inline bool operator <(const int v, const PIChar & c) {return (PIChar(v) < c);}
|
||||||
|
inline bool operator >=(const int v, const PIChar & c) {return (PIChar(v) >= c);}
|
||||||
|
inline bool operator <=(const int v, const PIChar & c) {return (PIChar(v) <= c);}
|
||||||
|
|
||||||
|
#endif // PICHAR_H
|
||||||
63
picli.cpp
Normal file
63
picli.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include "picli.h"
|
||||||
|
|
||||||
|
|
||||||
|
PICLI::PICLI(int argc, char * argv[]) {
|
||||||
|
needParse = true;
|
||||||
|
_prefix_short = "-";
|
||||||
|
_prefix_full = "--";
|
||||||
|
_count_opt = 0;
|
||||||
|
_count_mand = 1;
|
||||||
|
for (int i = 0; i < argc; ++i)
|
||||||
|
_args_raw << argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICLI::parse() {
|
||||||
|
if (!needParse) return;
|
||||||
|
PIString cra, full;
|
||||||
|
Argument * last = 0;
|
||||||
|
for (int i = 1; i < _args_raw.size_s(); ++i) {
|
||||||
|
cra = _args_raw[i];
|
||||||
|
if (cra.left(2) == _prefix_full) {
|
||||||
|
last = 0;
|
||||||
|
full = cra.right(cra.length() - 2);
|
||||||
|
piForeachA (a, _args) {
|
||||||
|
if (a.full_key == full) {
|
||||||
|
a.found = true;
|
||||||
|
last = &a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (cra.left(1) == _prefix_short) {
|
||||||
|
last = 0;
|
||||||
|
for (int j = 1; j < cra.length(); ++j) {
|
||||||
|
piForeachA (a, _args) {
|
||||||
|
if (a.short_key == cra[j]) {
|
||||||
|
a.found = true;
|
||||||
|
last = &a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (last == 0 ? true : !last->has_value) {
|
||||||
|
if (_args_mand.size_s() < _count_mand) {
|
||||||
|
_args_mand << cra;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (_args_opt.size_s() < _count_opt) {
|
||||||
|
_args_opt << cra;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cout << "[PICli] Arguments overflow, \"" << cra << "\" ignored" << endl;
|
||||||
|
}
|
||||||
|
if (last == 0 ? false : last->has_value) {
|
||||||
|
last->value = cra;
|
||||||
|
last = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
needParse = false;
|
||||||
|
}
|
||||||
60
picli.h
Normal file
60
picli.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef PICLI_H
|
||||||
|
#define PICLI_H
|
||||||
|
|
||||||
|
#include "pistring.h"
|
||||||
|
|
||||||
|
class PICLI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PICLI(int argc, char * argv[]);
|
||||||
|
|
||||||
|
inline void addArgument(const PIString & name, bool value = false) {_args << Argument(name, name[0], name, value); needParse = true;}
|
||||||
|
inline void addArgument(const PIString & name, const PIChar & shortKey, bool value = false) {_args << Argument(name, shortKey, name, value); needParse = true;}
|
||||||
|
inline void addArgument(const PIString & name, const char * shortKey, bool value = false) {_args << Argument(name, PIChar(shortKey), name, value); needParse = true;}
|
||||||
|
inline void addArgument(const PIString & name, const PIChar & shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, shortKey, fullKey, value); needParse = true;}
|
||||||
|
inline void addArgument(const PIString & name, const char * shortKey, const PIString & fullKey, bool value = false) {_args << Argument(name, PIChar(shortKey), fullKey, value); needParse = true;}
|
||||||
|
|
||||||
|
inline PIString rawArgument(int index) {return _args_raw[index];}
|
||||||
|
inline PIString mandatoryArgument(int index) {return _args_mand[index];}
|
||||||
|
inline PIString optionalArgument(int index) {return _args_opt[index];}
|
||||||
|
inline const PIStringList & rawArguments() const {return _args_raw;}
|
||||||
|
inline const PIStringList & mandatoryArguments() const {return _args_mand;}
|
||||||
|
inline const PIStringList & optionalArguments() const {return _args_opt;}
|
||||||
|
inline const PIString programCommand() const {return _args_raw.size() > 0 ? _args_raw.front() : PIString();}
|
||||||
|
inline bool hasArgument(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return true; return false;}
|
||||||
|
inline PIString argumentValue(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return i.value; return PIString();}
|
||||||
|
inline PIString argumentShortKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.short_key; return PIString();}
|
||||||
|
inline PIString argumentFullKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.full_key; return PIString();}
|
||||||
|
|
||||||
|
inline const PIString & shortKeyPrefix() const {return _prefix_short;}
|
||||||
|
inline const PIString & fullKeyPrefix() const {return _prefix_full;}
|
||||||
|
inline const int mandatoryArgumentsCount() const {return _count_mand;}
|
||||||
|
inline const int optionalArgumentsCount() const {return _count_opt;}
|
||||||
|
inline void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix;}
|
||||||
|
inline void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix;}
|
||||||
|
inline void setMandatoryArgumentsCount(const int count) {_count_mand = count;}
|
||||||
|
inline void setOptionalArgumentsCount(const int count) {_count_opt = count;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Argument {
|
||||||
|
Argument() {has_value = found = false;}
|
||||||
|
Argument(const PIString & n, const PIChar & s, const PIString & f, bool v) {name = n; short_key = s; full_key = f; has_value = v; found = false;}
|
||||||
|
PIString name;
|
||||||
|
PIChar short_key;
|
||||||
|
PIString full_key;
|
||||||
|
PIString value;
|
||||||
|
bool has_value, found;
|
||||||
|
};
|
||||||
|
|
||||||
|
void parse();
|
||||||
|
|
||||||
|
PIString _prefix_short, _prefix_full;
|
||||||
|
PIStringList _args_raw, _args_mand, _args_opt;
|
||||||
|
PISet<PIString> keys_full, keys_short;
|
||||||
|
PIVector<Argument> _args;
|
||||||
|
int _count_mand, _count_opt;
|
||||||
|
bool needParse;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PICLI_H
|
||||||
22
picodec.cpp
Normal file
22
picodec.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "picodec.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIStringList PICodec::availableCodecs() {
|
||||||
|
exec("iconv", "-l");
|
||||||
|
waitForFinish();
|
||||||
|
PIString str(readOutput());
|
||||||
|
str.cutLeft(str.find("\n "));
|
||||||
|
str.replaceAll("\n", "");
|
||||||
|
return str.split("//");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray PICodec::exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str) {
|
||||||
|
tf.open();
|
||||||
|
tf.clear();
|
||||||
|
tf << str;
|
||||||
|
tf.close();
|
||||||
|
exec("iconv", ("-f=" + from), ("-t=" + to), tf.path());
|
||||||
|
waitForFinish();
|
||||||
|
return readOutput();
|
||||||
|
}
|
||||||
31
picodec.h
Normal file
31
picodec.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef PICODEC_H
|
||||||
|
#define PICODEC_H
|
||||||
|
|
||||||
|
#include "piprocess.h"
|
||||||
|
|
||||||
|
class PICodec: private PIProcess
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PICodec(): PIProcess() {setGrabOutput(true); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write); tf.open();}
|
||||||
|
PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to); tf = PIFile::openTemporary(PIFile::New | PIFile::Read | PIFile::Write);}
|
||||||
|
~PICodec() {tf.remove();}
|
||||||
|
|
||||||
|
void setFromCoding(const PIString & from) {c_from = from;}
|
||||||
|
void setToCoding(const PIString & to) {c_to = to;}
|
||||||
|
void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;}
|
||||||
|
|
||||||
|
PIStringList availableCodecs();
|
||||||
|
PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));}
|
||||||
|
PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));}
|
||||||
|
PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));}
|
||||||
|
PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str);
|
||||||
|
|
||||||
|
PIString c_from, c_to;
|
||||||
|
PIFile tf;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PICODEC_H
|
||||||
581
piconfig.cpp
581
piconfig.cpp
@@ -1,259 +1,474 @@
|
|||||||
#include "piconfig.h"
|
#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]))
|
if (!isOpened() && (mode[Write] || mode[New]))
|
||||||
open(path, Read | Write | New);
|
open(path, Read | Write | New);
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIStringList PIConfig::getValue(const PIString & vname, const PIStringList & def, bool * exist) const {
|
PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) {
|
||||||
return getValue(vname, def.join("%|%"), exist).split("%|%");}
|
PIStringList tree = vname.split(delim);
|
||||||
bool PIConfig::getValue(const PIString & vname, const bool def, bool * exist) const {
|
Entry * ce = &root;
|
||||||
return atob(getValue(vname, btos(def), exist));}
|
piForeachCA (i, tree) {
|
||||||
char PIConfig::getValue(const PIString & vname, const char def, bool * exist) const {
|
ce = ce->findChild(i);
|
||||||
return getValue(vname, PIString(def), exist)[0];}
|
if (ce == 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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exist != 0) *exist = false;
|
if (exist != 0) *exist = false;
|
||||||
return def;
|
empty._name = vname;
|
||||||
|
empty._value = def;
|
||||||
|
empty.delim = delim;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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) {
|
void PIConfig::setValue(const PIString & name, const PIString & value, const PIString & type, bool write) {
|
||||||
int number = getNumber(name);
|
Entry & e(getValue(name));
|
||||||
if (number == -1) {
|
if (&e == &empty) {
|
||||||
addLine(name, value, type);
|
addEntry(name, value, type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PIString tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
|
e._value = value;
|
||||||
settval[number] = value;
|
e._type = type;
|
||||||
all[settlines[number]] = tmp;
|
|
||||||
if (write) writeAll();
|
if (write) writeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIConfig::existsValue(const PIString & name) {
|
int PIConfig::entryIndex(const PIString & name) {
|
||||||
for (uint i = 0; i < settname.size(); i++)
|
PIStringList tree = name.split(delim);
|
||||||
if (settname[i] == name) return true;
|
Entry * ce = &root;
|
||||||
return false;
|
piForeachCA (i, tree) {
|
||||||
}
|
ce = ce->findChild(i);
|
||||||
|
if (ce == 0)
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Branch b = allLeaves();
|
||||||
|
return allLeaves().indexOf(ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::setValue(uint number, const PIString & value, bool write) {
|
void PIConfig::setValue(uint number, const PIString & value, bool write) {
|
||||||
PIString tmp = settname[number] + " = " + value + " #" + setttype[number] + " " + settcom[number];
|
Entry & e(entryByIndex(number));
|
||||||
settval[number] = value;
|
if (&e == &empty) return;
|
||||||
all[settlines[number]] = tmp;
|
e._value = value;
|
||||||
if (write) writeAll();
|
if (write) writeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::setName(uint number, const PIString & name) {
|
void PIConfig::setName(uint number, const PIString & name, bool write) {
|
||||||
PIString tmp = name + " = " + settval[number] + " #" + setttype[number] + " " + settcom[number];
|
Entry & e(entryByIndex(number));
|
||||||
settname[number] = name;
|
if (&e == &empty) return;
|
||||||
all[settlines[number]] = tmp;
|
e._name = name;
|
||||||
writeAll();
|
if (write) writeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::setType(uint number, const PIString & type) {
|
void PIConfig::setType(uint number, const PIString & type, bool write) {
|
||||||
PIString tmp = settname[number] + " = " + settval[number] + " #" + type + " " + settcom[number];
|
Entry & e(entryByIndex(number));
|
||||||
setttype[number] = type;
|
if (&e == &empty) return;
|
||||||
all[settlines[number]] = tmp;
|
e._type = type;
|
||||||
writeAll();
|
if (write) writeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::setComment(uint number, const PIString & comment) {
|
void PIConfig::setComment(uint number, const PIString & comment, bool write) {
|
||||||
PIString tmp = settname[number] + " = " + settval[number] + " #" + setttype[number] + " " + comment;
|
Entry & e(entryByIndex(number));
|
||||||
settcom[number] = comment;
|
if (&e == &empty) return;
|
||||||
all[settlines[number]] = tmp;
|
e._comment = comment;
|
||||||
writeAll();
|
if (write) writeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::deleteLine(const PIString & name) {
|
void PIConfig::removeEntry(const PIString & name, bool write) {
|
||||||
bool exist = false;
|
Entry & e(getValue(name));
|
||||||
uint i;
|
if (&e == &empty) return;
|
||||||
for (i = 0; i < settname.size(); i++) {
|
Branch b = allLeaves();
|
||||||
if (settname[i] == name) {
|
removeEntry(b, &e);
|
||||||
exist = true;
|
if (write) writeAll();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!exist) return;
|
|
||||||
deleteLine(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::deleteLine(uint number) {
|
void PIConfig::removeEntry(uint number, bool write) {
|
||||||
settname.erase(settname.begin() + number);
|
Entry & e(entryByIndex(number));
|
||||||
settval.erase(settval.begin() + number);
|
if (&e == &empty) return;
|
||||||
settcom.erase(settcom.begin() + number);
|
Branch b = allLeaves();
|
||||||
setttab.erase(setttab.begin() + number);
|
removeEntry(b, &e);
|
||||||
setttype.erase(setttype.begin() + number);
|
if (write) writeAll();
|
||||||
all.erase(all.begin() + settlines[number]);
|
}
|
||||||
for (uint i = number; i < settlines.size(); i++) settlines[i]--;
|
|
||||||
settlines.erase(settlines.begin() + number);
|
|
||||||
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());
|
||||||
|
}
|
||||||
|
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() {
|
void PIConfig::writeAll() {
|
||||||
clear();
|
clear();
|
||||||
uint c = 0;
|
//writeEntry(&root);
|
||||||
for (uint i = 0; i < all.size() - 1; i++) {
|
buildFullNames(&root);
|
||||||
if (c < settlines.size() && c < setttab.size()) {
|
Branch b = allLeaves();
|
||||||
if (settlines[c] == i) {
|
int j = 0;
|
||||||
*this << setttab[c];
|
for (int i = 0; i < other.size_s(); ++i) {
|
||||||
c++;
|
//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();
|
readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::readAll() {
|
void PIConfig::readAll() {
|
||||||
settname.clear();
|
root.clear();
|
||||||
settval.clear();
|
|
||||||
settcom.clear();
|
|
||||||
setttab.clear();
|
|
||||||
settlines.clear();
|
|
||||||
setttype.clear();
|
|
||||||
all.clear();
|
|
||||||
flush();
|
flush();
|
||||||
parse();
|
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() {
|
void PIConfig::parse() {
|
||||||
PIString str, tab, comm;
|
PIString src, str, tab, comm, all, name, type;
|
||||||
|
PIStringList tree;
|
||||||
|
Entry * entry, * te, * ce;
|
||||||
int ind, sind;
|
int ind, sind;
|
||||||
|
bool isNew;
|
||||||
if (!isOpened()) return;
|
if (!isOpened()) return;
|
||||||
seek(0);
|
seekToBegin();
|
||||||
lines = 0;
|
other.clear();
|
||||||
|
lines = centry = 0;
|
||||||
while (!isEnd()) {
|
while (!isEnd()) {
|
||||||
str = readLine();
|
other.push_back(PIString());
|
||||||
|
src = str = readLine();
|
||||||
//cout << str << endl;
|
//cout << str << endl;
|
||||||
tab = str.left(str.find(str.trimmed().left(1)));
|
tab = str.left(str.find(str.trimmed().left(1)));
|
||||||
str.trim();
|
str.trim();
|
||||||
all.push_back(str);
|
all = str;
|
||||||
ind = str.find('=');
|
ind = str.find('=');
|
||||||
if ((ind > 0) && !(str[0] == '#')) {
|
if ((ind > 0) && !(str[0] == '#')) {
|
||||||
sind = str.find('#');
|
sind = str.find('#');
|
||||||
if (sind > 0) {
|
if (sind > 0) {
|
||||||
comm = str.right(str.size() - sind - 1).trimmed();
|
comm = str.right(str.length() - sind - 1).trimmed();
|
||||||
if (comm.length() > 0) setttype.push_back(comm[0]);
|
if (comm.length() > 0) type = comm[0];
|
||||||
else setttype.push_back("s");
|
else type = "s";
|
||||||
comm = comm.right(comm.size() - 1).trimmed();
|
comm = comm.right(comm.length() - 1).trimmed();
|
||||||
settcom.push_back(comm);
|
|
||||||
str = str.left(sind);
|
str = str.left(sind);
|
||||||
} else {
|
} else {
|
||||||
setttype.push_back("s");
|
type = "s";
|
||||||
settcom.push_back("");
|
comm = "";
|
||||||
}
|
}
|
||||||
settname.push_back(str.left(ind).trimmed());
|
//name = str.left(ind).trimmed();
|
||||||
settval.push_back(str.right(str.size() - ind - 1).trimmed());
|
tree = str.left(ind).trimmed().split(delim);
|
||||||
setttab.push_back(tab);
|
name = tree.back();
|
||||||
settlines.push_back(lines);
|
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++;
|
lines++;
|
||||||
}
|
}
|
||||||
|
setEntryDelim(&root, delim);
|
||||||
}
|
}
|
||||||
|
|||||||
243
piconfig.h
243
piconfig.h
@@ -3,72 +3,205 @@
|
|||||||
|
|
||||||
#include "pifile.h"
|
#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
|
class PIConfig: public PIFile
|
||||||
{
|
{
|
||||||
|
friend class Entry;
|
||||||
|
friend class Branch;
|
||||||
public:
|
public:
|
||||||
PIConfig(const PIString & path, Flags<Mode> mode = Read | Write);
|
PIConfig(const PIString & path, PIFlags<Mode> mode = Read | Write);
|
||||||
~PIConfig() {;}
|
~PIConfig() {;}
|
||||||
|
|
||||||
PIString getValue(const PIString & vname, const PIString & def = "", bool * exist = 0) const;
|
class Entry;
|
||||||
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;
|
|
||||||
|
|
||||||
void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
|
class Branch: public PIVector<Entry * > {
|
||||||
void setValue(const PIString & name, const PIStringList & value, bool write = true);
|
friend class PIConfig;
|
||||||
void setValue(const PIString & name, const char * value, bool write = true);
|
friend class Entry;
|
||||||
void setValue(const PIString & name, const bool value, bool write = true);
|
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
||||||
void setValue(const PIString & name, const char value, bool write = true);
|
public:
|
||||||
void setValue(const PIString & name, const short value, bool write = true);
|
inline Branch() {;}
|
||||||
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);
|
|
||||||
|
|
||||||
PIString getValue(uint number) const {return settval[number];}
|
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0);
|
||||||
PIString getName(uint number) const {return settname[number];}
|
PICONFIG_GET_VALUE
|
||||||
PIString getComment(uint number) const {return settcom[number];}
|
|
||||||
void setValue(uint number, const PIString & value, bool write = true);
|
Branch allLeaves();
|
||||||
bool existsValue(const PIString & name);
|
Branch getValues(const PIString & name);
|
||||||
char getType(uint number) const {return setttype[number][0];}
|
Branch getLeaves();
|
||||||
int getNumber(const PIString & name);
|
Branch getBranches();
|
||||||
void setName(uint number, const PIString & name);
|
Branch & filter(const PIString & f);
|
||||||
void setType(uint number, const PIString & type);
|
inline bool isEntryExists(const PIString & name) const {piForeachCA (i, *this) if (entryExists(i, name)) return true; return false;}
|
||||||
void setComment(uint number, const PIString & comment);
|
inline int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
|
||||||
int numValues() const {return settval.size();}
|
|
||||||
void addLine(const PIString & name, const PIString & value, const PIString & type = "s");
|
inline void clear() {piForeachA (i, *this) delete i; PIVector<Entry * >::clear();}
|
||||||
void insertLine(uint number, const PIString & name, const PIString & value, const PIString & type = "s");
|
|
||||||
void deleteLine(const PIString & name);
|
|
||||||
void deleteLine(uint number);
|
|
||||||
void readAll();
|
|
||||||
void writeAll();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parse();
|
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);}
|
||||||
|
|
||||||
PIVector<PIString> settname;
|
static Entry _empty;
|
||||||
PIVector<PIString> settval;
|
PIString delim;
|
||||||
PIVector<PIString> settcom;
|
|
||||||
PIVector<PIString> setttab;
|
|
||||||
PIVector<PIString> setttype;
|
|
||||||
PIVector<PIString> all;
|
|
||||||
PIVector<uint> settlines;
|
|
||||||
uint lines;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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();
|
||||||
|
|
||||||
|
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
|
#endif // PICONFIG_H
|
||||||
|
|||||||
250
piconsole.cpp
250
piconsole.cpp
@@ -6,7 +6,7 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
|||||||
needLockRun(true);
|
needLockRun(true);
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
num_format = 0;
|
num_format = 0;
|
||||||
cur_tab = width = height = my = 0;
|
cur_tab = width = height = pwidth = pheight = my = 0;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
ulcoord.X = ulcoord.Y = 0;
|
ulcoord.X = ulcoord.Y = 0;
|
||||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
@@ -17,29 +17,25 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
|||||||
GetConsoleMode(hOut, &smode);
|
GetConsoleMode(hOut, &smode);
|
||||||
GetConsoleCursorInfo(hOut, &curinfo);
|
GetConsoleCursorInfo(hOut, &curinfo);
|
||||||
#endif
|
#endif
|
||||||
addTab(PIString("main"));
|
addTab("main");
|
||||||
listener = new PIKbdListener(key_event, this);
|
listener = new PIKbdListener(key_event, this);
|
||||||
if (startNow) start(40);
|
if (startNow) start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIConsole::~PIConsole() {
|
PIConsole::~PIConsole() {
|
||||||
if (isRunning()) {
|
if (isRunning())
|
||||||
stop();
|
stop();
|
||||||
waitForFinish();
|
|
||||||
moveTo(0, my + 4);
|
|
||||||
showCursor();
|
|
||||||
}
|
|
||||||
delete listener;
|
|
||||||
clearTabs(false);
|
clearTabs(false);
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
SetConsoleMode(hOut, smode);
|
SetConsoleMode(hOut, smode);
|
||||||
SetConsoleTextAttribute(hOut, dattr);
|
SetConsoleTextAttribute(hOut, dattr);
|
||||||
#endif
|
#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));
|
tabs.push_back(Tab(name, bind_key));
|
||||||
cur_tab = tabs.size() - 1;
|
cur_tab = tabs.size() - 1;
|
||||||
return tabs.size();
|
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;
|
uint index = tabs.size() + 1;
|
||||||
for (uint i = 0; i < tabs.size(); ++i) {
|
for (uint i = 0; i < tabs.size(); ++i) {
|
||||||
if (tabs[i].name == name) {
|
if (tabs[i].name == name) {
|
||||||
@@ -66,7 +62,7 @@ void PIConsole::removeTab(PIString name) {
|
|||||||
|
|
||||||
|
|
||||||
bool PIConsole::setTab(uint index) {
|
bool PIConsole::setTab(uint index) {
|
||||||
if (index >= tabs.size() || index < 0)
|
if (index >= tabs.size())
|
||||||
return false;
|
return false;
|
||||||
cur_tab = index;
|
cur_tab = index;
|
||||||
if (!isRunning()) return true;
|
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;
|
uint index = tabs.size() + 1;
|
||||||
for (uint i = 0; i < tabs.size(); ++i) {
|
for (uint i = 0; i < tabs.size(); ++i) {
|
||||||
if (tabs[i].name == name) {
|
if (tabs[i].name == name) {
|
||||||
@@ -91,14 +87,14 @@ bool PIConsole::setTab(PIString name) {
|
|||||||
|
|
||||||
|
|
||||||
bool PIConsole::setTabBindKey(uint index, char bind_key) {
|
bool PIConsole::setTabBindKey(uint index, char bind_key) {
|
||||||
if (index < 0 || index >= tabs.size())
|
if (index >= tabs.size())
|
||||||
return false;
|
return false;
|
||||||
tabs[index].key = bind_key;
|
tabs[index].key = bind_key;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIConsole::setTabBindKey(PIString name, char bind_key) {
|
bool PIConsole::setTabBindKey(const PIString & name, char bind_key) {
|
||||||
uint index =tabs.size() + 1;
|
uint index =tabs.size() + 1;
|
||||||
for (uint i = 0; i < tabs.size(); ++i) {
|
for (uint i = 0; i < tabs.size(); ++i) {
|
||||||
if (tabs[i].name == name) {
|
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::Dec]) num_format = 0;
|
||||||
if (f[PIConsole::Hex]) num_format = 1;
|
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;
|
if (f[PIConsole::Scientific]) num_format = 3;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
WORD attr = dattr;
|
WORD attr = 0;
|
||||||
|
|
||||||
if (f[PIConsole::Inverse]) {
|
if (f[PIConsole::Inverse]) {
|
||||||
if (f[PIConsole::Red]) attr |= BACKGROUND_RED;
|
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::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
|
||||||
if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
|
if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||||
if (f[PIConsole::White]) attr |= (BACKGROUND_RED | 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 {
|
} else {
|
||||||
if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
|
if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
|
||||||
if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN;
|
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::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
|
||||||
if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | 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::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;
|
if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY;
|
||||||
|
|
||||||
@@ -173,6 +195,15 @@ if (f[PIConsole::Oct]) num_format = 2;
|
|||||||
if (f[PIConsole::Cyan]) ts += ";36";
|
if (f[PIConsole::Cyan]) ts += ";36";
|
||||||
if (f[PIConsole::White]) ts += ";37";
|
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";
|
return ts + "m";
|
||||||
#endif
|
#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 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 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 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 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 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;}
|
#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 int v) {iprint(v);}
|
||||||
inline int PIConsole::couts(const long v) {liprint(v);}
|
inline int PIConsole::couts(const long v) {liprint(v);}
|
||||||
inline int PIConsole::couts(const llong v) {lliprint(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 ushort v) {suprint(v);}
|
||||||
inline int PIConsole::couts(const uint v) {uprint(v);}
|
inline int PIConsole::couts(const uint v) {uprint(v);}
|
||||||
inline int PIConsole::couts(const ulong v) {luprint(v);}
|
inline int PIConsole::couts(const ulong v) {luprint(v);}
|
||||||
@@ -217,7 +249,6 @@ void PIConsole::begin() {
|
|||||||
|
|
||||||
void PIConsole::run() {
|
void PIConsole::run() {
|
||||||
uint cx, clen = 0;
|
uint cx, clen = 0;
|
||||||
string ts;
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||||
@@ -228,19 +259,20 @@ void PIConsole::run() {
|
|||||||
width = ws.ws_col;
|
width = ws.ws_col;
|
||||||
height = ws.ws_row;
|
height = ws.ws_row;
|
||||||
#endif
|
#endif
|
||||||
|
if (pwidth != width || pheight != height) {
|
||||||
|
clearScreen();
|
||||||
|
fillLabels();
|
||||||
|
}
|
||||||
|
pwidth = width;
|
||||||
|
pheight = height;
|
||||||
col_cnt = vars().size();
|
col_cnt = vars().size();
|
||||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||||
for (uint i = 0; i < col_cnt; ++i) {
|
for (uint i = 0; i < col_cnt; ++i) {
|
||||||
cx = col_wid * i;
|
cx = col_wid * i;
|
||||||
toUpperLeft();
|
toUpperLeft();
|
||||||
for (uint j = 0; j < vars()[i].size(); ++j) {
|
if (my < vars()[i].size()) my = vars()[i].size();
|
||||||
if (my < j) my = j;
|
piForeachCA (tv, vars()[i]) {
|
||||||
tv = vars()[i][j];
|
|
||||||
moveRight(cx);
|
moveRight(cx);
|
||||||
if (tv.name.size() == 0) {
|
|
||||||
newLine();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (tv.type == 0 && tv.s == 0) {
|
if (tv.type == 0 && tv.s == 0) {
|
||||||
newLine();
|
newLine();
|
||||||
continue;
|
continue;
|
||||||
@@ -261,10 +293,10 @@ void PIConsole::run() {
|
|||||||
case 11: clen = printValue(*tv.uc, tv.format); break;
|
case 11: clen = printValue(*tv.uc, tv.format); break;
|
||||||
case 12: clen = printValue(*tv.ll, tv.format); break;
|
case 12: clen = printValue(*tv.ll, tv.format); break;
|
||||||
case 13: clen = printValue(*tv.ull, 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) {
|
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());
|
printf("%s", ts.c_str());
|
||||||
}
|
}
|
||||||
newLine();
|
newLine();
|
||||||
@@ -275,7 +307,7 @@ void PIConsole::run() {
|
|||||||
|
|
||||||
|
|
||||||
void PIConsole::fillLabels() {
|
void PIConsole::fillLabels() {
|
||||||
uint cx, my = 0;
|
uint cx, cy, my = 0;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||||
@@ -290,27 +322,43 @@ void PIConsole::fillLabels() {
|
|||||||
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
||||||
for (uint i = 0; i < col_cnt; ++i) {
|
for (uint i = 0; i < col_cnt; ++i) {
|
||||||
cx = col_wid * i;
|
cx = col_wid * i;
|
||||||
|
cy = 1;
|
||||||
toUpperLeft();
|
toUpperLeft();
|
||||||
for (uint j = 0; j < vars()[i].size(); ++j) {
|
for (uint j = 0; j < vars()[i].size(); ++j) {
|
||||||
if (my < j) my = j;
|
if (my < j) my = j;
|
||||||
moveRight(cx);
|
moveRight(cx);
|
||||||
tv = vars()[i][j];
|
tv = vars()[i][j];
|
||||||
|
vars()[i][j].nx = cx;
|
||||||
|
vars()[i][j].ny = cy;
|
||||||
if (tv.name.size() == 0) {
|
if (tv.name.size() == 0) {
|
||||||
|
vars()[i][j].offset = 0;
|
||||||
|
clearLine();
|
||||||
newLine();
|
newLine();
|
||||||
|
cy++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
clearLine();
|
clearLine();
|
||||||
if (tv.type == 0 && tv.s == 0) {
|
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);
|
printLine(tv.name, cx, tv.format);
|
||||||
newLine();
|
newLine();
|
||||||
|
cy++;
|
||||||
continue;
|
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();
|
newLine();
|
||||||
|
cy++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
moveTo(0, my + 1);
|
||||||
|
#else
|
||||||
moveTo(0, my + 2);
|
moveTo(0, my + 2);
|
||||||
if (tabs[cur_tab].status.length() > 0) {
|
#endif
|
||||||
|
if (!tabs[cur_tab].status.isEmpty()) {
|
||||||
printValue(tabs[cur_tab].status);
|
printValue(tabs[cur_tab].status);
|
||||||
newLine();
|
newLine();
|
||||||
}
|
}
|
||||||
@@ -325,24 +373,24 @@ void PIConsole::status() {
|
|||||||
for (uint i = 0; i < tabsCount(); ++i) {
|
for (uint i = 0; i < tabsCount(); ++i) {
|
||||||
ctab = &tabs[i];
|
ctab = &tabs[i];
|
||||||
if (ctab->key == 0) continue;
|
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(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
||||||
printValue(PIString(" "), PIConsole::Normal);
|
printValue(" ");
|
||||||
}
|
}
|
||||||
newLine();
|
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;
|
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++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ret |= ((cbyte >> cbit & 1) << i);
|
ret |= ((cbyte >> cbit & 1) << i);
|
||||||
cbit++;
|
cbit++;
|
||||||
if (cbit == 8) {
|
if (cbit == 8) {
|
||||||
cbit = 0;
|
cbit = 0;
|
||||||
stbyte++;
|
stbyte++;
|
||||||
cbyte = src[stbyte];
|
cbyte = reinterpret_cast<char * >(src)[stbyte];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
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);
|
#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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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);}
|
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) {
|
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.uc = ptr; tv.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);}
|
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;
|
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;
|
int i = width - value.length() - dx;
|
||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
--i;
|
--i;
|
||||||
#endif
|
#endif
|
||||||
string ts = fstr(format).stdString();
|
PIString ts = fstr(format);
|
||||||
couts(ts);
|
couts(ts.stdString());
|
||||||
if (i >= 0) ts = (value + PIString(i, ' ')).stdString();
|
if (i >= 0) ts = value + PIString(i, ' ');
|
||||||
else ts = value.left(value.size() + i).stdString();
|
else ts = value.left(value.size() + i);
|
||||||
couts(ts);
|
couts(ts.stdString());
|
||||||
ts = fstr(Dec).stdString();
|
couts(fstr(Dec).stdString());
|
||||||
couts(ts);
|
|
||||||
}
|
}
|
||||||
inline int PIConsole::printValue(const PIString & value, Flags<PIConsole::Format> format) {
|
inline int PIConsole::printValue(const PIString & value, PIFlags<PIConsole::Format> format) {
|
||||||
string ts = fstr(format).stdString();
|
couts(fstr(format).stdString());
|
||||||
couts(ts);
|
int ret = couts(value.stdString());
|
||||||
ts = value.stdString();
|
|
||||||
int ret = couts(ts);
|
|
||||||
fstr(PIConsole::Dec);
|
fstr(PIConsole::Dec);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
inline int PIConsole::printValue(const char * 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, Flags<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, Flags<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, Flags<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, Flags<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, Flags<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, Flags<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, 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 short value, Flags<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, Flags<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, Flags<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, Flags<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, Flags<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, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
inline int PIConsole::printValue(const ullong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||||
|
|||||||
146
piconsole.h
146
piconsole.h
@@ -29,42 +29,73 @@ public:
|
|||||||
Magenta = 0x2000,
|
Magenta = 0x2000,
|
||||||
Cyan = 0x4000,
|
Cyan = 0x4000,
|
||||||
White = 0x8000,
|
White = 0x8000,
|
||||||
Dec = 0x10000,
|
BackBlack = 0x10000,
|
||||||
Hex = 0x20000,
|
BackRed = 0x20000,
|
||||||
Oct = 0x40000,
|
BackGreen = 0x40000,
|
||||||
Scientific = 0x80000};
|
BackYellow = 0x80000,
|
||||||
|
BackBlue = 0x100000,
|
||||||
|
BackMagenta = 0x200000,
|
||||||
|
BackCyan = 0x400000,
|
||||||
|
BackWhite = 0x800000,
|
||||||
|
Dec = 0x1000000,
|
||||||
|
Hex = 0x2000000,
|
||||||
|
Oct = 0x4000000,
|
||||||
|
Scientific = 0x8000000};
|
||||||
|
|
||||||
|
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();}
|
||||||
|
|
||||||
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);
|
|
||||||
uint tabsCount() const {return tabs.size();}
|
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;}
|
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:
|
private:
|
||||||
void begin();
|
void begin();
|
||||||
@@ -101,28 +132,30 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
void status();
|
void status();
|
||||||
void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}}
|
void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}}
|
||||||
int bitsValue(unsigned char * src, int offset, int count);
|
int bitsValue(void * src, int offset, int count);
|
||||||
inline void printLine(const PIString & str, int dx = 0, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline void printLine(const PIString & str, int dx = 0, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const PIString & str, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const PIString & str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const char * str, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const char * str, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const bool value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const bool value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const int value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const int value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const long value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const long value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const llong value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const llong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const float value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const float value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const double value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const double value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const char value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const char value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const short value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const short value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const uchar value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const uchar value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const ushort value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const ushort value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const uint value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const uint value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const ulong value, Flags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const ulong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const ullong value, Flags<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);
|
static void key_event(char key, void * t);
|
||||||
|
|
||||||
struct Variable {
|
struct Variable {
|
||||||
PIString name;
|
PIString name;
|
||||||
Flags<PIConsole::Format> format;
|
PIFlags<PIConsole::Format> format;
|
||||||
|
int nx;
|
||||||
|
int ny;
|
||||||
int type;
|
int type;
|
||||||
int offset;
|
int offset;
|
||||||
int bitFrom;
|
int bitFrom;
|
||||||
@@ -142,13 +175,14 @@ private:
|
|||||||
uint * ui;
|
uint * ui;
|
||||||
ulong * ul;
|
ulong * ul;
|
||||||
ullong * ull;
|
ullong * ull;
|
||||||
|
void * ptr;
|
||||||
};
|
};
|
||||||
void operator =(const Variable & src) {name = src.name; format = src.format; type = src.type; offset = src.offset;
|
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 {
|
struct Tab {
|
||||||
vector<vector<Variable> > variables;
|
PIVector<PIVector<Variable> > variables;
|
||||||
PIString name;
|
PIString name;
|
||||||
PIString status;
|
PIString status;
|
||||||
char key;
|
char key;
|
||||||
@@ -156,7 +190,7 @@ private:
|
|||||||
Tab(PIString n, char k) {name = n; key = k;}
|
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 string v);
|
||||||
inline int couts(const char * v);
|
inline int couts(const char * v);
|
||||||
inline int couts(const bool v);
|
inline int couts(const bool v);
|
||||||
@@ -183,11 +217,11 @@ private:
|
|||||||
#else
|
#else
|
||||||
struct termios sterm, vterm;
|
struct termios sterm, vterm;
|
||||||
#endif
|
#endif
|
||||||
vector<Tab> tabs;
|
PIVector<Tab> tabs;
|
||||||
Variable tv;
|
Variable tv;
|
||||||
PIKbdListener * listener;
|
PIKbdListener * listener;
|
||||||
KBFunc ret_func;
|
KBFunc ret_func;
|
||||||
int width, height, ret, col_wid, num_format;
|
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
||||||
uint my;
|
uint my;
|
||||||
uint cur_tab, col_cnt;
|
uint cur_tab, col_cnt;
|
||||||
|
|
||||||
|
|||||||
226
picontainers.h
Normal file
226
picontainers.h
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
#ifndef PICONTAINERS_H
|
||||||
|
#define PICONTAINERS_H
|
||||||
|
|
||||||
|
#include "piincludes.h"
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
class _PIForeachC {
|
||||||
|
public:
|
||||||
|
_PIForeachC(const Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;}
|
||||||
|
typename Type::value_type _var;
|
||||||
|
typename Type::const_iterator _it;
|
||||||
|
typename Type::const_reverse_iterator _rit;
|
||||||
|
const Type & _t;
|
||||||
|
bool _break, _inv;
|
||||||
|
inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
|
||||||
|
inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
class _PIForeach {
|
||||||
|
public:
|
||||||
|
_PIForeach(Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;}
|
||||||
|
typename Type::value_type _var;
|
||||||
|
typename Type::iterator _it;
|
||||||
|
typename Type::reverse_iterator _rit;
|
||||||
|
Type & _t;
|
||||||
|
bool _break, _inv;
|
||||||
|
inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
|
||||||
|
inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define piForTimes(c) for(int i = 0; i < c; ++i)
|
||||||
|
|
||||||
|
#define piForeach(i,c) for(_PIForeach<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(i = *_for._it; !_for._break; _for._break = true)
|
||||||
|
#define piForeachR(i,c) for(_PIForeach<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(i = *_for._rit; !_for._break; _for._break = true)
|
||||||
|
#define piForeachA(i,c) for(_PIForeach<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
|
||||||
|
#define piForeachAR(i,c) for(_PIForeach<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
|
||||||
|
#define piForeachC(i,c) for(_PIForeachC<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(const i = *_for._it; !_for._break; _for._break = true)
|
||||||
|
#define piForeachCR(i,c) for(_PIForeachC<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(const i = *_for._rit; !_for._break; _for._break = true)
|
||||||
|
#define piForeachCA(i,c) for(_PIForeachC<typeof(c)> _for(c); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
|
||||||
|
#define piForeachCAR(i,c) for(_PIForeachC<typeof(c)> _for(c, true); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
|
||||||
|
|
||||||
|
#define piForeachRA piForeachAR
|
||||||
|
#define piForeachRC piForeachCR
|
||||||
|
#define piForeachAC piForeachCA
|
||||||
|
#define piForeachCRA piForeachCAR
|
||||||
|
#define piForeachARC piForeachCAR
|
||||||
|
#define piForeachACR piForeachCAR
|
||||||
|
#define piForeachRCA piForeachCAR
|
||||||
|
#define piForeachRAC piForeachCAR
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
class PIFlags {
|
||||||
|
public:
|
||||||
|
inline PIFlags(): flags(0) {;}
|
||||||
|
inline PIFlags(Enum e): flags(e) {;}
|
||||||
|
inline PIFlags(const PIFlags & f): flags(f.flags) {;}
|
||||||
|
inline PIFlags(const int i): flags(i) {;}
|
||||||
|
inline void operator =(const PIFlags & f) {flags = f.flags;}
|
||||||
|
inline void operator =(const Enum & e) {flags = e;}
|
||||||
|
inline void operator =(const int & i) {flags = i;}
|
||||||
|
inline void operator |=(const PIFlags & f) {flags = flags | f.flags;}
|
||||||
|
inline void operator |=(const Enum & e) {flags = flags | e;}
|
||||||
|
inline void operator |=(const int i) {flags = flags | i;}
|
||||||
|
inline void operator &=(const PIFlags & f) {flags = flags & f.flags;}
|
||||||
|
inline void operator &=(const Enum & e) {flags = flags & e;}
|
||||||
|
inline void operator &=(const int i) {flags = flags & i;}
|
||||||
|
inline PIFlags & operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
|
||||||
|
inline PIFlags & operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
|
||||||
|
inline PIFlags & operator |(int i) const {PIFlags tf(flags | i); return tf;}
|
||||||
|
inline PIFlags & operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
|
||||||
|
inline PIFlags & operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
|
||||||
|
inline PIFlags & operator &(int i) const {PIFlags tf(flags & i); return tf;}
|
||||||
|
inline bool operator [](Enum e) {return (flags & e) == e;}
|
||||||
|
inline operator int() const {return flags;}
|
||||||
|
private:
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
|
class PIVector: public vector<Type, Allocator> {
|
||||||
|
typedef PIVector<Type, Allocator> _CVector;
|
||||||
|
typedef vector<Type, Allocator> _stlc;
|
||||||
|
public:
|
||||||
|
inline PIVector() {;}
|
||||||
|
inline PIVector(const Type & value) {_stlc::push_back(value);}
|
||||||
|
inline PIVector(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||||
|
inline PIVector(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||||
|
inline PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||||
|
inline PIVector(uint size, const Type & value = Type()) {_stlc::resize(size, value);}
|
||||||
|
inline const Type & at(uint index) const {return (*this)[index];}
|
||||||
|
inline Type & at(uint index) {return (*this)[index];}
|
||||||
|
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||||
|
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||||
|
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
inline bool isEmpty() const {return _stlc::empty();}
|
||||||
|
inline _CVector & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||||
|
inline _CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
|
||||||
|
inline _CVector & push_front(const Type & t) {_stlc::insert(_stlc::begin(), t); return *this;}
|
||||||
|
inline _CVector & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||||
|
inline _CVector & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||||
|
inline _CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;}
|
||||||
|
inline _CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||||
|
inline _CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||||
|
inline bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIVector<Type> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
|
||||||
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
|
class PIList: public list<Type, Allocator> {
|
||||||
|
typedef PIList<Type, Allocator> _CList;
|
||||||
|
typedef list<Type, Allocator> _stlc;
|
||||||
|
public:
|
||||||
|
inline PIList() {;}
|
||||||
|
inline PIList(const Type & value) {_stlc::resize(1, value);}
|
||||||
|
inline PIList(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||||
|
inline PIList(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||||
|
inline PIList(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||||
|
inline PIList(uint size, const Type & value = Type()) {_stlc::resize(size, value);}
|
||||||
|
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
||||||
|
inline Type * data(uint index = 0) {return &(*this)[index];}
|
||||||
|
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
inline bool isEmpty() const {return _stlc::empty();}
|
||||||
|
inline _CList & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
|
||||||
|
inline _CList & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||||
|
inline _CList & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||||
|
inline _CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
|
||||||
|
inline _CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
|
||||||
|
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename Compare = std::less<Type>, typename Allocator = std::allocator<Type> >
|
||||||
|
class PISet: public set<Type, Compare, Allocator> {
|
||||||
|
typedef PISet<Type, Compare, Allocator> _CSet;
|
||||||
|
typedef set<Type, Compare, Allocator> _stlc;
|
||||||
|
public:
|
||||||
|
inline PISet() {;}
|
||||||
|
inline PISet(const Type & value) {_stlc::resize(1, value);}
|
||||||
|
inline PISet(const Type & v0, const Type & v1) {_stlc::insert(v0); _stlc::insert(v1);}
|
||||||
|
inline PISet(const Type & v0, const Type & v1, const Type & v2) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2);}
|
||||||
|
inline PISet(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2); _stlc::insert(v3);}
|
||||||
|
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
inline bool isEmpty() const {return _stlc::empty();}
|
||||||
|
inline _CSet & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;}
|
||||||
|
inline _CSet & remove(uint num, uint count) {_stlc::erase(_stlc::begin() + num, _stlc::begin() + num + count); return *this;}
|
||||||
|
inline _CSet & operator <<(const Type & t) {_stlc::insert(t); return *this;}
|
||||||
|
inline bool operator [](const Type & t) {return _stlc::find(t);}
|
||||||
|
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
class PIStack: public PIVector<Type> {
|
||||||
|
typedef PIStack<Type> _CStack;
|
||||||
|
public:
|
||||||
|
inline PIStack() {;}
|
||||||
|
inline PIStack(const Type & value) {_CStack::resize(1, value);}
|
||||||
|
inline PIStack(const Type & v0, const Type & v1) {_CStack::push_back(v0); _CStack::push_back(v1);}
|
||||||
|
inline PIStack(const Type & v0, const Type & v1, const Type & v2) {_CStack::push_back(v0); _CStack::push_back(v1); _CStack::push_back(v2);}
|
||||||
|
inline PIStack(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_CStack::push_back(v0); _CStack::push_back(v1); _CStack::push_back(v2); _CStack::push_back(v3);}
|
||||||
|
inline _CStack & push(const Type & v) {_CStack::push_back(v); return *this;}
|
||||||
|
inline Type pop() {Type t = Type(); if (_CStack::size() == 0) return t; t = _CStack::back(); _CStack::pop_back(); return t;}
|
||||||
|
inline Type & top() {return _CStack::back();}
|
||||||
|
inline const Type & top() const {return _CStack::back();}
|
||||||
|
inline PIVector<Type> toVector() {PIVector<Type> v; for (typename _CStack::const_iterator i = _CStack::begin(); i != _CStack::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename Allocator = std::allocator<Type> >
|
||||||
|
class PIDeque: public deque<Type, Allocator> {
|
||||||
|
typedef PIDeque<Type, Allocator> _CDeque;
|
||||||
|
typedef deque<Type, Allocator> _stlc;
|
||||||
|
public:
|
||||||
|
inline PIDeque() {;}
|
||||||
|
inline PIDeque(const Type & value) {_stlc::resize(1, value);}
|
||||||
|
inline PIDeque(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);}
|
||||||
|
inline PIDeque(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
|
||||||
|
inline PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
|
||||||
|
inline int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
inline bool isEmpty() const {return _stlc::empty();}
|
||||||
|
inline _CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
|
||||||
|
inline PIVector<Type, Allocator> toVector() {PIVector<Type, Allocator> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
class PIQueue: public PIDeque<Type> {
|
||||||
|
typedef PIQueue<Type> _CQueue;
|
||||||
|
public:
|
||||||
|
inline PIQueue() {;}
|
||||||
|
inline PIQueue(const Type & value) {_CQueue::resize(1, value);}
|
||||||
|
inline PIQueue(const Type & v0, const Type & v1) {_CQueue::push_front(v0); _CQueue::push_front(v1);}
|
||||||
|
inline PIQueue(const Type & v0, const Type & v1, const Type & v2) {_CQueue::push_front(v0); _CQueue::push_front(v1); _CQueue::push_front(v2);}
|
||||||
|
inline PIQueue(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_CQueue::push_front(v0); _CQueue::push_front(v1); _CQueue::push_front(v2); _CQueue::push_front(v3);}
|
||||||
|
inline _CQueue & enqueue(const Type & v) {_CQueue::push_front(v); return *this;}
|
||||||
|
inline Type dequeue() {Type t = Type(); if (_CQueue::size() == 0) return t; t = _CQueue::back(); _CQueue::pop_back(); return t;}
|
||||||
|
inline Type & head() {return _CQueue::back();}
|
||||||
|
inline const Type & head() const {return _CQueue::back();}
|
||||||
|
inline PIVector<Type> toVector() {PIVector<Type> v; for (typename _CQueue::const_iterator i = _CQueue::begin(); i != _CQueue::end(); ++i) v << *i; return v;}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
class PIPair {
|
||||||
|
public:
|
||||||
|
inline PIPair() {first = Type0(); second = Type1();}
|
||||||
|
inline PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||||
|
Type0 first;
|
||||||
|
Type1 second;
|
||||||
|
};
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Type, typename Key = int>
|
||||||
|
class PIHash: public PISet<PIPair<Key, Type> > {
|
||||||
|
typedef PIHash<Type, Key> _CHash;
|
||||||
|
typedef PISet<PIPair<Key, Type> > _CSet;
|
||||||
|
public:
|
||||||
|
inline PIHash() {;}
|
||||||
|
inline PIHash(const Type & value, const Key & key) {insert(value, key);}
|
||||||
|
inline _CHash & insert(const Type & value, const Key & key) {_CSet::insert(PIPair<Key, Type>(key, value));}
|
||||||
|
inline Type value(Key key) {piForeachCA (i, *this) if (i.first == key) return i.second;; return Key();}
|
||||||
|
inline Type operator[](Key key) {return value(key);}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PICONTAINERS_H
|
||||||
140
pidir.cpp
140
pidir.cpp
@@ -1,5 +1,19 @@
|
|||||||
#include "pidir.h"
|
#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) {
|
PIDir::PIDir(const PIString & dir) {
|
||||||
path_ = dir.stdString();
|
path_ = dir.stdString();
|
||||||
@@ -17,7 +31,7 @@ bool PIDir::open() {
|
|||||||
if (dir_ != 0)
|
if (dir_ != 0)
|
||||||
if (!close())
|
if (!close())
|
||||||
return false;
|
return false;
|
||||||
dir_ = opendir(path_.c_str());
|
dir_ = opendir(path_.data());
|
||||||
return (dir_ != 0);
|
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() {
|
PIDir PIDir::current() {
|
||||||
char rc[1024];
|
char rc[1024];
|
||||||
if (getcwd(rc, 1024) == 0) return PIString();
|
if (getcwd(rc, 1024) == 0) return PIString();
|
||||||
@@ -58,12 +184,10 @@ PIDir PIDir::temporary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIDir::mkDir(const PIString & path) {
|
bool PIDir::mkDir(const PIString & path, bool withParents) {
|
||||||
string s = path.stdString();
|
PIDir d(path);
|
||||||
int ret = mkdir(s.c_str(), 16877);
|
if (d.isExists()) return true;
|
||||||
if (ret == 0) return true;
|
return d.mkDir(withParents);
|
||||||
printf("[PIDir] mkDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -74,3 +198,5 @@ bool PIDir::rmDir(const PIString & path) {
|
|||||||
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
42
pidir.h
42
pidir.h
@@ -2,41 +2,67 @@
|
|||||||
#define PIDIR_H
|
#define PIDIR_H
|
||||||
|
|
||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
|
#ifndef WINDOWS
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
class PIDir
|
class PIDir
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIDir() {dir_ = 0;}
|
PIDir();
|
||||||
PIDir(const PIString & dir);
|
PIDir(const PIString & dir);
|
||||||
~PIDir() {close();}
|
~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 isExists() {return (dir_ != 0);}
|
||||||
|
inline const bool isAbsolute() {if (path_.size() == 0) return false; return (path_[0] == separator);}
|
||||||
inline PIString path() {return PIString(path_);}
|
inline PIString path() {return PIString(path_);}
|
||||||
|
PIDir & cleanPath();
|
||||||
|
inline PIDir cleanedPath() {PIDir d(path_); d.cleanPath(); return d;}
|
||||||
PIString absolutePath();
|
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;
|
bool operator ==(const PIDir & d) const;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
static const PIChar separator;
|
||||||
static const char separator = '\\';
|
|
||||||
#else
|
|
||||||
static const char separator = '/';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static PIDir current();
|
static PIDir current();
|
||||||
static PIDir home();
|
static PIDir home();
|
||||||
static PIDir temporary();
|
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 rmDir(const PIString & path);
|
||||||
|
static bool isExists(const PIString & path) {return PIDir(path).isExists();}
|
||||||
//static bool rmDir(const PIString & path);
|
//static bool rmDir(const PIString & path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open();
|
bool open();
|
||||||
bool close();
|
bool close();
|
||||||
|
|
||||||
string path_;
|
PIString path_;
|
||||||
|
|
||||||
DIR * dir_;
|
DIR * dir_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif // PIDIR_H
|
#endif // PIDIR_H
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot):
|
|||||||
port_ = port_s = port;
|
port_ = port_s = port;
|
||||||
sock = sock_s = -1;
|
sock = sock_s = -1;
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
buffer = new char[BUFFER_SIZE];
|
tries = 0;
|
||||||
|
//buffer_ = new char[BUFFER_SIZE];
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
@@ -22,26 +23,36 @@ PIEthernet::~PIEthernet() {
|
|||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
delete buffer;
|
|
||||||
if (sock != -1) {
|
if (sock != -1) {
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
|
#endif
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
if (sock_s != -1) {
|
if (sock_s != -1) {
|
||||||
shutdown(sock_s, SHUT_RDWR);
|
shutdown(sock_s, SHUT_RDWR);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
closesocket(sock_s);
|
||||||
|
#else
|
||||||
close(sock_s);
|
close(sock_s);
|
||||||
|
#endif
|
||||||
sock_s = -1;
|
sock_s = -1;
|
||||||
}
|
}
|
||||||
|
//if (buffer_ != 0) delete buffer_;
|
||||||
|
//buffer_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::terminate() {
|
void PIEthernet::terminate() {
|
||||||
if (!initialized()) return;
|
if (!receiverInitialized()) return;
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
stop();
|
stop();
|
||||||
pthread_cancel(thread);
|
pthread_cancel(thread);
|
||||||
}
|
}
|
||||||
|
tries = 0;
|
||||||
/*if (sock != -1) {
|
/*if (sock != -1) {
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
@@ -63,20 +74,20 @@ void PIEthernet::begin() {
|
|||||||
|
|
||||||
void PIEthernet::run() {
|
void PIEthernet::run() {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
int addr_len;
|
int addr_len = sizeof(sockaddr_storage);
|
||||||
#else
|
#else
|
||||||
socklen_t addr_len;
|
socklen_t addr_len = sizeof(sockaddr_storage);
|
||||||
#endif
|
#endif
|
||||||
//cout << "[PIEthernet] reading ... ";
|
//cout << "[PIEthernet] reading from " << &addr_ << endl;
|
||||||
readed = recvfrom(sock, buffer, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len);
|
readed = recvfrom(sock, buffer_, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len);
|
||||||
//cout << WSAGetLastError() << endl;
|
//cout << WSAGetLastError() << endl;
|
||||||
if (readed < 0) {
|
if (readed < 0) {
|
||||||
//cout << "[PIEthernet] Error while reading" << endl;
|
cout << "[PIEthernet] Error while reading, " << errorString() << endl;
|
||||||
//stop();
|
//stop();
|
||||||
//init();
|
//init();
|
||||||
return;
|
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() {
|
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_family = PF_INET;
|
||||||
addr_.sin_port = htons(port_);
|
addr_.sin_port = htons(port_);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
|
#endif
|
||||||
sock = socket(PF_INET, SOCK_DGRAM, 0);
|
sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) {
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -100,10 +121,20 @@ bool PIEthernet::init() {
|
|||||||
|
|
||||||
|
|
||||||
bool PIEthernet::initSend() {
|
bool PIEthernet::initSend() {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
closesocket(sock_s);
|
||||||
|
#else
|
||||||
close(sock_s);
|
close(sock_s);
|
||||||
|
#endif
|
||||||
sock_s = socket(PF_INET, SOCK_DGRAM, 0);
|
sock_s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock_s == -1) {
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -116,7 +147,7 @@ bool PIEthernet::send(PIString ip, int port, char * data, int size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
saddr_.sin_port = htons(port);
|
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;
|
saddr_.sin_family = PF_INET;
|
||||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||||
if (wrote != size) {
|
if (wrote != size) {
|
||||||
@@ -134,7 +165,7 @@ bool PIEthernet::send(char * data, int size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
saddr_.sin_port = htons(port_s);
|
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;
|
saddr_.sin_family = PF_INET;
|
||||||
//cout << "[PIEthernet] sending in " << sock_s << endl;
|
//cout << "[PIEthernet] sending in " << sock_s << endl;
|
||||||
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
wrote = sendto(sock_s, data, size, 0, (sockaddr * )&saddr_, sizeof(saddr_));
|
||||||
|
|||||||
14
piethernet.h
14
piethernet.h
@@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
#define BUFFER_SIZE 4096
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
typedef bool (*EthernetFunc)(void * , char * );
|
typedef bool (*EthernetFunc)(void * , char * , int );
|
||||||
|
|
||||||
class PIEthernet: public PIThread
|
class PIEthernet: public PIThread
|
||||||
{
|
{
|
||||||
public:
|
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(PIString ip = "", int port = 0, void * data = 0, EthernetFunc slot = 0);
|
||||||
~PIEthernet();
|
~PIEthernet();
|
||||||
|
|
||||||
@@ -32,22 +32,22 @@ public:
|
|||||||
bool send(char * data, int size);
|
bool send(char * data, int size);
|
||||||
bool init();
|
bool init();
|
||||||
bool initSend();
|
bool initSend();
|
||||||
bool initialized() const {return sock != -1;}
|
bool receiverInitialized() const {return sock != -1;}
|
||||||
|
bool senderInitialized() const {return sock_s != -1;}
|
||||||
void terminate();
|
void terminate();
|
||||||
|
inline const char * buffer() const {return buffer_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void begin();
|
void begin();
|
||||||
void run();
|
void run();
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
|
int sock, sock_s, port_, port_s, wrote, readed, tries;
|
||||||
int sock, sock_s, port_, port_s, wrote;
|
|
||||||
sockaddr_in addr_, saddr_;
|
sockaddr_in addr_, saddr_;
|
||||||
PIString ip_, ip_s;
|
PIString ip_, ip_s;
|
||||||
EthernetFunc ret_func;
|
EthernetFunc ret_func;
|
||||||
char * buffer;
|
|
||||||
void * data;
|
void * data;
|
||||||
int readed;
|
char buffer_[BUFFER_SIZE];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1033
pievaluator.cpp
Normal file
1033
pievaluator.cpp
Normal file
@@ -0,0 +1,1033 @@
|
|||||||
|
#include "pievaluator.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorContent::PIEvaluatorContent() {
|
||||||
|
addFunction("arcsin", 1);
|
||||||
|
addFunction("arccos", 1);
|
||||||
|
addFunction("arctg", 1);
|
||||||
|
addFunction("arcctg", 1);
|
||||||
|
addFunction("random", 2);
|
||||||
|
addFunction("sin", 1);
|
||||||
|
addFunction("cos", 1);
|
||||||
|
addFunction("ctg", 1);
|
||||||
|
addFunction("tg", 1);
|
||||||
|
addFunction("exp", 1);
|
||||||
|
addFunction("cth", 1);
|
||||||
|
addFunction("sh", 1);
|
||||||
|
addFunction("ch", 1);
|
||||||
|
addFunction("th", 1);
|
||||||
|
addFunction("sqrt", 1);
|
||||||
|
addFunction("sqr", 1);
|
||||||
|
addFunction("pow", 2);
|
||||||
|
addFunction("abs", 1);
|
||||||
|
addFunction("ln", 1);
|
||||||
|
addFunction("lg", 1);
|
||||||
|
addFunction("log", 2);
|
||||||
|
addFunction("im", 1);
|
||||||
|
addFunction("re", 1);
|
||||||
|
addFunction("arg", 1);
|
||||||
|
addFunction("len", 1);
|
||||||
|
addFunction("conj", 1);
|
||||||
|
addFunction("sign", 1);
|
||||||
|
addFunction("rad", 1);
|
||||||
|
addFunction("deg", 1);
|
||||||
|
clearCustomVariables();
|
||||||
|
//addVariable("n", 0.);
|
||||||
|
//addVariable("x1", 123);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluatorContent::setVariableValue(int index, complexd new_value) {
|
||||||
|
if (index < 0 || index >= variables.size_s()) return false;
|
||||||
|
variables[index].value = new_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluatorContent::setVariableName(int index, const PIString & new_name) {
|
||||||
|
if (index < 0 || index >= variables.size_s()) return false;
|
||||||
|
variables[index].name = new_name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::clearCustomVariables() {
|
||||||
|
variables.clear();
|
||||||
|
addVariable("i", complexd_1);
|
||||||
|
addVariable("pi", atan(1.) * 4.);
|
||||||
|
addVariable("e", exp(1.));
|
||||||
|
cv_count = variables.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::sortVariables() {
|
||||||
|
PIEvaluatorTypes::Variable tv;
|
||||||
|
for (uint i = 0; i < variables.size(); i++) {
|
||||||
|
for (uint j = variables.size() - 1; j > i; j--) {
|
||||||
|
if (variables[j].name.length() <= variables[i].name.length()) continue;
|
||||||
|
piSwap<PIEvaluatorTypes::Variable>(variables[i], variables[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* qDebug() << "---";
|
||||||
|
* for (int i = 0; i < variables.size(); i++) {
|
||||||
|
* qDebug() << variables[i].name;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorTypes::BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) {
|
||||||
|
if (name == "sin") return PIEvaluatorTypes::bfSin;
|
||||||
|
if (name == "cos") return PIEvaluatorTypes::bfCos;
|
||||||
|
if (name == "tg") return PIEvaluatorTypes::bfTg;
|
||||||
|
if (name == "ctg") return PIEvaluatorTypes::bfCtg;
|
||||||
|
if (name == "arcsin") return PIEvaluatorTypes::bfArcsin;
|
||||||
|
if (name == "arccos") return PIEvaluatorTypes::bfArccos;
|
||||||
|
if (name == "arctg") return PIEvaluatorTypes::bfArctg;
|
||||||
|
if (name == "arcctg") return PIEvaluatorTypes::bfArcctg;
|
||||||
|
if (name == "exp") return PIEvaluatorTypes::bfExp;
|
||||||
|
if (name == "random") return PIEvaluatorTypes::bfRandom;
|
||||||
|
if (name == "sh") return PIEvaluatorTypes::bfSh;
|
||||||
|
if (name == "ch") return PIEvaluatorTypes::bfCh;
|
||||||
|
if (name == "th") return PIEvaluatorTypes::bfTh;
|
||||||
|
if (name == "cth") return PIEvaluatorTypes::bfCth;
|
||||||
|
if (name == "sqrt") return PIEvaluatorTypes::bfSqrt;
|
||||||
|
if (name == "sqr") return PIEvaluatorTypes::bfSqr;
|
||||||
|
if (name == "pow") return PIEvaluatorTypes::bfPow;
|
||||||
|
if (name == "abs") return PIEvaluatorTypes::bfAbs;
|
||||||
|
if (name == "ln") return PIEvaluatorTypes::bfLn;
|
||||||
|
if (name == "lg") return PIEvaluatorTypes::bfLg;
|
||||||
|
if (name == "log") return PIEvaluatorTypes::bfLog;
|
||||||
|
if (name == "im") return PIEvaluatorTypes::bfIm;
|
||||||
|
if (name == "re") return PIEvaluatorTypes::bfRe;
|
||||||
|
if (name == "arg") return PIEvaluatorTypes::bfArg;
|
||||||
|
if (name == "len") return PIEvaluatorTypes::bfLen;
|
||||||
|
if (name == "conj") return PIEvaluatorTypes::bfConj;
|
||||||
|
if (name == "sign") return PIEvaluatorTypes::bfSign;
|
||||||
|
if (name == "rad") return PIEvaluatorTypes::bfRad;
|
||||||
|
if (name == "deg") return PIEvaluatorTypes::bfDeg;
|
||||||
|
return PIEvaluatorTypes::bfUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PIString & PIEvaluator::prepare(const PIString & string) {
|
||||||
|
currentString = string.trimmed();
|
||||||
|
if (currentString.isEmpty()) currentString = "0";
|
||||||
|
replaceOperators();
|
||||||
|
removeSpaces();
|
||||||
|
checkBrackets();
|
||||||
|
while (fillElements()) checkBrackets();
|
||||||
|
while (setSignes()) fillElements();
|
||||||
|
removeJunk();
|
||||||
|
findUnknownVariables();
|
||||||
|
return currentString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::removeSpaces() {
|
||||||
|
PIString tmps = currentString;
|
||||||
|
for (int i = 0; i < tmps.length(); i++) {
|
||||||
|
if (tmps[i] == ' ' || tmps[i] == '\t') {
|
||||||
|
tmps.remove(i, 1);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentString = tmps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::removeJunk() {
|
||||||
|
PIChar cc;
|
||||||
|
bool junk = true;
|
||||||
|
int bcnt;
|
||||||
|
while (junk) {
|
||||||
|
if (currentString.left(1) != "(" || currentString.right(1) != ")") return;
|
||||||
|
bcnt = 1;
|
||||||
|
junk = false;
|
||||||
|
for (int i = 1; i < currentString.length(); i++) {
|
||||||
|
cc = currentString[i];
|
||||||
|
if (cc == '(') bcnt++;
|
||||||
|
if (cc == ')') bcnt--;
|
||||||
|
if (bcnt == 0) {
|
||||||
|
if (i == currentString.length() - 1) {
|
||||||
|
currentString = currentString.mid(1, currentString.length() - 2);
|
||||||
|
elements.pop_front();
|
||||||
|
elements.pop_back();
|
||||||
|
junk = true;
|
||||||
|
break;
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::replaceOperators() {
|
||||||
|
currentString.replaceAll("==", "=");
|
||||||
|
currentString.replaceAll("!=", ":");
|
||||||
|
currentString.replaceAll(">=", "}");
|
||||||
|
currentString.replaceAll("<=", "{");
|
||||||
|
currentString.replaceAll("&&", "&");
|
||||||
|
currentString.replaceAll("||", "|");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::makeOutput(PIString & string) {
|
||||||
|
string.replaceAll(":", "≠");
|
||||||
|
string.replaceAll("}", "≥");
|
||||||
|
string.replaceAll("{", "≤");
|
||||||
|
string.replaceAll("&", "⋀");
|
||||||
|
string.replaceAll("|", "⋁");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::findUnknownVariables() {
|
||||||
|
PIString cvar;
|
||||||
|
unknownVars.clear();
|
||||||
|
for (int i = 0; i < currentString.length(); i++) {
|
||||||
|
if (elements[i].var_num == -666) cvar += currentString[i];
|
||||||
|
else {
|
||||||
|
if (cvar.length() == 0) continue;
|
||||||
|
unknownVars << cvar;
|
||||||
|
cvar = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cvar.length() > 0) unknownVars << cvar;
|
||||||
|
unknownVars.removeDuplicates();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluator::isSign(const PIChar & ch) {
|
||||||
|
return ch == '+' || ch == '-' ||
|
||||||
|
ch == '*' || ch == '/' ||
|
||||||
|
ch == '%' || ch == '^' ||
|
||||||
|
ch == '=' || ch == ':' ||
|
||||||
|
ch == '>' || ch == '<' ||
|
||||||
|
ch == '}' || ch == '{' ||
|
||||||
|
ch == '&' || ch == '|';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::checkBrackets() {
|
||||||
|
PIString tmps = currentString;
|
||||||
|
PIChar fc, sc;
|
||||||
|
int bcnt = 0, bpos = 0, inserted = 0;
|
||||||
|
currentString = tmps;
|
||||||
|
for (int i = 0; i < tmps.length(); i++) {
|
||||||
|
if (tmps[i] == '(') {
|
||||||
|
if (bcnt == 0) bpos = i;
|
||||||
|
bcnt++;
|
||||||
|
}
|
||||||
|
if (tmps[i] == ')') {
|
||||||
|
if (bcnt == 0) {
|
||||||
|
currentString.insert(bpos + inserted, "(");
|
||||||
|
inserted++;
|
||||||
|
} else bcnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bcnt > 0) currentString += PIString(bcnt, ')');
|
||||||
|
tmps = currentString;
|
||||||
|
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||||
|
fc = tmps[i].toLower();
|
||||||
|
sc = tmps[i + 1].toLower();
|
||||||
|
if ((fc == ')' && sc == '(') ||
|
||||||
|
(fc == ')' && sc >= '0' && sc <= '9') ||
|
||||||
|
(fc == ')' && sc >= 'a' && sc <= 'z') ) tmps.insert(++i, '*');
|
||||||
|
}
|
||||||
|
currentString = tmps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluator::fillElements() {
|
||||||
|
int fstart, flen, cnum = 0, cpart = 0, cfunc;
|
||||||
|
PIChar cc, nc, pc, fc = '!';
|
||||||
|
bool numFound = false;
|
||||||
|
PIString curfind, tmps = currentString;
|
||||||
|
elements.resize(tmps.length());
|
||||||
|
for (uint i = 0; i < elements.size(); i++) {
|
||||||
|
elements[i].type = PIEvaluatorTypes::etVariable;
|
||||||
|
elements[i].var_num = -666;
|
||||||
|
}
|
||||||
|
currentVariables.clear();
|
||||||
|
//qDebug().nospace() << "search for functions ...";
|
||||||
|
for (int i = 0; i < content.functionsCount(); i++) {
|
||||||
|
curfind = content.function(i).identifier;
|
||||||
|
cfunc = i; //(int)content.function(i).type;
|
||||||
|
flen = curfind.length();
|
||||||
|
fstart = 0;
|
||||||
|
while (fstart >= 0) {
|
||||||
|
fstart = tmps.find(curfind, fstart);
|
||||||
|
if (fstart < 0) break;
|
||||||
|
if (tmps[fstart + flen] != '(') {
|
||||||
|
currentString.insert(fstart + flen, "(");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int j = fstart; j < fstart + flen; j++) {
|
||||||
|
elements[j].set(PIEvaluatorTypes::etFunction, cnum, cfunc);
|
||||||
|
tmps.replace(j, 1, fc);
|
||||||
|
}
|
||||||
|
cnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnum = 0;
|
||||||
|
//qDebug().nospace() << "search for variables ...";
|
||||||
|
for (int i = 0; i < content.variablesCount(); i++) {
|
||||||
|
curfind = content.variable(i).name;
|
||||||
|
flen = curfind.length();
|
||||||
|
fstart = 0;
|
||||||
|
while (fstart >= 0) {
|
||||||
|
fstart = tmps.find(curfind, fstart);
|
||||||
|
if (fstart < 0) break;
|
||||||
|
for (int j = fstart; j < fstart + flen; j++) {
|
||||||
|
elements[j].set(PIEvaluatorTypes::etVariable, cnum, i);
|
||||||
|
tmps.replace(j, 1, fc);
|
||||||
|
}
|
||||||
|
cnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curfind = "";
|
||||||
|
cnum = 1;
|
||||||
|
//qDebug().nospace() << "search for numbers ...";
|
||||||
|
for (int i = 0; i < tmps.length(); i++) {
|
||||||
|
cc = tmps[i];
|
||||||
|
/*if (cc == " " || cc == "(" || cc == ")") {
|
||||||
|
curfind = "";
|
||||||
|
cpart = 0;
|
||||||
|
numFound = false;
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
switch (cpart) {
|
||||||
|
case 0:
|
||||||
|
if ((cc >= '0' && cc <= '9')) {// || cc == '-' || cc == '+') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == '.') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == 'E') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (cc >= '0' && cc <= '9') {
|
||||||
|
curfind += cc;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == '.') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == 'E') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
numFound = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (cc >= '0' && cc <= '9') {
|
||||||
|
curfind += cc;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == 'E') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
numFound = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if ((cc >= '0' && cc <= '9') || cc == '-' || cc == '+') {
|
||||||
|
curfind += cc;
|
||||||
|
cpart = 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
numFound = true;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (cc >= '0' && cc <= '9') {
|
||||||
|
curfind += cc;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
numFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (numFound) {
|
||||||
|
//qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble();
|
||||||
|
currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble()));
|
||||||
|
for (int j = i - curfind.length(); j < i; j++) {
|
||||||
|
elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum);
|
||||||
|
tmps.replace(j, 1, fc);
|
||||||
|
}
|
||||||
|
curfind = "";
|
||||||
|
cnum++;
|
||||||
|
cpart = 0;
|
||||||
|
numFound = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cpart > 0) {
|
||||||
|
//qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble();
|
||||||
|
currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble()));
|
||||||
|
for (int j = tmps.length() - curfind.length(); j < tmps.length(); j++) {
|
||||||
|
elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum);
|
||||||
|
tmps.replace(j, 1, fc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc = nc = fc;
|
||||||
|
//qDebug().nospace() << "search for signes ...";
|
||||||
|
for (int i = 0; i < tmps.length(); i++) {
|
||||||
|
cc = tmps[i];
|
||||||
|
if (i > 0) pc = tmps[i - 1];
|
||||||
|
else pc = fc;
|
||||||
|
if (i < tmps.length() - 1) nc = tmps[i + 1];
|
||||||
|
else nc = fc;
|
||||||
|
if (cc == '(' || cc == ')' || cc == ',') {
|
||||||
|
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == '-' || cc == '+') {
|
||||||
|
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||||
|
if (i < tmps.length() - 1) if (elements[i + 1].type == PIEvaluatorTypes::etVariable ||
|
||||||
|
elements[i + 1].type == PIEvaluatorTypes::etFunction) continue;
|
||||||
|
if ((pc == '(' || isSign(pc) || i == 0) && i < tmps.length() - 1) {
|
||||||
|
if (elements[i + 1].type != PIEvaluatorTypes::etOperator) {
|
||||||
|
cnum = elements[i + 1].num;
|
||||||
|
elements[i].set(PIEvaluatorTypes::etNumber, cnum);
|
||||||
|
tmps.replace(i, 1, fc);
|
||||||
|
///cout << "found sign " << cc << " :" << cnum - 1 << endl;
|
||||||
|
if (cc == '-' && currentVariables.size_s() >= cnum)
|
||||||
|
currentVariables[cnum - 1].value = -currentVariables[cnum - 1].value;
|
||||||
|
//i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSign(cc)) {
|
||||||
|
elements[i].set(PIEvaluatorTypes::etOperator, -1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
qDebug().nospace() << tmps;
|
||||||
|
cout << " ";
|
||||||
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
|
switch (elements[i].type) {
|
||||||
|
case etFunction: cout << "f"; break;
|
||||||
|
case etNumber: cout << "n"; break;
|
||||||
|
case etOperator: cout << "o"; break;
|
||||||
|
case etVariable: cout << "v"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
//for (int i = 0; i < currentVariables.size(); i++) qDebug() << "var " << i << ": " << currentVariables[i].value.real();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluator::setSignes() {
|
||||||
|
int inserted = 0, ni, pi = 0, needInsert = 0;
|
||||||
|
PIChar fc, sc, pc;
|
||||||
|
PIString tmps = currentString;
|
||||||
|
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||||
|
needInsert = 0;
|
||||||
|
ni = i + 1;
|
||||||
|
if (i > 0) pi = i - 1;
|
||||||
|
fc = tmps[i].toLower();
|
||||||
|
sc = tmps[ni].toLower();
|
||||||
|
pc = tmps[pi].toLower();
|
||||||
|
//if (elements[i].type == etOperator || elements[ni].type == etVariable) continue;
|
||||||
|
if (fc == ',' || sc == ',') continue;
|
||||||
|
if (elements[i].type == PIEvaluatorTypes::etOperator && elements[ni].type == PIEvaluatorTypes::etOperator) continue;
|
||||||
|
if (fc == ')' && (elements[ni].type == PIEvaluatorTypes::etNumber || elements[ni].type == PIEvaluatorTypes::etVariable || elements[ni].type == PIEvaluatorTypes::etFunction)) needInsert = 1;
|
||||||
|
if (sc == '(' && (elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable)) needInsert = 1;
|
||||||
|
if (elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etNumber && elements[i].num != elements[ni].num) needInsert = 1;
|
||||||
|
if (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etVariable && elements[i].num != elements[ni].num) needInsert = 1;
|
||||||
|
if ((elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etVariable) || (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etNumber)) needInsert = 1;
|
||||||
|
if ((elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable) && elements[ni].type == PIEvaluatorTypes::etFunction) needInsert = 1;
|
||||||
|
if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type == PIEvaluatorTypes::etFunction && elements[i].num != elements[ni].num) needInsert = 2;
|
||||||
|
if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type != PIEvaluatorTypes::etFunction && sc != '(') needInsert = 2;
|
||||||
|
if (elements[pi].type == PIEvaluatorTypes::etOperator && (elements[ni].type == PIEvaluatorTypes::etFunction || elements[ni].type == PIEvaluatorTypes::etVariable) && fc == '-') needInsert = 3;
|
||||||
|
switch (needInsert) {
|
||||||
|
case 1:
|
||||||
|
currentString.insert(ni + inserted, "*");
|
||||||
|
elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1));
|
||||||
|
//inserted++;
|
||||||
|
//i++;
|
||||||
|
return true;
|
||||||
|
/*case 2:
|
||||||
|
currentString.insert(ni + inserted, ")");
|
||||||
|
currentString.insert(ni + inserted, "(");
|
||||||
|
elements.insert(ni + inserted, Element(etOperator, -1));
|
||||||
|
elements.insert(ni + inserted, Element(etOperator, -1));
|
||||||
|
inserted++;
|
||||||
|
i++;
|
||||||
|
return true;*/
|
||||||
|
case 3:
|
||||||
|
currentString.insert(ni + inserted, "1*");
|
||||||
|
elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1));
|
||||||
|
//inserted;
|
||||||
|
//i++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*if (elements[tmps.length() - 1].type == etFunction) {
|
||||||
|
currentString.insert(tmps.length() + inserted, ")");
|
||||||
|
currentString.insert(tmps.length() + inserted, "(");
|
||||||
|
elements.insert(tmps.length() + inserted, Element(etOperator, -1));
|
||||||
|
elements.insert(tmps.length() + inserted, Element(etOperator, -1));
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::convert() {
|
||||||
|
int j;
|
||||||
|
PIEvaluatorTypes::Element ce, pe;
|
||||||
|
for (int i = 0; i < currentString.length(); i++) {
|
||||||
|
pe = elements[i];
|
||||||
|
if (pe.type != PIEvaluatorTypes::etFunction) continue;
|
||||||
|
j = i + 1;
|
||||||
|
while (j < currentString.length()) {
|
||||||
|
ce = elements[j];
|
||||||
|
if (ce != pe) break;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
currentString.replace(i, j - i, " ");
|
||||||
|
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||||
|
//i++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < currentString.length(); i++) {
|
||||||
|
pe = elements[i];
|
||||||
|
if (pe.type != PIEvaluatorTypes::etNumber) continue;
|
||||||
|
j = i + 1;
|
||||||
|
while (j < currentString.length()) {
|
||||||
|
ce = elements[j];
|
||||||
|
if (ce != pe) break;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
currentString.replace(i, j - i, " ");
|
||||||
|
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||||
|
//i++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < currentString.length(); i++) {
|
||||||
|
pe = elements[i];
|
||||||
|
if (pe.type != PIEvaluatorTypes::etVariable) continue;
|
||||||
|
j = i + 1;
|
||||||
|
while (j < currentString.length()) {
|
||||||
|
ce = elements[j];
|
||||||
|
if (ce != pe) break;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
currentString.replace(i, j - i, " ");
|
||||||
|
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||||
|
//i++;
|
||||||
|
}
|
||||||
|
/*qDebug().nospace() << currentString;
|
||||||
|
cout << " ";
|
||||||
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
|
switch (elements[i].type) {
|
||||||
|
case etFunction: cout << "f"; break;
|
||||||
|
case etNumber: cout << "n"; break;
|
||||||
|
case etOperator: cout << "o"; break;
|
||||||
|
case etVariable: cout << "v"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const PIString & PIEvaluator::preprocess(const PIString & string) {
|
||||||
|
static PIString ret;
|
||||||
|
int lind;
|
||||||
|
ret = prepare(string);
|
||||||
|
convert();
|
||||||
|
instructions.clear();
|
||||||
|
//qDebug() << preproc->currentString;
|
||||||
|
variables = currentVariables;
|
||||||
|
lind = parse(currentString);
|
||||||
|
if (instructions.size() == 0) {
|
||||||
|
variables.push_back(PIEvaluatorTypes::Variable());
|
||||||
|
instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oNone, PIVector<int>(1, lind), -variables.size()));
|
||||||
|
}
|
||||||
|
kvars = &(content.variables);
|
||||||
|
/*
|
||||||
|
cout << endl << "variables:" << endl;
|
||||||
|
for (int i = 0; i < variables.size(); i++)
|
||||||
|
cout << i << " value = " << variables[i].value << endl;
|
||||||
|
|
||||||
|
cout << endl << "instructions:" << endl;
|
||||||
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
|
cout << i << endl;
|
||||||
|
cout << " operation " << instructions[i].operation << endl;
|
||||||
|
cout << " operators: ";
|
||||||
|
for (int j = 0; j < instructions[i].operators.size(); j++)
|
||||||
|
cout << instructions[i].operators[j] << "; ";
|
||||||
|
cout << endl << " function " << instructions[i].function << endl;
|
||||||
|
cout << " out " << instructions[i].out << endl;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
makeOutput(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorTypes::Operation PIEvaluator::operationInOrder(const int & index) {
|
||||||
|
switch (index) {
|
||||||
|
case 0: return PIEvaluatorTypes::oPower;
|
||||||
|
case 1: return PIEvaluatorTypes::oMultiply;
|
||||||
|
case 2: return PIEvaluatorTypes::oDivide;
|
||||||
|
case 3: return PIEvaluatorTypes::oResidue;
|
||||||
|
case 4: return PIEvaluatorTypes::oAdd;
|
||||||
|
case 5: return PIEvaluatorTypes::oSubtract;
|
||||||
|
case 6: return PIEvaluatorTypes::oEqual;
|
||||||
|
case 7: return PIEvaluatorTypes::oNotEqual;
|
||||||
|
case 8: return PIEvaluatorTypes::oGreaterEqual;
|
||||||
|
case 9: return PIEvaluatorTypes::oSmallerEqual;
|
||||||
|
case 10: return PIEvaluatorTypes::oGreater;
|
||||||
|
case 11: return PIEvaluatorTypes::oSmaller;
|
||||||
|
case 12: return PIEvaluatorTypes::oAnd;
|
||||||
|
case 13: return PIEvaluatorTypes::oOr;
|
||||||
|
default: return PIEvaluatorTypes::oNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluator::parse(const PIString & string, int offset) {
|
||||||
|
int slen = string.length(), facnt, farg, bcnt, k;
|
||||||
|
PIChar cc;
|
||||||
|
PIEvaluatorTypes::Element ce;
|
||||||
|
PIEvaluatorTypes::Function cfunc;
|
||||||
|
PIEvaluatorTypes::Operation coper;
|
||||||
|
PIString sbrackets, carg;
|
||||||
|
PIVector<int> args, atmp;
|
||||||
|
PIVector<PIEvaluatorTypes::Operation> opers;
|
||||||
|
|
||||||
|
///qDebug() << "to parse :" + string;
|
||||||
|
///cout << " "; for (int i = 0; i < slen; i++) cout << preproc->elements[i + offset].type; cout << endl;
|
||||||
|
|
||||||
|
for (int i = 0; i < slen; i++) {
|
||||||
|
ce = elements[i + offset];
|
||||||
|
cc = string[i];
|
||||||
|
switch (ce.type) {
|
||||||
|
case PIEvaluatorTypes::etNumber:
|
||||||
|
args.push_back(ce.var_num);
|
||||||
|
continue;
|
||||||
|
case PIEvaluatorTypes::etVariable:
|
||||||
|
args.push_back(ce.var_num);
|
||||||
|
continue;
|
||||||
|
case PIEvaluatorTypes::etFunction:
|
||||||
|
i++;
|
||||||
|
cfunc = content.function(ce.var_num);
|
||||||
|
facnt = cfunc.arguments;
|
||||||
|
atmp.clear();
|
||||||
|
bcnt = farg = 1;
|
||||||
|
///qDebug() << "function: " + cfunc.identifier;
|
||||||
|
//for (int k = 0; k < facnt; k++) {
|
||||||
|
bcnt = 1;
|
||||||
|
carg = "";
|
||||||
|
k = i + 1;
|
||||||
|
//if (string.size_s() <= k || k < 0) return -666;
|
||||||
|
while (bcnt > 0) {
|
||||||
|
//if (k < facnt - 1) fcomma = string.indexOf(',', j);
|
||||||
|
cc = string[k];
|
||||||
|
switch (cc.toAscii()) {
|
||||||
|
case '(': bcnt++; break;
|
||||||
|
case ')':
|
||||||
|
bcnt--;
|
||||||
|
if (bcnt == 0) {
|
||||||
|
///qDebug() << "arument: " << carg;
|
||||||
|
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||||
|
k++;
|
||||||
|
carg = "";
|
||||||
|
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
if (bcnt == 1) {
|
||||||
|
///qDebug() << "arument: " << carg;
|
||||||
|
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||||
|
k++;
|
||||||
|
carg = "";
|
||||||
|
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
carg += cc;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
i = k - 1;
|
||||||
|
if (farg > 0) {
|
||||||
|
variables.push_back(PIEvaluatorTypes::Variable());
|
||||||
|
farg = -variables.size_s();
|
||||||
|
}
|
||||||
|
instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oFunction, atmp, farg, ce.var_num));
|
||||||
|
args.push_back(farg);
|
||||||
|
//for (int i = 0; i < args.size_s(); i++) cout << preproc->currentVariables[-args[i]].value << endl;
|
||||||
|
//i = j + 1;
|
||||||
|
continue;
|
||||||
|
case PIEvaluatorTypes::etOperator:
|
||||||
|
//qDebug() << "operator: " << cc;
|
||||||
|
if (cc == '(') {
|
||||||
|
sbrackets = inBrackets(string.right(slen - i));
|
||||||
|
args.push_back(parse(sbrackets, i + offset + 1));
|
||||||
|
i += sbrackets.length() + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc == '+') {opers.push_back(PIEvaluatorTypes::oAdd); continue;}
|
||||||
|
if (cc == '-') {opers.push_back(PIEvaluatorTypes::oSubtract); continue;}
|
||||||
|
if (cc == '*') {opers.push_back(PIEvaluatorTypes::oMultiply); continue;}
|
||||||
|
if (cc == '/') {opers.push_back(PIEvaluatorTypes::oDivide); continue;}
|
||||||
|
if (cc == '%') {opers.push_back(PIEvaluatorTypes::oResidue); continue;}
|
||||||
|
if (cc == '^') {opers.push_back(PIEvaluatorTypes::oPower); continue;}
|
||||||
|
if (cc == '=') {opers.push_back(PIEvaluatorTypes::oEqual); continue;}
|
||||||
|
if (cc == ':') {opers.push_back(PIEvaluatorTypes::oNotEqual); continue;}
|
||||||
|
if (cc == '}') {opers.push_back(PIEvaluatorTypes::oGreaterEqual); continue;}
|
||||||
|
if (cc == '{') {opers.push_back(PIEvaluatorTypes::oSmallerEqual); continue;}
|
||||||
|
if (cc == '>') {opers.push_back(PIEvaluatorTypes::oGreater); continue;}
|
||||||
|
if (cc == '<') {opers.push_back(PIEvaluatorTypes::oSmaller); continue;}
|
||||||
|
if (cc == '&') {opers.push_back(PIEvaluatorTypes::oAnd); continue;}
|
||||||
|
if (cc == '|') {opers.push_back(PIEvaluatorTypes::oOr); continue;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
cout << "stack: " << endl << "args: ";
|
||||||
|
for (int i = 0; i < args.size_s(); i++) cout << args[i] << ", ";
|
||||||
|
cout << endl << "opers: ";
|
||||||
|
for (int i = 0; i < opers.size_s(); i++) cout << opers[i] << ", ";
|
||||||
|
*/
|
||||||
|
if (opers.size_s() == 0) {
|
||||||
|
if (args.size_s() > 0) return args.back();
|
||||||
|
else return -666;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < PIEvaluatorTypes::operationCount; i++) {
|
||||||
|
coper = operationInOrder(i);
|
||||||
|
for (int j = 0; j < opers.size_s(); j++) {
|
||||||
|
if (coper == PIEvaluatorTypes::oDivide || coper == PIEvaluatorTypes::oMultiply) {
|
||||||
|
if (opers[j] != PIEvaluatorTypes::oDivide && opers[j] != PIEvaluatorTypes::oMultiply) continue;
|
||||||
|
} else {
|
||||||
|
if (opers[j] != coper) continue;
|
||||||
|
}
|
||||||
|
atmp.clear();
|
||||||
|
if (j < args.size_s() && j >= 0) atmp.push_back(args[j]);
|
||||||
|
else atmp.push_back(-666);
|
||||||
|
if (j + 1 < args.size_s() && j >= -1) atmp.push_back(args[j + 1]);
|
||||||
|
else atmp.push_back(-666);
|
||||||
|
farg = 1;
|
||||||
|
if (atmp[0] < 0) farg = atmp[0];
|
||||||
|
else {
|
||||||
|
if (atmp[1] < 0) farg = atmp[1];
|
||||||
|
else {
|
||||||
|
variables.push_back(PIEvaluatorTypes::Variable());
|
||||||
|
farg = -variables.size_s();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instructions.push_back(PIEvaluatorTypes::Instruction(opers[j], atmp, farg));
|
||||||
|
if (j >= 0 && j < args.size_s()) {
|
||||||
|
args.remove(j);
|
||||||
|
if (j < args.size_s()) args[j] = farg;
|
||||||
|
}
|
||||||
|
opers.remove(j);
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instructions.back().out;
|
||||||
|
///cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluator::check() {
|
||||||
|
PIEvaluatorTypes::Instruction ci;
|
||||||
|
bool error;
|
||||||
|
if (unknownVars.size_s() > 0) {
|
||||||
|
lastError = "Unknown variables: \"" + unknownVars.join("\", \"") + "\"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < instructions.size_s(); i++) {
|
||||||
|
error = false;
|
||||||
|
ci = instructions[i];
|
||||||
|
switch (ci.operation) {
|
||||||
|
case PIEvaluatorTypes::oNone: break;
|
||||||
|
case PIEvaluatorTypes::oFunction:
|
||||||
|
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||||
|
if (ci.operators[j] == -666) { //(ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ci.operators.size_s() != content.function(ci.function).arguments || error) {
|
||||||
|
lastError = "Invalid arguments count for function \"" + content.function(ci.function).identifier + "\"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (ci.operators[0] == -666 || ci.operators[1] == -666) error = true;
|
||||||
|
if (ci.operators.size_s() != 2 || error) {
|
||||||
|
lastError = "Invalid arguments count for operation \" " + operationChar(ci.operation) + " \"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ci.out < -variables.size_s()) {
|
||||||
|
lastError = "Invalid variable index \"" + PIString::fromNumber(ci.out) + "\"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||||
|
if (ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size_s()) {
|
||||||
|
lastError = "Invalid variable index \"" + PIString::fromNumber(ci.operators[j]) + "\"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIEvaluator::inBrackets(const PIString & string) {
|
||||||
|
int slen = string.length(), bcnt = 0;
|
||||||
|
PIChar cc;
|
||||||
|
for (int i = 0; i < slen; i++) {
|
||||||
|
cc = string[i];
|
||||||
|
if (cc == '(') bcnt++;
|
||||||
|
if (cc == ')') {
|
||||||
|
bcnt--;
|
||||||
|
if (bcnt == 0) return string.mid(1, i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PIString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIEvaluator::operationChar(const PIEvaluatorTypes::Operation & operation) {
|
||||||
|
switch (operation) {
|
||||||
|
case PIEvaluatorTypes::oAdd: return "+";
|
||||||
|
case PIEvaluatorTypes::oSubtract: return "-";
|
||||||
|
case PIEvaluatorTypes::oMultiply: return "*";
|
||||||
|
case PIEvaluatorTypes::oDivide: return "/";
|
||||||
|
case PIEvaluatorTypes::oPower: return "^";
|
||||||
|
case PIEvaluatorTypes::oResidue: return "%";
|
||||||
|
case PIEvaluatorTypes::oEqual: return "=";
|
||||||
|
case PIEvaluatorTypes::oNotEqual: return ("≠");
|
||||||
|
case PIEvaluatorTypes::oGreaterEqual: return ("≥");
|
||||||
|
case PIEvaluatorTypes::oSmallerEqual: return ("≤");
|
||||||
|
case PIEvaluatorTypes::oGreater: return ">";
|
||||||
|
case PIEvaluatorTypes::oSmaller: return "<";
|
||||||
|
case PIEvaluatorTypes::oAnd: return ("⋀");
|
||||||
|
case PIEvaluatorTypes::oOr: return ("⋁");
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline complexd PIEvaluator::residue(const complexd & f, const complexd & s) {
|
||||||
|
complexd ret;
|
||||||
|
if (s.real() != 0.) ret = complexd(f.real() - ((int)(f.real() / s.real())) * s.real(), 0.);
|
||||||
|
if (s.imag() != 0.) ret = complexd(ret.real(), f.imag() - ((int)(f.imag() / s.imag())) * s.imag());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci) {
|
||||||
|
PIEvaluatorTypes::Function cfunc = content.function(ci.function);
|
||||||
|
int oi = -ci.out - 1;
|
||||||
|
complexd tmp, stmp;
|
||||||
|
ldouble ldtmp;
|
||||||
|
//qDebug() << "function " << (int)cfunc.type;
|
||||||
|
switch (cfunc.type) {
|
||||||
|
case PIEvaluatorTypes::bfSin:
|
||||||
|
tmpvars[oi].value = sin(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfCos:
|
||||||
|
tmpvars[oi].value = cos(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfTg:
|
||||||
|
tmpvars[oi].value = tan(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfCtg:
|
||||||
|
tmp = tan(value(ci.operators[0]));
|
||||||
|
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||||
|
else tmpvars[oi].value = complexd_1 / tmp;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfArcsin:
|
||||||
|
tmpvars[oi].value = asinc(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfArccos:
|
||||||
|
tmpvars[oi].value = acosc(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfArctg:
|
||||||
|
tmpvars[oi].value = atanc(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfArcctg:
|
||||||
|
tmp = atanc(value(ci.operators[0]));
|
||||||
|
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||||
|
else tmpvars[oi].value = complexd_1 / tmp;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfSh:
|
||||||
|
tmpvars[oi].value = sinh(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfCh:
|
||||||
|
tmpvars[oi].value = cosh(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfTh:
|
||||||
|
tmpvars[oi].value = tanh(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfCth:
|
||||||
|
tmp = tanh(value(ci.operators[0]));
|
||||||
|
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||||
|
else tmpvars[oi].value = complexd_1 / tmp;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfAbs:
|
||||||
|
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfSqrt:
|
||||||
|
tmpvars[oi].value = sqrt(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfSqr:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[0]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfExp:
|
||||||
|
tmpvars[oi].value = exp(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfPow:
|
||||||
|
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfLn:
|
||||||
|
tmpvars[oi].value = log(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfLg:
|
||||||
|
tmpvars[oi].value = log10(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfLog:
|
||||||
|
tmp = log(value(ci.operators[1]));
|
||||||
|
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||||
|
else tmpvars[oi].value = log(value(ci.operators[0])) / tmp;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfRe:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfIm:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).imag();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfArg:
|
||||||
|
tmpvars[oi].value = arg(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfLen:
|
||||||
|
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfConj:
|
||||||
|
tmpvars[oi].value = conj(value(ci.operators[0]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfSign:
|
||||||
|
ldtmp = value(ci.operators[0]).real();
|
||||||
|
tmpvars[oi].value = ldtmp >= 0. ? complexd_1 : -complexd_1;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfRad:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) * complexd(deg2rad, 0.);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfDeg:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::bfRandom:
|
||||||
|
tmp = static_cast<ldouble>(rand()) / RAND_MAX;
|
||||||
|
stmp = value(ci.operators[1]) - value(ci.operators[0]);
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) + tmp * stmp;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool PIEvaluator::execInstructions() {
|
||||||
|
PIEvaluatorTypes::Instruction ci;
|
||||||
|
int oi;
|
||||||
|
complexd tmp;
|
||||||
|
tmpvars = variables;
|
||||||
|
//cout << "var count " << tmpvars.size_s() << endl;
|
||||||
|
for (int i = 0; i < instructions.size_s(); i++) {
|
||||||
|
ci = instructions[i];
|
||||||
|
oi = -ci.out - 1;
|
||||||
|
//cout << value(ci.operators[0]) << operationChar(ci.operation) << value(ci.operators[1]) << ", " << oi << endl;
|
||||||
|
switch (ci.operation) {
|
||||||
|
case PIEvaluatorTypes::oAdd:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) + value(ci.operators[1]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oSubtract:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) - value(ci.operators[1]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oMultiply:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oDivide:
|
||||||
|
tmp = value(ci.operators[1]);
|
||||||
|
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
|
||||||
|
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oResidue:
|
||||||
|
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oPower:
|
||||||
|
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oEqual:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) == value(ci.operators[1]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oNotEqual:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]) != value(ci.operators[1]);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oGreaterEqual:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() >= value(ci.operators[1]).real();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oSmallerEqual:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() <= value(ci.operators[1]).real();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oGreater:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() > value(ci.operators[1]).real();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oSmaller:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() < value(ci.operators[1]).real();
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oAnd:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() > 0. && value(ci.operators[1]).real() > 0.;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oOr:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]).real() > 0. || value(ci.operators[1]).real() > 0.;
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oFunction:
|
||||||
|
execFunction(ci);
|
||||||
|
break;
|
||||||
|
case PIEvaluatorTypes::oNone:
|
||||||
|
tmpvars[oi].value = value(ci.operators[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out = value(instructions.back().out);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIEvaluator::check(const PIString & string) {
|
||||||
|
currentString = preprocess(string);
|
||||||
|
if (!check())
|
||||||
|
return false;
|
||||||
|
lastError = "Correct";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
complexd PIEvaluator::evaluate() {
|
||||||
|
if (!execInstructions()) out = 0.;
|
||||||
|
if (fabs(out.real()) < 1E-300) out = complexd(0., out.imag());
|
||||||
|
if (fabs(out.imag()) < 1E-300) out = complexd(out.real(), 0.);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
148
pievaluator.h
Normal file
148
pievaluator.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#ifndef PIEVALUATOR_H
|
||||||
|
#define PIEVALUATOR_H
|
||||||
|
|
||||||
|
#include "pistring.h"
|
||||||
|
#include "pimath.h"
|
||||||
|
|
||||||
|
namespace PIEvaluatorTypes {
|
||||||
|
static const int operationCount = 14;
|
||||||
|
|
||||||
|
enum eType {etNumber, etOperator, etVariable, etFunction};
|
||||||
|
enum Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower,
|
||||||
|
oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual,
|
||||||
|
oAnd, oOr, oFunction};
|
||||||
|
enum BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg,
|
||||||
|
bfArcsin, bfArccos, bfArctg, bfArcctg,
|
||||||
|
bfExp, bfRandom, bfSh, bfCh, bfTh, bfCth,
|
||||||
|
bfSqrt, bfSqr, bfPow, bfAbs,
|
||||||
|
bfLn, bfLg, bfLog, bfSign,
|
||||||
|
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||||
|
bfRad, bfDeg};
|
||||||
|
|
||||||
|
struct Instruction {
|
||||||
|
Instruction() {;}
|
||||||
|
Instruction(Operation oper, PIVector<int> opers, int out_ind, int func = -1) {
|
||||||
|
operation = oper; operators = opers; out = out_ind; function = func;}
|
||||||
|
Operation operation;
|
||||||
|
PIVector<int> operators;
|
||||||
|
int out;
|
||||||
|
int function;};
|
||||||
|
struct Element {
|
||||||
|
Element() {;}
|
||||||
|
Element(eType new_type, int new_num, int new_var_num = -1) {set(new_type, new_num, new_var_num);}
|
||||||
|
void set(eType new_type, int new_num, int new_var_num = -1) {type = new_type; num = new_num; var_num = new_var_num;}
|
||||||
|
eType type;
|
||||||
|
int num;
|
||||||
|
int var_num;};
|
||||||
|
struct Function {
|
||||||
|
Function() {arguments = 0; type = bfUnknown;}
|
||||||
|
Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype;}
|
||||||
|
PIString identifier;
|
||||||
|
BaseFunctions type;
|
||||||
|
int arguments;};
|
||||||
|
struct Variable {
|
||||||
|
Variable() {value = 0.;}
|
||||||
|
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
||||||
|
PIString name;
|
||||||
|
complexd value;};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
≠ :
|
||||||
|
≥ }
|
||||||
|
≤ {
|
||||||
|
⋀ &
|
||||||
|
⋁ |
|
||||||
|
*/
|
||||||
|
class PIEvaluatorContent
|
||||||
|
{
|
||||||
|
friend class PIEvaluator;
|
||||||
|
public:
|
||||||
|
PIEvaluatorContent();
|
||||||
|
~PIEvaluatorContent() {;}
|
||||||
|
|
||||||
|
inline void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));}
|
||||||
|
inline void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();}
|
||||||
|
inline int functionsCount() const {return functions.size();}
|
||||||
|
inline int variablesCount() const {return variables.size();}
|
||||||
|
inline int customVariablesCount() const {return variables.size() - cv_count;}
|
||||||
|
inline int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;}
|
||||||
|
inline int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;}
|
||||||
|
inline PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];}
|
||||||
|
inline PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];}
|
||||||
|
inline PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||||
|
inline PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||||
|
inline PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];}
|
||||||
|
bool setVariableValue(int index, complexd new_value);
|
||||||
|
bool setVariableName(int index, const PIString & new_name);
|
||||||
|
inline bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||||
|
inline bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||||
|
inline void removeVariable(int index) {variables.remove(index);}
|
||||||
|
inline void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));}
|
||||||
|
void clearCustomVariables();
|
||||||
|
void sortVariables();
|
||||||
|
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PIVector<PIEvaluatorTypes::Function> functions;
|
||||||
|
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||||
|
int cv_count;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class PIEvaluator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PIEvaluator() {;}
|
||||||
|
~PIEvaluator() {;}
|
||||||
|
|
||||||
|
bool check(const PIString & string);
|
||||||
|
inline int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);}
|
||||||
|
inline void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);}
|
||||||
|
inline void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;}
|
||||||
|
complexd evaluate();
|
||||||
|
inline void removeVariable(const PIString & name) {content.removeVariable(name);}
|
||||||
|
inline void clearCustomVariables() {content.clearCustomVariables();}
|
||||||
|
inline int variableIndex(const PIString & name) const {return content.findVariable(name);}
|
||||||
|
inline const PIStringList & unknownVariables() {return unknownVars;}
|
||||||
|
inline const PIString & expression() {return currentString;}
|
||||||
|
inline const PIString & error() {return lastError;}
|
||||||
|
inline const complexd & lastResult() {return out;}
|
||||||
|
|
||||||
|
PIEvaluatorContent content;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const PIString & prepare(const PIString & string);
|
||||||
|
const PIString & preprocess(const PIString & string);
|
||||||
|
int parse(const PIString & string, int offset = 0);
|
||||||
|
void convert();
|
||||||
|
void checkBrackets();
|
||||||
|
void removeSpaces();
|
||||||
|
void findUnknownVariables();
|
||||||
|
void removeJunk();
|
||||||
|
void replaceOperators();
|
||||||
|
void makeOutput(PIString & string);
|
||||||
|
bool fillElements();
|
||||||
|
bool setSignes();
|
||||||
|
bool isSign(const PIChar & ch);
|
||||||
|
inline PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;}
|
||||||
|
bool check();
|
||||||
|
bool execInstructions();
|
||||||
|
PIString inBrackets(const PIString & string);
|
||||||
|
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
||||||
|
PIEvaluatorTypes::Operation operationInOrder(const int & index);
|
||||||
|
inline complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;}
|
||||||
|
inline complexd residue(const complexd & f, const complexd & s);
|
||||||
|
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||||
|
|
||||||
|
PIVector<PIEvaluatorTypes::Element> elements;
|
||||||
|
PIVector<PIEvaluatorTypes::Variable> currentVariables, variables, tmpvars, * kvars;
|
||||||
|
PIVector<PIEvaluatorTypes::Instruction> instructions;
|
||||||
|
PIStringList unknownVars;
|
||||||
|
PIString currentString, lastError;
|
||||||
|
complexd out;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||||
|
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
||||||
|
|
||||||
|
#endif // PIEVALUATOR_H
|
||||||
38
pifile.cpp
38
pifile.cpp
@@ -1,7 +1,7 @@
|
|||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
|
|
||||||
|
|
||||||
bool PIFile::open(const PIString & path_, Flags<Mode> mode_) {
|
bool PIFile::open(const PIString & path_, PIFlags<Mode> mode_) {
|
||||||
cpath = path_;
|
cpath = path_;
|
||||||
cmode = mode_;
|
cmode = mode_;
|
||||||
string st = cpath.stdString();
|
string st = cpath.stdString();
|
||||||
@@ -18,7 +18,26 @@ bool PIFile::open(const PIString & path_, Flags<Mode> mode_) {
|
|||||||
PIString PIFile::readLine() {
|
PIString PIFile::readLine() {
|
||||||
char * buff = new char[4096];
|
char * buff = new char[4096];
|
||||||
stream.getline(buff, 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();
|
int s, cp = stream.tellg();
|
||||||
stream.seekg(0, fstream::end);
|
stream.seekg(0, fstream::end);
|
||||||
s = stream.tellg();
|
s = stream.tellg();
|
||||||
stream.seekg(cp);
|
stream.seekg(cp, fstream::beg);
|
||||||
return s;
|
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_) {
|
void PIFile::resize(int new_size, char fill_) {
|
||||||
int ds = new_size - size();
|
int ds = new_size - size();
|
||||||
if (ds == 0) return;
|
if (ds == 0) return;
|
||||||
@@ -56,3 +69,10 @@ int PIFile::pos() {
|
|||||||
if (cmode[Write]) return stream.tellp();
|
if (cmode[Write]) return stream.tellp();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIFile PIFile::openTemporary(PIFlags<PIFile::Mode> mode) {
|
||||||
|
char * rc;
|
||||||
|
rc = tmpnam(0);
|
||||||
|
return PIFile(PIString(rc), mode);
|
||||||
|
}
|
||||||
|
|||||||
42
pifile.h
42
pifile.h
@@ -1,7 +1,6 @@
|
|||||||
#ifndef PIFILE_H
|
#ifndef PIFILE_H
|
||||||
#define PIFILE_H
|
#define PIFILE_H
|
||||||
|
|
||||||
#include "piincludes.h"
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
@@ -14,29 +13,42 @@ public:
|
|||||||
|
|
||||||
enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app};
|
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(const PIFile & file) {cpath = file.cpath; cmode = file.cmode;}
|
||||||
~PIFile() {if (isOpened()) close();}
|
~PIFile() {if (isOpened()) close();}
|
||||||
|
|
||||||
bool open(const PIString & path, Flags<Mode> mode = Read | Write);
|
PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;}
|
||||||
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);}
|
bool open(const PIString & path, PIFlags<Mode> mode);
|
||||||
void seek(int position);
|
bool open(PIFlags<Mode> mode) {return open(cpath, mode);}
|
||||||
inline void seekToEnd() {stream.seekg(0, fstream::end);}
|
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);
|
void resize(int new_size, char fill = 0);
|
||||||
inline void fill(char c) {stream.fill(c);}
|
void fill(char c) {stream.fill(c);}
|
||||||
inline void flush() {stream.flush();}
|
void flush() {stream.flush();}
|
||||||
PIString readLine();
|
PIString readLine();
|
||||||
|
int readAll(void * data);
|
||||||
|
PIByteArray readAll();
|
||||||
|
void remove() {if (isOpened()) close(); std::remove(cpath.data());}
|
||||||
|
|
||||||
PIString path() const {return cpath;}
|
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 size();
|
||||||
int pos();
|
int pos();
|
||||||
bool isOpened() const {return stream.is_open();}
|
bool isOpened() {return stream.is_open();}
|
||||||
bool isEnd() const {return stream.eof();}
|
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 & 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 & 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 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 short v) {stream.write((char * )&v, sizeof(v)); return *this;}
|
||||||
@@ -51,7 +63,7 @@ public:
|
|||||||
|
|
||||||
PIFile & operator <<(const char & v) {stream.write(&v, 1); 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 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 PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;}
|
||||||
PIFile & operator <<(const short & v) {stream << v; return *this;}
|
PIFile & operator <<(const short & v) {stream << v; return *this;}
|
||||||
PIFile & operator <<(const int & v) {stream << v; return *this;}
|
PIFile & operator <<(const int & v) {stream << v; return *this;}
|
||||||
@@ -74,10 +86,12 @@ public:
|
|||||||
PIFile & operator >>(float & v) {stream >> v; return *this;}
|
PIFile & operator >>(float & v) {stream >> v; return *this;}
|
||||||
PIFile & operator >>(double & 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:
|
private:
|
||||||
fstream stream;
|
fstream stream;
|
||||||
PIString cpath;
|
PIString cpath;
|
||||||
Flags<Mode> cmode;
|
PIFlags<Mode> cmode;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public:
|
|||||||
inline PIPoint<Type> & move(const PIPoint<Type> & p) {x += p.x; y += p.y; return *this;}
|
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 double angleRad() const {return atan2(y, x);}
|
||||||
inline int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);}
|
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 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);}
|
inline PIPoint<Type> operator +(const Type & p) {return PIPoint<Type>(x + p, y + p);}
|
||||||
|
|||||||
100
piincludes.h
100
piincludes.h
@@ -7,24 +7,39 @@
|
|||||||
#if __QNX__
|
#if __QNX__
|
||||||
# define QNX
|
# define QNX
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WINDOWS
|
||||||
|
# ifndef QNX
|
||||||
|
# define LINUX
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#ifndef QNX
|
#ifndef QNX
|
||||||
# include <cstdio>
|
# include <cstdio>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
|
# include <clocale>
|
||||||
#else
|
#else
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <cctype>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <algorithm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <queue>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <stack>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# include <conio.h>
|
# include <conio.h>
|
||||||
@@ -33,7 +48,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FOREVER for (;;)
|
#define FOREVER for (;;)
|
||||||
#define FOREVER_WAIT FOREVER msleep(10);
|
#define FOREVER_WAIT FOREVER msleep(1);
|
||||||
|
|
||||||
typedef long long llong;
|
typedef long long llong;
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
@@ -49,60 +64,46 @@ using std::endl;
|
|||||||
using std::flush;
|
using std::flush;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::list;
|
using std::list;
|
||||||
|
using std::queue;
|
||||||
using std::deque;
|
using std::deque;
|
||||||
|
using std::stack;
|
||||||
|
using std::set;
|
||||||
using std::string;
|
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> >
|
static bool isPIInit = false;
|
||||||
class PIVector: public vector<Type, Allocator> {
|
|
||||||
|
class piInit {
|
||||||
public:
|
public:
|
||||||
inline const Type & at(uint index) const {return (*this)[index];}
|
piInit() {
|
||||||
inline Type & at(uint index) {return (*this)[index];}
|
if (isPIInit) return;
|
||||||
inline const Type * data(uint index = 0) const {return &(*this)[index];}
|
isPIInit = true;
|
||||||
inline Type * data(uint index = 0) {return &(*this)[index];}
|
#ifdef LINUX
|
||||||
inline void fill(const Type & t) {vector<Type, Allocator>::assign(vector<Type, Allocator>::size(), t);}
|
if (currentLocale_t != 0) {
|
||||||
inline void pop_front() {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin());}
|
freelocale(currentLocale_t);
|
||||||
inline void push_front(const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin(), t);}
|
currentLocale_t = 0;
|
||||||
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);}
|
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
||||||
inline void insert(uint pos, const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin() + pos, t);}
|
#else
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
~piInit() {
|
||||||
|
//if (currentLocale_t != 0) freelocale(currentLocale_t);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type, typename Allocator = std::allocator<Type> >
|
static piInit __pi_init;
|
||||||
class PIList: public list<Type, Allocator> {
|
static lconv * currentLocale = std::localeconv();
|
||||||
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);}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Enum>
|
inline const char * errorString() {return strerror(errno);}
|
||||||
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;}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
inline int random() {return rand();}
|
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 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 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);}
|
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 bool atob(const string & str) { return str == "1" ? true : false;};
|
||||||
inline string btos(const bool num) { return num ? "0" : "1";};
|
inline string btos(const bool num) { return num ? "0" : "1";};
|
||||||
inline string itos(const int num) {
|
inline string itos(const int num) {
|
||||||
|
|||||||
@@ -1,9 +1,27 @@
|
|||||||
#include "pikbdlistener.h"
|
#include "pikbdlistener.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool PIKbdListener::exiting;
|
||||||
|
|
||||||
PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
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;
|
ret_func = slot;
|
||||||
data = data_;
|
data = data_;
|
||||||
|
PIKbdListener::exiting = exit_enabled = false;
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIKbdListener::begin() {
|
||||||
|
//cout << "list begin" << endl;
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
GetConsoleMode(hIn, &smode);
|
GetConsoleMode(hIn, &smode);
|
||||||
@@ -11,19 +29,8 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() {
|
|||||||
#else
|
#else
|
||||||
struct termios term;
|
struct termios term;
|
||||||
tcgetattr(0, &term);
|
tcgetattr(0, &term);
|
||||||
sterm = term;
|
|
||||||
term.c_lflag &= ~(ECHO | ICANON) | NOFLSH;
|
term.c_lflag &= ~(ECHO | ICANON) | NOFLSH;
|
||||||
tcsetattr(0, TCSAFLUSH, &term);
|
tcsetattr(0, TCSAFLUSH, &term);
|
||||||
#endif
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIKbdListener::~PIKbdListener() {
|
|
||||||
#ifdef __WIN32__
|
|
||||||
SetConsoleMode(hIn, smode);
|
|
||||||
#else
|
|
||||||
tcsetattr(0, TCSANOW, &sterm);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +41,16 @@ void PIKbdListener::run() {
|
|||||||
#else
|
#else
|
||||||
ret = read(0, &rc, 1);
|
ret = read(0, &rc, 1);
|
||||||
#endif
|
#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
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,19 +6,34 @@
|
|||||||
# include <termios.h>
|
# include <termios.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) msleep(1);
|
||||||
|
|
||||||
typedef void (*KBFunc)(char, void * );
|
typedef void (*KBFunc)(char, void * );
|
||||||
|
|
||||||
class PIKbdListener: public PIThread {
|
class PIKbdListener: public PIThread {
|
||||||
|
friend class PIConsole;
|
||||||
public:
|
public:
|
||||||
// slot is any function format "void <func>(char, void * )"
|
// slot is any function format "void <func>(char, void * )"
|
||||||
PIKbdListener(KBFunc slot = 0, void * data = 0);
|
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:
|
private:
|
||||||
|
void begin();
|
||||||
void run();
|
void run();
|
||||||
|
void end();
|
||||||
|
|
||||||
KBFunc ret_func;
|
KBFunc ret_func;
|
||||||
char rc;
|
char rc, exit_key, is_active;
|
||||||
|
bool exit_enabled;
|
||||||
void * data;
|
void * data;
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
|
|||||||
20
pimath.cpp
20
pimath.cpp
@@ -155,7 +155,7 @@ void fft(complexd * x, int T, bool complement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char Solver::methods_desc[] = "Methods:\
|
const char Solver::methods_desc[] = "b{Methods:}\
|
||||||
\n -1 - Global settings\
|
\n -1 - Global settings\
|
||||||
\n 01 - Eyler 1\
|
\n 01 - Eyler 1\
|
||||||
\n 02 - Eyler 2\
|
\n 02 - Eyler 2\
|
||||||
@@ -167,15 +167,15 @@ const char Solver::methods_desc[] = "Methods:\
|
|||||||
\n 34 - Polynomial Approximation 4\
|
\n 34 - Polynomial Approximation 4\
|
||||||
\n 35 - Polynomial Approximation 5";
|
\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) {
|
void Solver::solve(double u, double h) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case Global:
|
case Global:
|
||||||
switch (method_global) {
|
switch (method_global) {
|
||||||
case Eyler1: solveEyler1(u, h); break;
|
case Eyler_1: solveEyler1(u, h); break;
|
||||||
case Eyler2: solveEyler2(u, h); break;
|
case Eyler_2: solveEyler2(u, h); break;
|
||||||
case RungeKutta_4: solveRK4(u, h); break;
|
case RungeKutta_4: solveRK4(u, h); break;
|
||||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||||
case AdamsBashfortMoulton_3: solveABM3(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;
|
case PolynomialApproximation_5: solvePA5(u, h); break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Eyler1: solveEyler1(u, h); break;
|
case Eyler_1: solveEyler1(u, h); break;
|
||||||
case Eyler2: solveEyler2(u, h); break;
|
case Eyler_2: solveEyler2(u, h); break;
|
||||||
case RungeKutta_4: solveRK4(u, h); break;
|
case RungeKutta_4: solveRK4(u, h); break;
|
||||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||||
case AdamsBashfortMoulton_3: solveABM3(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) {
|
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;
|
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;
|
k2 = A * (XX + k1 * h / 2.) + d * (u + td/3.); xx = k2 * h / 2.; XX += xx;
|
||||||
k3 = A * (XX + k2 * h / 2.) + d * (u + xx[0]); xx = k3 * h; 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 + xx[0]);
|
k4 = A * (XX + k3 * h) + d * (u + td);
|
||||||
//cout << k1 << k2 << k3 << k4 << endl;
|
//cout << k1 << k2 << k3 << k4 << endl;
|
||||||
X += (k1 + k2 * 2. + k3 * 2. + k4) * h / 6.;
|
X += (k1 + k2 * 2. + k3 * 2. + k4) * h / 6.;
|
||||||
|
F[0] = X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
55
pimath.h
55
pimath.h
@@ -1,27 +1,52 @@
|
|||||||
#ifndef PIMATH_H
|
#ifndef PIMATH_H
|
||||||
#define PIMATH_H
|
#define PIMATH_H
|
||||||
|
|
||||||
#include <complex>
|
#include "picontainers.h"
|
||||||
#include <stdarg.h>
|
|
||||||
#include "piincludes.h"
|
|
||||||
#ifndef QNX
|
#ifndef QNX
|
||||||
# include <cmath>
|
# include <cmath>
|
||||||
|
# include <complex>
|
||||||
#else
|
#else
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
|
# include <complex.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define M_2PI 6.28318530717958647692
|
||||||
|
#define M_PI_3 1.04719755119659774615
|
||||||
|
|
||||||
using std::complex;
|
using std::complex;
|
||||||
|
|
||||||
typedef complex<int> complexi;
|
typedef complex<int> complexi;
|
||||||
typedef complex<float> complexf;
|
typedef complex<float> complexf;
|
||||||
typedef complex<double> complexd;
|
typedef complex<double> complexd;
|
||||||
typedef complex<long double> complexld;
|
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 deg2rad = atan(1.) / 45.;
|
||||||
const double rad2deg = 45. / atan(1.);
|
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 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>
|
template<uint Cols, uint Rows, typename Type>
|
||||||
class PIMathMatrixT;
|
class PIMathMatrixT;
|
||||||
@@ -35,13 +60,15 @@ class PIMathVectorT {
|
|||||||
typedef PIMathVectorT<Size, Type> _CVector;
|
typedef PIMathVectorT<Size, Type> _CVector;
|
||||||
public:
|
public:
|
||||||
PIMathVectorT() {resize(Size);}
|
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(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 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 uint size() const {return Size;}
|
||||||
inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;}
|
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(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 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(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;}
|
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 _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 Type & v) {PIMV_FOR(i, 0) c[i] /= v;}
|
||||||
inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];}
|
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 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) const {_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 _CVector & v) const {_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) const {_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 Type & v) const {_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 & 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 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);}
|
inline operator PIMathMatrixT<1, Size, Type>() {return PIMathMatrixT<1, Size, Type>(c);}
|
||||||
@@ -96,6 +123,8 @@ private:
|
|||||||
|
|
||||||
template<uint Size, typename Type>
|
template<uint Size, typename Type>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
|
||||||
|
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}
|
//template<uint Size0, typename Type0 = double, uint Size1 = Size0, typename Type1 = Type0> /// vector {Size0, Type0} to vector {Size1, Type1}
|
||||||
//inline operator PIMathVectorT<Size1, Type1>(const PIMathVectorT<Size0, Type0> & v) {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;}
|
//inline operator PIMathVectorT<Size1, Type1>(const PIMathVectorT<Size0, Type0> & v) {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;}
|
||||||
@@ -637,8 +666,8 @@ class Solver
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Method {Global = -1,
|
enum Method {Global = -1,
|
||||||
Eyler1 = 01,
|
Eyler_1 = 01,
|
||||||
Eyler2 = 02,
|
Eyler_2 = 02,
|
||||||
EylerKoshi = 03,
|
EylerKoshi = 03,
|
||||||
RungeKutta_4 = 14,
|
RungeKutta_4 = 14,
|
||||||
AdamsBashfortMoulton_2 = 22,
|
AdamsBashfortMoulton_2 = 22,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public:
|
|||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED);
|
pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED);
|
||||||
|
//pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||||
pthread_mutex_init(&mutex, &attr);
|
pthread_mutex_init(&mutex, &attr);
|
||||||
pthread_mutexattr_destroy(&attr);
|
pthread_mutexattr_destroy(&attr);
|
||||||
}
|
}
|
||||||
|
|||||||
5
pip.h
5
pip.h
@@ -1,6 +1,7 @@
|
|||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "pivariable.h"
|
#include "pivariable.h"
|
||||||
#include "piconsole.h"
|
#include "piconsole.h"
|
||||||
#include "pimath.h"
|
#include "picli.h"
|
||||||
#include "pidir.h"
|
#include "pievaluator.h"
|
||||||
#include "piprotocol.h"
|
#include "piprotocol.h"
|
||||||
|
#include "picodec.h"
|
||||||
|
|||||||
47
pip.pro
Normal file
47
pip.pro
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
######################################################################
|
||||||
|
# Automatically generated by qmake (2.01a) ?? ???. 18 21:49:21 2011
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
TARGET =
|
||||||
|
DEPENDPATH += .
|
||||||
|
INCLUDEPATH += .
|
||||||
|
|
||||||
|
# Input
|
||||||
|
HEADERS += pibitarray.h \
|
||||||
|
pibytearray.h \
|
||||||
|
pichar.h \
|
||||||
|
piconfig.h \
|
||||||
|
piconsole.h \
|
||||||
|
pidir.h \
|
||||||
|
piethernet.h \
|
||||||
|
pievaluator.h \
|
||||||
|
pifile.h \
|
||||||
|
pigeometry.h \
|
||||||
|
piincludes.h \
|
||||||
|
pikbdlistener.h \
|
||||||
|
pimath.h \
|
||||||
|
pimutex.h \
|
||||||
|
pip.h \
|
||||||
|
piprotocol.h \
|
||||||
|
piserial.h \
|
||||||
|
pistring.h \
|
||||||
|
pithread.h \
|
||||||
|
pitimer.h \
|
||||||
|
pivariable.h
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
pibytearray.cpp \
|
||||||
|
piconfig.cpp \
|
||||||
|
piconsole.cpp \
|
||||||
|
pidir.cpp \
|
||||||
|
piethernet.cpp \
|
||||||
|
pievaluator.cpp \
|
||||||
|
pifile.cpp \
|
||||||
|
pikbdlistener.cpp \
|
||||||
|
pimath.cpp \
|
||||||
|
piprotocol.cpp \
|
||||||
|
piserial.cpp \
|
||||||
|
pistring.cpp \
|
||||||
|
pithread.cpp \
|
||||||
|
pitimer.cpp \
|
||||||
|
pivariable.cpp
|
||||||
124
piprocess.cpp
Normal file
124
piprocess.cpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#include "piprocess.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIProcess::PIProcess(): PIThread() {
|
||||||
|
exit_code = -1;
|
||||||
|
pid = 0;
|
||||||
|
is_exec = false;
|
||||||
|
g_in = g_out = g_err = false;
|
||||||
|
t_in = t_out = t_err = false;
|
||||||
|
env = PIProcess::currentEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIProcess::~PIProcess() {
|
||||||
|
if (t_in) f_in.remove();
|
||||||
|
if (t_out) f_out.remove();
|
||||||
|
if (t_err) f_err.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProcess::exec_() {
|
||||||
|
is_exec = false;
|
||||||
|
startOnce();
|
||||||
|
//cout << "exec wait" << endl;
|
||||||
|
while (!is_exec)
|
||||||
|
msleep(1);
|
||||||
|
//cout << "exec end" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProcess::run() {
|
||||||
|
//cout << "run" << endl;
|
||||||
|
string str;
|
||||||
|
/// arguments convertion
|
||||||
|
char * a[args.size_s() + 1];
|
||||||
|
for (int i = 0; i < args.size_s(); ++i) {
|
||||||
|
str = args[i].stdString();
|
||||||
|
a[i] = new char[str.size() + 1];
|
||||||
|
memcpy(a[i], str.c_str(), str.size());
|
||||||
|
a[i][str.size()] = 0;
|
||||||
|
//cout << a[i] << endl;
|
||||||
|
}
|
||||||
|
a[args.size_s()] = 0;
|
||||||
|
/// environment convertion
|
||||||
|
char * e[env.size_s() + 1];
|
||||||
|
for (int i = 0; i < env.size_s(); ++i) {
|
||||||
|
str = env[i].stdString();
|
||||||
|
e[i] = new char[str.size() + 1];
|
||||||
|
memcpy(e[i], str.c_str(), str.size());
|
||||||
|
e[i][str.size()] = 0;
|
||||||
|
//cout << e[i] << endl;
|
||||||
|
}
|
||||||
|
e[env.size_s()] = 0;
|
||||||
|
/// files for stdin/out/err
|
||||||
|
t_in = t_out = t_err = false;
|
||||||
|
if (f_in.path().isEmpty()) {
|
||||||
|
f_in = PIFile::openTemporary(PIFile::New | PIFile::Read);
|
||||||
|
t_in = true;
|
||||||
|
}
|
||||||
|
f_in.open(PIFile::New | PIFile::Read); f_in.close();
|
||||||
|
if (f_out.path().isEmpty()) {
|
||||||
|
f_out = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||||
|
t_out = true;
|
||||||
|
}
|
||||||
|
f_out.open(PIFile::New | PIFile::Write); f_out.close();
|
||||||
|
if (f_err.path().isEmpty()) {
|
||||||
|
f_err = PIFile::openTemporary(PIFile::New | PIFile::Write);
|
||||||
|
t_err = true;
|
||||||
|
}
|
||||||
|
f_err.open(PIFile::New | PIFile::Write); f_err.close();
|
||||||
|
|
||||||
|
str = args.front().stdString();
|
||||||
|
is_exec = true;
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
FILE * tf;
|
||||||
|
//cout << "exec" << endl;
|
||||||
|
//cout << f_out.path() << endl;
|
||||||
|
if (g_in) tf = freopen(f_in.path().data(), "r", stdin);
|
||||||
|
if (g_out) tf = freopen(f_out.path().data(), "w", stdout);
|
||||||
|
if (g_err) tf = freopen(f_err.path().data(), "w", stderr);
|
||||||
|
if (!wd.isEmpty()) system(("cd " + wd).data());
|
||||||
|
if (execvpe(str.c_str(), a, e) < 0)
|
||||||
|
cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl;
|
||||||
|
} else {
|
||||||
|
msleep(1);
|
||||||
|
//cout << "wait" << endl;
|
||||||
|
wait(&exit_code);
|
||||||
|
pid = 0;
|
||||||
|
//cout << "wait done" << endl;
|
||||||
|
}
|
||||||
|
is_exec = false;
|
||||||
|
for (int i = 0; i < env.size_s(); ++i)
|
||||||
|
delete e[i];
|
||||||
|
for (int i = 0; i < args.size_s(); ++i)
|
||||||
|
delete a[i];
|
||||||
|
//cout << "end" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProcess::removeEnvironmentVariable(const PIString & variable) {
|
||||||
|
PIString s;
|
||||||
|
for (int i = 0; i < env.size_s(); ++i) {
|
||||||
|
s = env[i];
|
||||||
|
if (s.left(s.find("=")).trimmed() == variable) {
|
||||||
|
env.remove(i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProcess::setEnvironmentVariable(const PIString & variable, const PIString & value) {
|
||||||
|
PIString s, v;
|
||||||
|
for (int i = 0; i < env.size_s(); ++i) {
|
||||||
|
s = env[i];
|
||||||
|
v = s.left(s.find("=")).trimmed();
|
||||||
|
if (v == variable) {
|
||||||
|
env[i] = v + "=" + value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env << variable + "=" + value;
|
||||||
|
}
|
||||||
62
piprocess.h
Normal file
62
piprocess.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef PIPROCESS_H
|
||||||
|
#define PIPROCESS_H
|
||||||
|
|
||||||
|
#include "pithread.h"
|
||||||
|
#include "pifile.h"
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
/// TODO workind dir
|
||||||
|
|
||||||
|
class PIProcess: private PIThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PIProcess();
|
||||||
|
~PIProcess();
|
||||||
|
|
||||||
|
int exitCode() const {return exit_code;}
|
||||||
|
int pID() const {return pid;}
|
||||||
|
|
||||||
|
void setGrabInput(bool yes) {g_in = yes;}
|
||||||
|
void setGrabOutput(bool yes) {g_out = yes;}
|
||||||
|
void setGrabError(bool yes) {g_err = yes;}
|
||||||
|
void setInputFile(const PIString & path) {f_in.setPath(path);}
|
||||||
|
void setOutputFile(const PIString & path) {f_out.setPath(path);}
|
||||||
|
void setErrorFile(const PIString & path) {f_err.setPath(path);}
|
||||||
|
void unsetInputFile() {f_in.setPath("");}
|
||||||
|
void unsetOutputFile() {f_out.setPath("");}
|
||||||
|
void unsetErrorFile() {f_err.setPath("");}
|
||||||
|
void setWorkingDirectory(const PIString & path) {wd = path;}
|
||||||
|
void resetWorkingDirectory() {wd.clear();}
|
||||||
|
void exec(const PIString & program) {args.clear(); args << program; exec_();}
|
||||||
|
void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();}
|
||||||
|
void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();}
|
||||||
|
void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();}
|
||||||
|
void exec(const PIString & program, const PIStringList & args_) {args = args_; exec_();}
|
||||||
|
void terminate() {if (is_exec) ::kill(pid, SIGKILL); pid = 0;}
|
||||||
|
bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);}
|
||||||
|
PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();}
|
||||||
|
PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();}
|
||||||
|
|
||||||
|
PIStringList environment() {return env;}
|
||||||
|
void clearEnvironment() {env.clear();}
|
||||||
|
void removeEnvironmentVariable(const PIString & variable);
|
||||||
|
void setEnvironmentVariable(const PIString & variable, const PIString & value);
|
||||||
|
|
||||||
|
static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void run();
|
||||||
|
void exec_();
|
||||||
|
|
||||||
|
PIStringList args, env;
|
||||||
|
PIString wd;
|
||||||
|
PIByteArray out;
|
||||||
|
PIFile f_in, f_out, f_err;
|
||||||
|
bool g_in, g_out, g_err, t_in, t_out, t_err;
|
||||||
|
pid_t pid;
|
||||||
|
int exit_code, sz;
|
||||||
|
bool is_exec;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PIPROCESS_H
|
||||||
291
piprotocol.cpp
291
piprotocol.cpp
@@ -1,96 +1,217 @@
|
|||||||
#include "piprotocol.h"
|
#include "piprotocol.h"
|
||||||
|
|
||||||
|
|
||||||
PIProtocol::PIProtocol(PIString devName, int speed, void * headerPtr, int headerSize, void * dataPtr, int dataSize) {
|
PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_) {
|
||||||
init();
|
init();
|
||||||
type = PIProtocol::Serial;
|
PIConfig conf(config, PIFile::Read);
|
||||||
serial = new PISerial(devName, this, received);
|
if (!conf.isOpened()) {
|
||||||
serial->setReadData(headerPtr, headerSize, dataSize);
|
cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||||
this->devName = devName;
|
devReceiverState = devSenderState = "Config error";
|
||||||
this->headerPtr = (unsigned char * )headerPtr;
|
return;
|
||||||
this->headerSize = headerSize;
|
}
|
||||||
this->dataPtr = (unsigned char * )dataPtr;
|
int ps;
|
||||||
this->dataSize = dataSize;
|
bool ok;
|
||||||
packet = new char[headerSize + dataSize];
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
PIProtocol::PIProtocol(PIString ip, int port, void * dataPtr, int dataSize) {
|
float fr = rb.getValue("frequency", 0.f, &ok);
|
||||||
init();
|
if (ok) setExpectedFrequency(fr);
|
||||||
type = PIProtocol::Ethernet;
|
fr = sb.getValue("frequency", 0.f, &ok);
|
||||||
ether = new PIEthernet(ip, port, this, received);
|
if (ok) setSenderFrequency(fr);
|
||||||
this->devName = ip + ":" + itos(port);
|
headerPtr = (uchar * )recHeaderPtr;
|
||||||
this->dataPtr = (unsigned char * )dataPtr;
|
headerSize = recHeaderSize;
|
||||||
this->dataSize = dataSize;
|
dataPtr = (uchar * )recDataPtr;
|
||||||
packet = new char[dataSize];
|
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() {
|
PIProtocol::~PIProtocol() {
|
||||||
delete sendtimer;
|
delete diagTimer;
|
||||||
if (timer != 0) delete timer;
|
delete sendTimer;
|
||||||
if (type == PIProtocol::Serial) delete serial;
|
if (packet != 0) delete packet;
|
||||||
if (type == PIProtocol::Ethernet) delete ether;
|
if (eth != 0) delete eth;
|
||||||
|
if (ser != 0) delete ser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::init() {
|
void PIProtocol::init() {
|
||||||
work = false;
|
work = false;
|
||||||
|
ret_func = 0;
|
||||||
net_diag = PIProtocol::Unknown;
|
net_diag = PIProtocol::Unknown;
|
||||||
cur_pckt = 0;
|
cur_pckt = 0;
|
||||||
timer = 0;
|
diagTimer = 0;
|
||||||
sendtimer = new PITimer(run, this);
|
packet = 0;
|
||||||
|
sendTimer = new PITimer(sendEvent, this);
|
||||||
|
diagTimer = new PITimer(diagEvent, this);
|
||||||
wrong_count = receive_count = send_count = 0;
|
wrong_count = receive_count = send_count = 0;
|
||||||
immediateFreq = integralFreq = 0.f;
|
send_freq = -1.f;
|
||||||
|
immediateFreq = integralFreq = exp_freq = 0.f;
|
||||||
headerPtr = dataPtr = sendDataPtr = 0;
|
headerPtr = dataPtr = sendDataPtr = 0;
|
||||||
headerSize = dataSize = sendDataSize = 0;
|
headerSize = dataSize = sendDataSize = 0;
|
||||||
exp_freq = 20.f;
|
eth = 0;
|
||||||
devState = "Unknown";
|
ser = 0;
|
||||||
|
type_rec = type_send = PIProtocol::None;
|
||||||
|
devSenderState = devReceiverState = "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::setDevice(const PIString & dev_ip, int speed_port) {
|
void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed) {
|
||||||
if (type == PIProtocol::Serial) {
|
if (type_rec == PIProtocol::Serial) {
|
||||||
serial->setDevice(dev_ip);
|
ser->setDevice(device);
|
||||||
serial->setSpeed(speed_port);
|
ser->setSpeed(speed);
|
||||||
devName = dev_ip;
|
devReceiverName = device;
|
||||||
}
|
|
||||||
if (type == PIProtocol::Ethernet) {
|
|
||||||
ether->setReadAddress(dev_ip, speed_port);
|
|
||||||
devName = dev_ip + ":" + itos(speed_port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::setExpectedFrequency(float frequency)
|
void PIProtocol::setReceiverDevice(const PIString & ip, int port) {
|
||||||
{
|
if (type_rec == PIProtocol::Ethernet) {
|
||||||
|
eth->setReadAddress(ip, port);
|
||||||
|
devReceiverName = ip + ":" + PIString::fromNumber(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed) {
|
||||||
|
if (type_send == PIProtocol::Serial) {
|
||||||
|
ser->setDevice(device);
|
||||||
|
ser->setSpeed(speed);
|
||||||
|
devSenderName = device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProtocol::setSenderDevice(const PIString & ip, int port) {
|
||||||
|
if (type_send == PIProtocol::Ethernet) {
|
||||||
|
eth->setReadAddress(ip, port);
|
||||||
|
devSenderName = ip + ":" + PIString::fromNumber(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIProtocol::setExpectedFrequency(float frequency) {
|
||||||
exp_freq = frequency;
|
exp_freq = frequency;
|
||||||
if (exp_freq < 3.33) pckt_cnt_max = 10;
|
if (exp_freq < 10.f / 3.f) pckt_cnt_max = 10;
|
||||||
else pckt_cnt_max = 3 * (int)exp_freq;
|
else pckt_cnt_max = round(3.f * exp_freq);
|
||||||
last_packets.resize(pckt_cnt_max);
|
last_packets.resize(pckt_cnt_max);
|
||||||
timer = new PITimer(diag_event, this);
|
|
||||||
timer->start(1000. / exp_freq);
|
|
||||||
timer->reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::startReceive()
|
void PIProtocol::startReceive(float exp_frequency) {
|
||||||
{
|
if (exp_frequency > 0.f) exp_freq = exp_frequency;
|
||||||
if (type == PIProtocol::Serial) serial->start();
|
if (type_rec == PIProtocol::Serial) ser->start();
|
||||||
if (type == PIProtocol::Ethernet) ether->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::stopReceive()
|
void PIProtocol::startSend(float frequency) {
|
||||||
{
|
if (frequency > 0.f) send_freq = frequency;
|
||||||
if (type == PIProtocol::Serial) serial->stop();
|
if (send_freq <= 0.f) return;
|
||||||
if (type == PIProtocol::Ethernet) ether->stop();
|
sendTimer->start(1000. / send_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIProtocol::received(void * t, char * data) {
|
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;
|
PIProtocol * p = (PIProtocol * )t;
|
||||||
memcpy(p->dataPtr, data, p->dataSize);
|
if (!p->receive(data, size)) return false;
|
||||||
p->work = true;
|
p->work = true;
|
||||||
//p->lock();
|
//p->lock();
|
||||||
if (p->validate())
|
if (p->validate())
|
||||||
@@ -98,6 +219,7 @@ bool PIProtocol::received(void * t, char * data) {
|
|||||||
//p->unlock();
|
//p->unlock();
|
||||||
p->receive_count++;
|
p->receive_count++;
|
||||||
p->cur_pckt = 1;
|
p->cur_pckt = 1;
|
||||||
|
if (p->ret_func != 0) p->ret_func(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//p->unlock();
|
//p->unlock();
|
||||||
@@ -106,7 +228,7 @@ bool PIProtocol::received(void * t, char * data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::diag_event(void * t) {
|
void PIProtocol::diagEvent(void * t) {
|
||||||
PIProtocol * p = (PIProtocol * )t;
|
PIProtocol * p = (PIProtocol * )t;
|
||||||
p->calc_freq();
|
p->calc_freq();
|
||||||
p->calc_diag();
|
p->calc_diag();
|
||||||
@@ -131,19 +253,19 @@ void PIProtocol::calc_diag() {
|
|||||||
packets[(int)cur_pckt]++;
|
packets[(int)cur_pckt]++;
|
||||||
cur_pckt = 0;
|
cur_pckt = 0;
|
||||||
float good_percents;
|
float good_percents;
|
||||||
good_percents = (float)packets[1] / pckt_cnt * 100.0f;
|
good_percents = (float)packets[1] / pckt_cnt * 100.f;
|
||||||
if (good_percents == 0.0) diag = PIProtocol::Failure;
|
if (good_percents == 0.f) diag = PIProtocol::Failure;
|
||||||
else if (good_percents <= 20.0) diag = PIProtocol::Bad;
|
else if (good_percents <= 20.f) diag = PIProtocol::Bad;
|
||||||
else if (good_percents > 20.0 && good_percents <= 80.0) diag = PIProtocol::Average;
|
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
||||||
else diag = PIProtocol::Good;
|
else diag = PIProtocol::Good;
|
||||||
if (diag != net_diag) net_diag = diag;
|
if (diag != net_diag) net_diag = diag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIProtocol::calc_freq() {
|
void PIProtocol::calc_freq() {
|
||||||
tf = 1000. / timer->elapsed_m();
|
tf = 1000.f / diagTimer->elapsed_m();
|
||||||
timer->reset();
|
diagTimer->reset();
|
||||||
if (cur_pckt != 1) tf = 0.;
|
if (cur_pckt != 1) tf = 0.f;
|
||||||
immediateFreq = tf;
|
immediateFreq = tf;
|
||||||
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
|
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
|
||||||
last_freq.push_back(tf);
|
last_freq.push_back(tf);
|
||||||
@@ -155,26 +277,51 @@ void PIProtocol::calc_freq() {
|
|||||||
|
|
||||||
|
|
||||||
void PIProtocol::check_state() {
|
void PIProtocol::check_state() {
|
||||||
if (type == PIProtocol::Serial) {
|
if (type_send == PIProtocol::Serial) {
|
||||||
if (serial->initialized()) devState = "Initialized";
|
if (ser->initialized()) devSenderState = "Initialized";
|
||||||
else devState = "Uninitialized";
|
else devSenderState = "Uninitialized";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (type == PIProtocol::Ethernet) {
|
if (type_send == PIProtocol::Ethernet) {
|
||||||
if (ether->initialized()) devState = "Initialized";
|
if (eth->senderInitialized()) devSenderState = "Initialized";
|
||||||
else devState = "Uninitialized";
|
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() {
|
void PIProtocol::send() {
|
||||||
//lock();
|
//lock();
|
||||||
memcpy(packet, sendDataPtr, sendDataSize);
|
//memcpy(packet, sendDataPtr, sendDataSize);
|
||||||
//unlock();
|
//unlock();
|
||||||
if (type == PIProtocol::Serial)
|
if (sendDataPtr == 0 || sendDataSize == 0) return;
|
||||||
if (serial->send(packet, sendDataSize))
|
if (!aboutSend()) return;
|
||||||
|
if (type_rec == PIProtocol::Serial)
|
||||||
|
if (ser->send((char * )sendDataPtr, sendDataSize))
|
||||||
send_count++;
|
send_count++;
|
||||||
if (type == PIProtocol::Ethernet)
|
if (type_rec == PIProtocol::Ethernet)
|
||||||
if (ether->send(packet, sendDataSize))
|
if (eth->send((char * )sendDataPtr, sendDataSize))
|
||||||
send_count++;
|
send_count++;
|
||||||
}
|
}
|
||||||
|
|||||||
113
piprotocol.h
113
piprotocol.h
@@ -4,77 +4,108 @@
|
|||||||
#include "piserial.h"
|
#include "piserial.h"
|
||||||
#include "piethernet.h"
|
#include "piethernet.h"
|
||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
|
#include "piconfig.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
typedef void (*ReceiveFunc)(void * );
|
||||||
|
|
||||||
class PIProtocol
|
class PIProtocol
|
||||||
{
|
{
|
||||||
enum Type {Serial, Ethernet};
|
enum Type {None, Serial, Ethernet};
|
||||||
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();
|
|
||||||
|
|
||||||
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
|
||||||
|
|
||||||
void startReceive(); // start receive
|
public:
|
||||||
void stopReceive(); // stop receive
|
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
|
||||||
void startSend(float frequency = 20.f) {sendtimer->start(frequency > 0 ? 1000.f / frequency : 1000);} // start sending
|
void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config
|
||||||
void stopSend() {sendtimer->stop();} // stop sending
|
~PIProtocol();
|
||||||
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
|
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);
|
||||||
|
|
||||||
|
float immediateFrequency() {return immediateFreq;}
|
||||||
|
float integralFrequency() {return integralFreq;}
|
||||||
float * immediateFrequency_ptr() {return &immediateFreq;}
|
float * immediateFrequency_ptr() {return &immediateFreq;}
|
||||||
float * integralFrequency_ptr() {return &integralFreq;}
|
float * integralFrequency_ptr() {return &integralFreq;}
|
||||||
unsigned long long int * wrongCount_ptr() {return &wrong_count;}
|
ullong receiveCount() {return receive_count;}
|
||||||
unsigned long long int * receiveCount_ptr() {return &receive_count;}
|
ullong * receiveCount_ptr() {return &receive_count;}
|
||||||
unsigned long long int * sendCount_ptr() {return &send_count;}
|
ullong wrongCount() {return wrong_count;}
|
||||||
PIProtocol::Quality * quality_ptr() {return &net_diag;}
|
ullong * wrongCount_ptr() {return &wrong_count;}
|
||||||
PIString * deviceState_ptr() {return &devState;}
|
ullong sendCount() {return send_count;}
|
||||||
PIString deviceName() {return devName;}
|
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:
|
protected:
|
||||||
|
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 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
|
virtual uint checksum_i(void * data, int size) { // function for checksum (uint)
|
||||||
{
|
uint c = 0;
|
||||||
unsigned char c = 0;
|
|
||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
c += data[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);
|
c = ~(c + 1);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void send();
|
|
||||||
void check_state();
|
void check_state();
|
||||||
void calc_freq();
|
void calc_freq();
|
||||||
void calc_diag();
|
void calc_diag();
|
||||||
static bool received(void * t, char * data);
|
|
||||||
static void diag_event(void * t);
|
|
||||||
|
|
||||||
PISerial * serial;
|
PISerial * ser;
|
||||||
PIEthernet * ether;
|
PIEthernet * eth;
|
||||||
unsigned int dataSize, headerSize, sendDataSize;
|
uint dataSize, headerSize, sendDataSize;
|
||||||
unsigned char * dataPtr, * headerPtr, * sendDataPtr;
|
uchar * dataPtr, * headerPtr, * sendDataPtr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void run(void * e) {PIProtocol* p = (PIProtocol*)e; if (p->aboutSend()) p->send();}
|
static void sendEvent(void * e) {((PIProtocol * )e)->send();}
|
||||||
PITimer * timer, * sendtimer;
|
static bool receiveEvent(void * t, char * data, int size);
|
||||||
PIProtocol::Type type;
|
static void diagEvent(void * t);
|
||||||
|
ReceiveFunc ret_func;
|
||||||
|
PITimer * diagTimer, * sendTimer;
|
||||||
|
PIProtocol::Type type_send, type_rec;
|
||||||
PIProtocol::Quality net_diag;
|
PIProtocol::Quality net_diag;
|
||||||
deque<float> last_freq;
|
deque<float> last_freq;
|
||||||
deque<char> last_packets;
|
deque<char> last_packets;
|
||||||
PIString devState, devName;
|
PIString devReceiverName, devReceiverState, devSenderName, devSenderState;
|
||||||
bool work;
|
bool work;
|
||||||
float exp_freq, immediateFreq, integralFreq, tf;
|
float exp_freq, send_freq, immediateFreq, integralFreq, tf;
|
||||||
int packets[2];
|
int packets[2];
|
||||||
uint pckt_cnt, pckt_cnt_max;
|
uint pckt_cnt, pckt_cnt_max;
|
||||||
char * packet;
|
char * packet, cur_pckt;
|
||||||
char cur_pckt;
|
ullong wrong_count, receive_count, send_count;
|
||||||
unsigned long long int wrong_count, receive_count, send_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIPROTOCOL_H
|
#endif // PIPROTOCOL_H
|
||||||
|
|||||||
58
piserial.cpp
58
piserial.cpp
@@ -9,19 +9,21 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() {
|
|||||||
dataSize = headerSize = 0;
|
dataSize = headerSize = 0;
|
||||||
headerPtr = 0;
|
headerPtr = 0;
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
buffer = new char[BUFFER_SIZE];
|
//buffer = new char[BUFFER_SIZE];
|
||||||
sbuffer = new char[BUFFER_SIZE];
|
//sbuffer = new char[BUFFER_SIZE];
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
hCom = 0;
|
hCom = 0;
|
||||||
#endif
|
#endif
|
||||||
ispeed = ospeed = B115200;
|
ispeed = ospeed = S115200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PISerial::~PISerial() {
|
PISerial::~PISerial() {
|
||||||
terminate();
|
terminate();
|
||||||
delete buffer;
|
/*if (buffer != 0) delete buffer;
|
||||||
delete sbuffer;
|
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() {
|
void PISerial::begin() {
|
||||||
sbuffIndex = 0;
|
sbuffIndex = 0;
|
||||||
startIndex = 0;
|
startIndex = 0;
|
||||||
@@ -89,7 +109,7 @@ void PISerial::run() {
|
|||||||
{
|
{
|
||||||
//cout << "vsdfgvb" << endl;
|
//cout << "vsdfgvb" << endl;
|
||||||
memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize);
|
memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize);
|
||||||
if (ret_func(data, pbuffer))
|
if (ret_func(data, pbuffer, dataSize))
|
||||||
{
|
{
|
||||||
startIndex = 0;
|
startIndex = 0;
|
||||||
sbuffIndex = -1;
|
sbuffIndex = -1;
|
||||||
@@ -143,7 +163,7 @@ void PISerial::run() {
|
|||||||
b = buffer[i];
|
b = buffer[i];
|
||||||
sbuffer[sbuffIndex] = b;
|
sbuffer[sbuffIndex] = b;
|
||||||
if (sbuffIndex == dataSize - 1) {
|
if (sbuffIndex == dataSize - 1) {
|
||||||
if (ret_func != 0) ret_func(data, sbuffer);
|
if (ret_func != 0) ret_func(data, sbuffer, dataSize);
|
||||||
sbuffIndex = -1;
|
sbuffIndex = -1;
|
||||||
}
|
}
|
||||||
sbuffIndex++;
|
sbuffIndex++;
|
||||||
@@ -163,7 +183,7 @@ bool PISerial::init() {
|
|||||||
#ifdef WINDOWS
|
#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);
|
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) {
|
if(hCom == INVALID_HANDLE_VALUE) {
|
||||||
cout << "[PISerial] Unable to open " << devName << endl;
|
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fd = 0;
|
fd = 0;
|
||||||
@@ -174,7 +194,7 @@ bool PISerial::init() {
|
|||||||
times.WriteTotalTimeoutConstant = 0;
|
times.WriteTotalTimeoutConstant = 0;
|
||||||
times.WriteTotalTimeoutMultiplier = 1;
|
times.WriteTotalTimeoutMultiplier = 1;
|
||||||
if (SetCommTimeouts(hCom, ×) == -1) {
|
if (SetCommTimeouts(hCom, ×) == -1) {
|
||||||
cout << "[PISerial] Unable to set timeouts for " << devName << endl;
|
cout << "[PISerial] Unable to set timeouts for \"" << devName << "\"" << endl;
|
||||||
CloseHandle(hCom);
|
CloseHandle(hCom);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
return false;
|
return false;
|
||||||
@@ -184,12 +204,12 @@ bool PISerial::init() {
|
|||||||
GetCommState(hCom, &sdesc);
|
GetCommState(hCom, &sdesc);
|
||||||
desc = sdesc;
|
desc = sdesc;
|
||||||
desc.DCBlength = sizeof(desc);
|
desc.DCBlength = sizeof(desc);
|
||||||
desc.BaudRate = ispeed;
|
desc.BaudRate = convertSpeed(ispeed);
|
||||||
desc.ByteSize = 8;
|
desc.ByteSize = 8;
|
||||||
desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1;
|
desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1;
|
||||||
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||||
if (SetCommState(hCom, &desc) == -1) {
|
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);
|
CloseHandle(hCom);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
return false;
|
return false;
|
||||||
@@ -197,7 +217,7 @@ bool PISerial::init() {
|
|||||||
#else
|
#else
|
||||||
fd = open(devName.data(), O_NOCTTY | O_RDWR);
|
fd = open(devName.data(), O_NOCTTY | O_RDWR);
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
cout << "[PISerial] Unable to open " << devName << endl;
|
cout << "[PISerial] Unable to open \"" << devName << "\"" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fcntl(fd, F_SETFL, 0);
|
fcntl(fd, F_SETFL, 0);
|
||||||
@@ -206,16 +226,20 @@ bool PISerial::init() {
|
|||||||
sdesc = desc;
|
sdesc = desc;
|
||||||
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
desc.c_iflag = desc.c_oflag = desc.c_lflag = 0;
|
||||||
desc.c_cflag = CLOCAL | CREAD | CSIZE;
|
desc.c_cflag = CLOCAL | CREAD | CSIZE;
|
||||||
if (params[PISerial::TwoStopBits]) desc.c_cflag &= CSTOPB;
|
if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB;
|
||||||
if (params[PISerial::IgnoreParityControl]) desc.c_iflag &= IGNPAR ; // | INPCK | IGNBRK | IGNCR;
|
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[VMIN] = 0;
|
||||||
desc.c_cc[VTIME] = 1;
|
desc.c_cc[VTIME] = 1;
|
||||||
|
|
||||||
cfsetispeed(&desc, ispeed);
|
cfsetispeed(&desc, convertSpeed(ispeed));
|
||||||
cfsetospeed(&desc, ospeed);
|
cfsetospeed(&desc, convertSpeed(ospeed));
|
||||||
|
|
||||||
if(tcsetattr(fd, TCSANOW, &desc) < 0) {
|
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);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
36
piserial.h
36
piserial.h
@@ -25,23 +25,36 @@
|
|||||||
|
|
||||||
#define BUFFER_SIZE 4096
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
typedef bool (*SerialFunc)(void * , char * );
|
typedef bool (*SerialFunc)(void * , char * , int );
|
||||||
|
|
||||||
class PISerial: public PIThread
|
class PISerial: public PIThread
|
||||||
{
|
{
|
||||||
public:
|
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(PIString name = "serial", void * data = 0, SerialFunc slot = 0);
|
||||||
~PISerial();
|
~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 setSlot(SerialFunc func) {ret_func = func;}
|
||||||
void setSpeed(int speed) {ospeed = ispeed = speed;}
|
void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;}
|
||||||
void setOutSpeed(int speed) {ospeed = speed;}
|
void setOutSpeed(PISerial::Speed speed) {ospeed = speed;}
|
||||||
void setInSpeed(int speed) {ispeed = speed;}
|
void setInSpeed(PISerial::Speed speed) {ispeed = speed;}
|
||||||
void setDevice(const PIString & dev) {devName = dev;}
|
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 setData(void * d) {data = d;}
|
||||||
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr;
|
void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr;
|
||||||
this->headerSize = headerSize;
|
this->headerSize = headerSize;
|
||||||
@@ -53,6 +66,8 @@ public:
|
|||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int convertSpeed(PISerial::Speed speed);
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void run();
|
void run();
|
||||||
void end();
|
void end();
|
||||||
@@ -65,13 +80,14 @@ private:
|
|||||||
termios desc, sdesc;
|
termios desc, sdesc;
|
||||||
uint readed;
|
uint readed;
|
||||||
#endif
|
#endif
|
||||||
int fd, ospeed, ispeed;
|
int fd;
|
||||||
|
PISerial::Speed ospeed, ispeed;
|
||||||
PIString devName;
|
PIString devName;
|
||||||
SerialFunc ret_func;
|
SerialFunc ret_func;
|
||||||
char * buffer, * sbuffer, * hbuffer, * pbuffer;
|
char buffer[BUFFER_SIZE], sbuffer[BUFFER_SIZE], * hbuffer, * pbuffer;
|
||||||
void * headerPtr, * data;
|
void * headerPtr, * data;
|
||||||
int dataSize, headerSize, sbuffIndex, startIndex, backIndex;
|
int dataSize, headerSize, sbuffIndex, startIndex, backIndex;
|
||||||
Flags<PISerial::Parameters> params;
|
PIFlags<PISerial::Parameters> params;
|
||||||
bool first, tryagain;
|
bool first, tryagain;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
234
pistring.cpp
234
pistring.cpp
@@ -1,14 +1,46 @@
|
|||||||
#include "pistring.h"
|
#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) {
|
PIString & PIString::operator +=(const char * str) {
|
||||||
uint i = 0;
|
int l = 0;
|
||||||
while (str[i] != '\0') push_back(str[i++]);
|
while (str[l] != '\0') ++l;
|
||||||
|
appendFromChars(str, l);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString & PIString::operator +=(const string & str) {
|
PIString & PIString::operator +=(const wstring & str) {
|
||||||
uint l = str.size();
|
uint l = str.size();
|
||||||
for (uint i = 0; i < l; ++i) push_back(str[i]);
|
for (uint i = 0; i < l; ++i) push_back(str[i]);
|
||||||
return *this;
|
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 {
|
bool PIString::operator ==(const PIString & str) const {
|
||||||
uint l = str.size();
|
uint l = str.size();
|
||||||
if (size() != l) return false;
|
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 PIString::mid(const int start, const int len) const {
|
||||||
PIString str;
|
PIString str;
|
||||||
int s = start, l = len;
|
int s = start, l = len;
|
||||||
@@ -82,24 +133,12 @@ PIString & PIString::cutMid(const int start, const int len) {
|
|||||||
else {
|
else {
|
||||||
if (l > length() - s)
|
if (l > length() - s)
|
||||||
l = length() - s;
|
l = length() - s;
|
||||||
remove(s, s + l);
|
remove(s, l);
|
||||||
}
|
}
|
||||||
return *this;
|
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() {
|
PIString & PIString::trim() {
|
||||||
int st = 0, fn = 0;
|
int st = 0, fn = 0;
|
||||||
for (int i = 0; i < length(); ++i)
|
for (int i = 0; i < length(); ++i)
|
||||||
@@ -113,9 +152,53 @@ PIString & PIString::trim() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIStringList PIString::split(const PIString & delim) {
|
PIString PIString::trimmed() const {
|
||||||
PIString ts(*this);
|
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;
|
PIStringList sl;
|
||||||
|
if (isEmpty() || delim.isEmpty()) return sl;
|
||||||
|
PIString ts(*this);
|
||||||
int ci = ts.find(delim);
|
int ci = ts.find(delim);
|
||||||
while (ci >= 0) {
|
while (ci >= 0) {
|
||||||
sl << ts.left(ci);
|
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)
|
for (int i = start; i < length(); ++i)
|
||||||
if (at(i) == str)
|
if (at(i) == str)
|
||||||
return i;
|
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();
|
int l = str.length();
|
||||||
for (int i = start; i < length() - l + 1; ++i)
|
for (int i = start; i < length() - l + 1; ++i)
|
||||||
if (mid(i, l) == str)
|
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)
|
for (int i = length() - 1; i >= start; --i)
|
||||||
if (at(i) == str)
|
if (at(i) == str)
|
||||||
return i;
|
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();
|
int l = str.length();
|
||||||
for (int i = length() - l; i >= start; --i)
|
for (int i = length() - l; i >= start; --i)
|
||||||
if (mid(i, l) == str)
|
if (mid(i, l) == str)
|
||||||
@@ -164,7 +247,7 @@ int PIString::findLast(const PIString str, const int start) {
|
|||||||
PIString PIString::toUpperCase() const {
|
PIString PIString::toUpperCase() const {
|
||||||
PIString str(*this);
|
PIString str(*this);
|
||||||
int l = str.size();
|
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;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,11 +255,78 @@ PIString PIString::toUpperCase() const {
|
|||||||
PIString PIString::toLowerCase() const {
|
PIString PIString::toLowerCase() const {
|
||||||
PIString str(*this);
|
PIString str(*this);
|
||||||
int l = str.size();
|
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;
|
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) {
|
char chrUpr(char c) {
|
||||||
if (c >= 'a' && c <= 'z') return c + 'A' - 'a';
|
if (c >= 'a' && c <= 'z') return c + 'A' - 'a';
|
||||||
//if (c >= 'а' && c <= 'я') return c + 'А' - 'а';
|
//if (c >= 'а' && c <= 'я') return c + 'А' - 'а';
|
||||||
@@ -189,3 +339,25 @@ char chrLwr(char c) {
|
|||||||
//if (c >= 'А' && c <= 'Я') return c + 'а' - 'А';
|
//if (c >= 'А' && c <= 'Я') return c + 'а' - 'А';
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIStringList& PIStringList::removeDuplicates() {
|
||||||
|
PIStringList l;
|
||||||
|
PIString s;
|
||||||
|
bool ae;
|
||||||
|
for (uint i = 0; i < size(); ++i) {
|
||||||
|
ae = false;
|
||||||
|
s = at(i);
|
||||||
|
for (uint j = 0; j < l.size(); ++j) {
|
||||||
|
if (s != l[j]) continue;
|
||||||
|
ae = true; break;
|
||||||
|
}
|
||||||
|
if (!ae) {
|
||||||
|
l << s;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
remove(i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|||||||
236
pistring.h
236
pistring.h
@@ -2,112 +2,179 @@
|
|||||||
#define PISTRING_H
|
#define PISTRING_H
|
||||||
|
|
||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
|
#include "pichar.h"
|
||||||
|
|
||||||
class PIStringList;
|
class PIStringList;
|
||||||
|
|
||||||
class PIString: public PIVector<char>
|
class PIString: public PIVector<PIChar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PIString() {;}
|
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 char * str) {*this += str;}
|
||||||
PIString(const string & str) {*this += str;}
|
PIString(const string & str) {*this += str;}
|
||||||
|
PIString(const wstring & str) {*this += str;}
|
||||||
PIString(const PIString & str) {*this += str;}
|
PIString(const PIString & str) {*this += str;}
|
||||||
PIString(const PIByteArray & ba) {*this += ba;}
|
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 char*() {return data();}
|
||||||
operator const string() {return (size() == 0) ? string() : string(&at(0), size());}
|
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;}
|
||||||
inline char & operator [](const int pos) {return at(pos);}
|
#ifdef WINDOWS
|
||||||
inline const char operator [](const int pos) const {return at(pos);}
|
PIChar operator [](const int pos) const __attribute__ ((optimize(0))) {return at(pos);}
|
||||||
|
#else
|
||||||
PIString & operator +=(const PIString & str);
|
PIChar operator [](const int pos) const {return at(pos);}
|
||||||
PIString & operator +=(const PIByteArray & ba);
|
#endif
|
||||||
inline PIString & operator +=(const char & c) {push_back(c); return *this;}
|
PIChar & operator [](const int pos) {return at(pos);}
|
||||||
PIString & operator +=(const char * str);
|
|
||||||
PIString & operator +=(const string & str);
|
|
||||||
|
|
||||||
bool operator ==(const PIString & str) const;
|
bool operator ==(const PIString & str) const;
|
||||||
inline bool operator ==(const PIByteArray & ba) const {return *this == PIString(ba);}
|
bool operator ==(const PIChar c) const {return *this == PIString(c);}
|
||||||
inline bool operator ==(const char & c) const {return *this == PIString(c);}
|
//inline bool operator ==(const char c) const {return *this == PIString(c);}
|
||||||
inline bool operator ==(const char * str) const {return *this == PIString(str);}
|
bool operator ==(const char * str) const {return *this == PIString(str);}
|
||||||
inline bool operator ==(const string & 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 PIString & str) const;
|
||||||
inline bool operator !=(const PIByteArray & ba) const {return *this != PIString(ba);}
|
bool operator !=(const PIChar c) const {return *this != PIString(c);}
|
||||||
inline bool operator !=(const char & c) const {return *this != PIString(c);}
|
//inline bool operator !=(const char c) const {return *this != PIString(c);}
|
||||||
inline bool operator !=(const char * str) const {return *this != PIString(str);}
|
bool operator !=(const char * str) const {return *this != PIString(str);}
|
||||||
inline bool operator !=(const string & 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;}
|
bool operator <(const PIString & str) const;
|
||||||
inline PIString & operator <<(const PIByteArray & ba) {*this += ba; return *this;}
|
bool operator <(const PIChar c) const {return *this < PIString(c);}
|
||||||
inline PIString & operator <<(const char & c) {*this += c; return *this;}
|
//inline bool operator <(const char c) const {return *this < PIString(c);}
|
||||||
inline PIString & operator <<(const char * str) {*this += str; return *this;}
|
bool operator <(const char * str) const {return *this < PIString(str);}
|
||||||
inline PIString & operator <<(const string & str) {*this += str; return *this;}
|
bool operator <(const string & str) const {return *this < PIString(str);}
|
||||||
inline PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;}
|
|
||||||
inline PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;}
|
bool operator >(const PIString & str) const;
|
||||||
inline PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;}
|
bool operator >(const PIChar c) const {return *this > PIString(c);}
|
||||||
inline PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;}
|
//inline bool operator >(const char c) const {return *this > PIString(c);}
|
||||||
inline PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;}
|
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;
|
PIString mid(const int start, const int len = -1) const;
|
||||||
inline PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);}
|
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 right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);}
|
||||||
PIString & cutMid(const int start, const int len);
|
PIString & cutMid(const int start, const int len);
|
||||||
inline PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);}
|
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 & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);}
|
||||||
PIString trimmed() const;
|
|
||||||
PIString & trim();
|
PIString & trim();
|
||||||
const char * data() const {return stdString().c_str();}
|
PIString trimmed() const;
|
||||||
string stdString() const {return (size() == 0) ? string() : string(&at(0), size());}
|
PIString & replace(const int from, const int count, const PIString & with);
|
||||||
PIStringList split(const PIString & delim);
|
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 toUpperCase() const;
|
||||||
PIString toLowerCase() 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 char str, const int start = 0) const;
|
||||||
int find(const PIString str, const int start = 0);
|
int find(const PIString str, const int start = 0) const;
|
||||||
inline int find(const char * str, const int start = 0) {return find(PIString(str), start);}
|
int find(const char * str, const int start = 0) const {return find(PIString(str), start);}
|
||||||
inline int find(const string str, const int start = 0) {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);
|
int findLast(const char str, const int start = 0) const;
|
||||||
int findLast(const PIString str, const int start = 0);
|
int findLast(const PIString str, const int start = 0) const;
|
||||||
inline int findLast(const char * str, const int start = 0) {return findLast(PIString(str), start);}
|
int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);}
|
||||||
inline int findLast(const string str, const int start = 0) {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();}
|
int length() const {return size();}
|
||||||
inline bool isEmpty() const {return size() == 0;}
|
bool isEmpty() const {return (size() == 0 || *this == "");}
|
||||||
|
|
||||||
int toInt() const {return atoi(data());}
|
bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true") return true; return false;}
|
||||||
short toShort() const {return (short)atoi(data());}
|
char toChar() const;
|
||||||
long toLong() const {return atol(data());}
|
short toShort() const;
|
||||||
float toFloat() const {return (float)atof(data());}
|
int toInt() const;
|
||||||
double toDouble() const {return atof(data());}
|
long toLong() const;
|
||||||
inline PIByteArray toBase64() {return PIByteArray(data(), size()).toBase64();}
|
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 char value) {clear(); *this += itos(value); return *this;}
|
||||||
inline PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
|
PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
|
||||||
inline PIString & setNumber(const long value) {clear(); *this += ltos(value); return *this;}
|
PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
|
||||||
inline PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;}
|
PIString & setNumber(const long value) {clear(); *this += ltos(value); return *this;}
|
||||||
inline PIString & setNumber(const double value) {clear(); *this += dtos(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 char value) {return PIString(itos(value));}
|
||||||
inline static PIString fromNumber(const uint value) {return PIString(itos(value));}
|
static PIString fromNumber(const int value) {return PIString(itos(value));}
|
||||||
inline static PIString fromNumber(const short value) {return PIString(itos(value));}
|
static PIString fromNumber(const uint value) {return PIString(itos(value));}
|
||||||
inline static PIString fromNumber(const long value) {return PIString(ltos(value));}
|
static PIString fromNumber(const short value) {return PIString(itos(value));}
|
||||||
inline static PIString fromNumber(const float value) {return PIString(ftos(value));}
|
static PIString fromNumber(const long value) {return PIString(ltos(value));}
|
||||||
inline static PIString fromNumber(const double value) {return PIString(dtos(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 & 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 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 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 char * str, const PIString & f) {return PIString(str) + f;}
|
||||||
inline PIString operator +(const string & 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:
|
public:
|
||||||
PIStringList() {;}
|
PIStringList() {;}
|
||||||
PIStringList(const PIString & str) {push_back(str);}
|
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;}
|
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 & c) {push_back(PIString(c)); return *this;}
|
PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;}
|
||||||
inline PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;}
|
PIStringList & operator <<(const string & str) {push_back(str); return *this;}
|
||||||
inline PIStringList & operator <<(const string & str) {push_back(str); return *this;}
|
PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||||
inline PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;}
|
PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||||
inline PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;}
|
PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||||
inline PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;}
|
PIStringList & operator <<(const float & num) {push_back(PIString::fromNumber(num)); return *this;}
|
||||||
inline 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 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
|
#endif // PISTRING_H
|
||||||
|
|||||||
61
pithread.cpp
61
pithread.cpp
@@ -17,7 +17,7 @@ PIThread::~PIThread() {
|
|||||||
|
|
||||||
bool PIThread::start(int timer_delay) {
|
bool PIThread::start(int timer_delay) {
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
terminating = false;
|
terminating = running = false;
|
||||||
timer = timer_delay;
|
timer = timer_delay;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setschedparam(&attr, &sparam);
|
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) {
|
void * PIThread::thread_function(void * t) {
|
||||||
PIThread * ct = (PIThread * )t;
|
PIThread * ct = (PIThread * )t;
|
||||||
|
ct->running = true;
|
||||||
ct->begin();
|
ct->begin();
|
||||||
while (!ct->terminating) {
|
while (!ct->terminating) {
|
||||||
if (ct->lockRun) ct->mutex_.lock();
|
if (ct->lockRun) ct->mutex_.lock();
|
||||||
ct->run();
|
ct->run();
|
||||||
if (ct->lockRun) ct->mutex_.unlock();;
|
if (ct->lockRun) ct->mutex_.unlock();
|
||||||
if (ct->timer > 0) msleep(ct->timer);
|
if (ct->timer > 0) msleep(ct->timer);
|
||||||
}
|
}
|
||||||
ct->end();
|
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) {
|
void PIThread::setPriority(PIThread::Priority prior) {
|
||||||
priority_ = prior;
|
priority_ = prior;
|
||||||
#if __QNX__ || __WIN32__
|
#ifndef LINUX
|
||||||
sparam.sched_priority = (int)priority_;
|
sparam.sched_priority = (int)priority_;
|
||||||
#else
|
#else
|
||||||
sparam.__sched_priority = (int)priority_;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
12
pithread.h
12
pithread.h
@@ -2,7 +2,7 @@
|
|||||||
#define PITHREAD_H
|
#define PITHREAD_H
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "piincludes.h"
|
#include <signal.h>
|
||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
@@ -31,13 +31,16 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool start(int timer_delay = -1);
|
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);
|
void setPriority(PIThread::Priority prior);
|
||||||
PIThread::Priority priority() const {return priority_;}
|
PIThread::Priority priority() const {return priority_;}
|
||||||
bool isRunning() const {return running;}
|
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 needLockRun(bool need) {lockRun = need;}
|
||||||
void lock() {mutex_.lock();;}
|
void lock() {mutex_.lock();}
|
||||||
void unlock() {mutex_.unlock();}
|
void unlock() {mutex_.unlock();}
|
||||||
PIMutex & mutex() {return mutex_;}
|
PIMutex & mutex() {return mutex_;}
|
||||||
|
|
||||||
@@ -48,6 +51,7 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void * thread_function(void * t);
|
static void * thread_function(void * t);
|
||||||
|
static void * thread_function_once(void * t);
|
||||||
|
|
||||||
volatile bool terminating, running, lockRun;
|
volatile bool terminating, running, lockRun;
|
||||||
int timer, policy;
|
int timer, policy;
|
||||||
|
|||||||
52
pitimer.cpp
52
pitimer.cpp
@@ -4,19 +4,20 @@
|
|||||||
PITimer::PITimer(TimerEvent slot, void * data_) {
|
PITimer::PITimer(TimerEvent slot, void * data_) {
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
data = data_;
|
data = data_;
|
||||||
#ifndef __WIN32__
|
#ifndef WINDOWS
|
||||||
ti = -1;
|
ti = -1;
|
||||||
running = false;
|
running = false;
|
||||||
se.sigev_notify = SIGEV_THREAD;
|
se.sigev_notify = SIGEV_THREAD;
|
||||||
se.sigev_value.sival_ptr = this;
|
se.sigev_value.sival_ptr = this;
|
||||||
se.sigev_notify_function = timer_event;
|
se.sigev_notify_function = timer_event;
|
||||||
se.sigev_notify_attributes = 0;
|
se.sigev_notify_attributes = 0;
|
||||||
|
lockRun = false;
|
||||||
#endif
|
#endif
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef __WIN32__
|
#ifndef WINDOWS
|
||||||
void PITimer::start(double msecs) {
|
void PITimer::start(double msecs) {
|
||||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||||
spec.it_interval.tv_sec = (time_t)(msecs / 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) {
|
void PITimer::timer_event(sigval e) {
|
||||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
double PITimer::elapsed_n() {
|
double PITimer::elapsed_n() {
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
t_cur = GetCurrentTime();
|
t_cur = GetCurrentTime();
|
||||||
return (t_cur * 1000000. - t_st * 1000000.);
|
return (t_cur * 1000000. - t_st * 1000000.);
|
||||||
#else
|
#else
|
||||||
@@ -47,7 +52,7 @@ double PITimer::elapsed_n() {
|
|||||||
|
|
||||||
|
|
||||||
double PITimer::elapsed_u() {
|
double PITimer::elapsed_u() {
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
t_cur = GetCurrentTime();
|
t_cur = GetCurrentTime();
|
||||||
return (t_cur * 1000. - t_st * 1000.);
|
return (t_cur * 1000. - t_st * 1000.);
|
||||||
#else
|
#else
|
||||||
@@ -59,7 +64,7 @@ double PITimer::elapsed_u() {
|
|||||||
|
|
||||||
|
|
||||||
double PITimer::elapsed_m() {
|
double PITimer::elapsed_m() {
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
t_cur = GetCurrentTime();
|
t_cur = GetCurrentTime();
|
||||||
return (double)(t_cur - t_st);
|
return (double)(t_cur - t_st);
|
||||||
#else
|
#else
|
||||||
@@ -71,7 +76,7 @@ double PITimer::elapsed_m() {
|
|||||||
|
|
||||||
|
|
||||||
double PITimer::elapsed_s() {
|
double PITimer::elapsed_s() {
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
t_cur = GetCurrentTime();
|
t_cur = GetCurrentTime();
|
||||||
return (t_cur / 1000. - t_st / 1000.);
|
return (t_cur / 1000. - t_st / 1000.);
|
||||||
#else
|
#else
|
||||||
@@ -104,25 +109,26 @@ PIDate currentDate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string time2string(const PITime & time, const string & format) {
|
PIString time2string(const PITime & time, const PIString & format) {
|
||||||
string ts = format;
|
PIString ts = format;
|
||||||
int i = ts.find_first_of('h');
|
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.hours));
|
ts.replace("h", PIString::fromNumber(time.hours));
|
||||||
i = ts.find_first_of('m');
|
ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0'));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.minutes));
|
ts.replace("m", PIString::fromNumber(time.minutes));
|
||||||
i = ts.find_first_of('s');
|
ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0'));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(time.seconds));
|
ts.replace("s", PIString::fromNumber(time.seconds));
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string date2string(const PIDate & date, const string & format) {
|
PIString date2string(const PIDate & date, const PIString & format) {
|
||||||
string ts = format;
|
PIString ts = format;
|
||||||
int i = ts.find_first_of('y');
|
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.year));
|
ts.replace("yy", PIString::fromNumber(date.year).expandLeftTo(2, '0'));
|
||||||
i = ts.find_first_of('m');
|
ts.replace("y", PIString::fromNumber(date.year));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.month));
|
ts.replace("mm", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||||
i = ts.find_first_of('d');
|
ts.replace("m", PIString::fromNumber(date.month));
|
||||||
if (i >= 0) ts = ts.replace(i, 1, itos(date.day));
|
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("d", PIString::fromNumber(date.day));
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|||||||
16
pitimer.h
16
pitimer.h
@@ -4,6 +4,7 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
|
#include "pistring.h"
|
||||||
|
|
||||||
typedef void (*TimerEvent)(void * );
|
typedef void (*TimerEvent)(void * );
|
||||||
|
|
||||||
@@ -20,20 +21,23 @@ struct PIDate {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class PITimer
|
class PITimer
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
: public PIThread
|
: public PIThread
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PITimer(TimerEvent slot = 0, void * data = 0);
|
PITimer(TimerEvent slot = 0, void * data = 0);
|
||||||
~PITimer() {stop();}
|
~PITimer() {stop();}
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
void reset() {t_st = GetCurrentTime();}
|
void reset() {t_st = GetCurrentTime();}
|
||||||
#else
|
#else
|
||||||
void reset() {clock_gettime(0, &t_st);}
|
void reset() {clock_gettime(0, &t_st);}
|
||||||
void start(double msecs);
|
void start(double msecs);
|
||||||
void stop() {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
|
void stop() {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
|
||||||
bool isRunning() const {return running;}
|
bool isRunning() const {return running;}
|
||||||
|
void needLockRun(bool need) {lockRun = need;}
|
||||||
|
void lock() {mutex_.lock();}
|
||||||
|
void unlock() {mutex_.unlock();}
|
||||||
#endif
|
#endif
|
||||||
double elapsed_n(); // nanoseconds
|
double elapsed_n(); // nanoseconds
|
||||||
double elapsed_u(); // microseconds
|
double elapsed_u(); // microseconds
|
||||||
@@ -41,7 +45,7 @@ public:
|
|||||||
double elapsed_s(); // seconds
|
double elapsed_s(); // seconds
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef __WIN32__
|
#ifdef WINDOWS
|
||||||
void run() {if (ret_func != 0) ret_func(data);}
|
void run() {if (ret_func != 0) ret_func(data);}
|
||||||
|
|
||||||
long int t_st, t_cur;
|
long int t_st, t_cur;
|
||||||
@@ -49,6 +53,8 @@ private:
|
|||||||
static void timer_event(sigval e);
|
static void timer_event(sigval e);
|
||||||
|
|
||||||
bool running;
|
bool running;
|
||||||
|
volatile bool lockRun;
|
||||||
|
PIMutex mutex_;
|
||||||
int ti;
|
int ti;
|
||||||
itimerspec spec;
|
itimerspec spec;
|
||||||
timespec t_st, t_cur;
|
timespec t_st, t_cur;
|
||||||
@@ -63,7 +69,7 @@ private:
|
|||||||
|
|
||||||
PITime currentTime();
|
PITime currentTime();
|
||||||
PIDate currentDate();
|
PIDate currentDate();
|
||||||
string time2string(const PITime & time, const string & format = "h:m:s");
|
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss");
|
||||||
string date2string(const PIDate & date, const string & format = "d.m.y");
|
PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy");
|
||||||
|
|
||||||
#endif // PITIMER_H
|
#endif // PITIMER_H
|
||||||
|
|||||||
246
pivariable.cpp
246
pivariable.cpp
@@ -1,111 +1,195 @@
|
|||||||
#include "pivariable.h"
|
#include "pivariable.h"
|
||||||
|
|
||||||
|
|
||||||
void PIVariable::setVariable(const PIString & str) {
|
bool PIVariant::operator ==(const PIVariant & v) const {
|
||||||
type_ = PIVariable::fromString(str);
|
if (type != v.type) return false;
|
||||||
size_ = PIVariable::variableSize(type_);
|
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) {
|
void PIVariant::setValueOnly(const PIString & s) {
|
||||||
PIString s = str.trimmed().toLowerCase();
|
switch (type) {
|
||||||
if (s == "char" || s == "sbyte") return PIVariable::Char;
|
case PIVariant::Bool: vBool = s.toBool(); break;
|
||||||
if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariable::Short;
|
case PIVariant::Char: vChar = s.toChar(); break;
|
||||||
if (s == "int" || s == "signed" || s == "signed int") return PIVariable::Int;
|
case PIVariant::Short: vShort = s.toShort(); break;
|
||||||
if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariable::Long;
|
case PIVariant::Int: vInt = s.toInt(); break;
|
||||||
if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariable::LLong;
|
case PIVariant::Long: vLong = s.toLong(); break;
|
||||||
if (s == "uchar" || s == "byte") return PIVariable::UChar;
|
case PIVariant::LLong: vLLong = s.toLLong(); break;
|
||||||
if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariable::UShort;
|
case PIVariant::UChar: vUChar = s.toChar(); break;
|
||||||
if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariable::UInt;
|
case PIVariant::UShort: vUShort = s.toShort(); break;
|
||||||
if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariable::ULong;
|
case PIVariant::UInt: vUInt = s.toInt(); break;
|
||||||
if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariable::ULLong;
|
case PIVariant::ULong: vULong = s.toLong(); break;
|
||||||
if (s == "float") return PIVariable::Float;
|
case PIVariant::ULLong: vULLong = s.toLLong(); break;
|
||||||
if (s == "double" || s == "real") return PIVariable::Double;
|
case PIVariant::Float: vFloat = s.toFloat(); break;
|
||||||
if (s == "ldouble" || s == "long double") return PIVariable::LDouble;
|
case PIVariant::Double: vDouble = s.toDouble(); break;
|
||||||
if (s == "bool") return PIVariable::Bool;
|
case PIVariant::LDouble: vLDouble = s.toLDouble(); break;
|
||||||
return PIVariable::Double;
|
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) {
|
switch (var) {
|
||||||
case PIVariable::Char: return "char";
|
case PIVariant::Bool: return "bool";
|
||||||
case PIVariable::Short: return "short";
|
case PIVariant::Char: return "char";
|
||||||
case PIVariable::Int: return "int";
|
case PIVariant::Short: return "short";
|
||||||
case PIVariable::Long: return "long";
|
case PIVariant::Int: return "int";
|
||||||
case PIVariable::LLong: return "llong";
|
case PIVariant::Long: return "long";
|
||||||
case PIVariable::UChar: return "uchar";
|
case PIVariant::LLong: return "llong";
|
||||||
case PIVariable::UShort: return "ushort";
|
case PIVariant::UChar: return "uchar";
|
||||||
case PIVariable::UInt: return "uint";
|
case PIVariant::UShort: return "ushort";
|
||||||
case PIVariable::ULong: return "ulong";
|
case PIVariant::UInt: return "uint";
|
||||||
case PIVariable::ULLong: return "ullong";
|
case PIVariant::ULong: return "ulong";
|
||||||
case PIVariable::Float: return "float";
|
case PIVariant::ULLong: return "ullong";
|
||||||
case PIVariable::Double: return "double";
|
case PIVariant::Float: return "float";
|
||||||
case PIVariable::LDouble: return "ldouble";
|
case PIVariant::Double: return "double";
|
||||||
case PIVariable::Bool: return "bool";
|
case PIVariant::LDouble: return "ldouble";
|
||||||
|
case PIVariant::String: return "string";
|
||||||
|
case PIVariant::StringList: return "stringlist";
|
||||||
}
|
}
|
||||||
return "double";
|
return "double";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint PIVariable::variableSize(const PIVariable::Type & var) {
|
uint PIVariant::variableSize(const PIVariant::Type & var) {
|
||||||
switch (var) {
|
switch (var) {
|
||||||
case PIVariable::Char: return sizeof(char);
|
case PIVariant::Bool: return sizeof(bool);
|
||||||
case PIVariable::Short: return sizeof(short);
|
case PIVariant::Char: return sizeof(char);
|
||||||
case PIVariable::Int: return sizeof(int);
|
case PIVariant::Short: return sizeof(short);
|
||||||
case PIVariable::Long: return sizeof(long);
|
case PIVariant::Int: return sizeof(int);
|
||||||
case PIVariable::LLong: return sizeof(llong);
|
case PIVariant::Long: return sizeof(long);
|
||||||
case PIVariable::UChar: return sizeof(uchar);
|
case PIVariant::LLong: return sizeof(llong);
|
||||||
case PIVariable::UShort: return sizeof(ushort);
|
case PIVariant::UChar: return sizeof(uchar);
|
||||||
case PIVariable::UInt: return sizeof(uint);
|
case PIVariant::UShort: return sizeof(ushort);
|
||||||
case PIVariable::ULong: return sizeof(ulong);
|
case PIVariant::UInt: return sizeof(uint);
|
||||||
case PIVariable::ULLong: return sizeof(ullong);
|
case PIVariant::ULong: return sizeof(ulong);
|
||||||
case PIVariable::Float: return sizeof(float);
|
case PIVariant::ULLong: return sizeof(ullong);
|
||||||
case PIVariable::Double: return sizeof(double);
|
case PIVariant::Float: return sizeof(float);
|
||||||
case PIVariable::LDouble: return sizeof(ldouble);
|
case PIVariant::Double: return sizeof(double);
|
||||||
case PIVariable::Bool: return sizeof(bool);
|
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) {
|
switch (var) {
|
||||||
case PIVariable::Char: return (double)(*((char * )var_ptr));
|
case PIVariant::Bool: return (double)(*((bool * )var_ptr));
|
||||||
case PIVariable::Short: return (double)(*((short * )var_ptr));
|
case PIVariant::Char: return (double)(*((char * )var_ptr));
|
||||||
case PIVariable::Int: return (double)(*((int * )var_ptr));
|
case PIVariant::Short: return (double)(*((short * )var_ptr));
|
||||||
case PIVariable::Long: return (double)(*((long * )var_ptr));
|
case PIVariant::Int: return (double)(*((int * )var_ptr));
|
||||||
case PIVariable::LLong: return (double)(*((llong * )var_ptr));
|
case PIVariant::Long: return (double)(*((long * )var_ptr));
|
||||||
case PIVariable::UChar: return (double)(*((uchar * )var_ptr));
|
case PIVariant::LLong: return (double)(*((llong * )var_ptr));
|
||||||
case PIVariable::UShort: return (double)(*((ushort * )var_ptr));
|
case PIVariant::UChar: return (double)(*((uchar * )var_ptr));
|
||||||
case PIVariable::UInt: return (double)(*((uint * )var_ptr));
|
case PIVariant::UShort: return (double)(*((ushort * )var_ptr));
|
||||||
case PIVariable::ULong: return (double)(*((ulong * )var_ptr));
|
case PIVariant::UInt: return (double)(*((uint * )var_ptr));
|
||||||
case PIVariable::ULLong: return (double)(*((ullong * )var_ptr));
|
case PIVariant::ULong: return (double)(*((ulong * )var_ptr));
|
||||||
case PIVariable::Float: return (double)(*((float * )var_ptr));
|
case PIVariant::ULLong: return (double)(*((ullong * )var_ptr));
|
||||||
case PIVariable::Double: return (double)(*((double * )var_ptr));
|
case PIVariant::Float: return (double)(*((float * )var_ptr));
|
||||||
case PIVariable::LDouble: return (ldouble)(*((ldouble * )var_ptr));
|
case PIVariant::Double: return (double)(*((double * )var_ptr));
|
||||||
case PIVariable::Bool: return (double)(*((bool * )var_ptr));
|
case PIVariant::LDouble: return (ldouble)(*((ldouble * )var_ptr));
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
return 0.;
|
return 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIVariable::setVariable(const PIString & str) {
|
||||||
|
type_ = PIVariant::fromString(str);
|
||||||
|
size_ = PIVariant::variableSize(type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIVariable::writeVariable(char * dest) {
|
void PIVariable::writeVariable(char * dest) {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case PIVariable::Char: *((char * )((int)dest + offset)) = value_; return;
|
case PIVariant::Bool: *((bool * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Short: *((short * )((int)dest + offset)) = value_; return;
|
case PIVariant::Char: *((char * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Int: *((int * )((int)dest + offset)) = value_; return;
|
case PIVariant::Short: *((short * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Long: *((long * )((int)dest + offset)) = value_; return;
|
case PIVariant::Int: *((int * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::LLong: *((llong * )((int)dest + offset)) = value_; return;
|
case PIVariant::Long: *((long * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::UChar: *((uchar * )((int)dest + offset)) = value_; return;
|
case PIVariant::LLong: *((llong * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::UShort: *((ushort * )((int)dest + offset)) = value_; return;
|
case PIVariant::UChar: *((uchar * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::UInt: *((uint * )((int)dest + offset)) = value_; return;
|
case PIVariant::UShort: *((ushort * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::ULong: *((ulong * )((int)dest + offset)) = value_; return;
|
case PIVariant::UInt: *((uint * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::ULLong: *((ullong * )((int)dest + offset)) = value_; return;
|
case PIVariant::ULong: *((ulong * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Float: *((float * )((int)dest + offset)) = value_; return;
|
case PIVariant::ULLong: *((ullong * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Double: *((double * )((int)dest + offset)) = value_; return;
|
case PIVariant::Float: *((float * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::LDouble: *((ldouble * )((int)dest + offset)) = value_; return;
|
case PIVariant::Double: *((double * )((long)dest + offset)) = value_; return;
|
||||||
case PIVariable::Bool: *((bool * )((int)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;
|
PIString ts;
|
||||||
uint sz = 0;
|
uint sz = 0;
|
||||||
vars.clear();
|
vars.clear();
|
||||||
for (int i = 0; i < conf.numValues(); ++i) {
|
for (int i = 0; i < conf.entriesCount(); ++i) {
|
||||||
var.setVariable(conf.getValue(i));
|
var.setVariable(conf.getValue(i));
|
||||||
var.setName(conf.getName(i));
|
var.setName(conf.getName(i));
|
||||||
var.offset = sz;
|
var.offset = sz;
|
||||||
|
|||||||
120
pivariable.h
120
pivariable.h
@@ -3,16 +3,83 @@
|
|||||||
|
|
||||||
#include "piconfig.h"
|
#include "piconfig.h"
|
||||||
|
|
||||||
|
class PIVariant {
|
||||||
class PIVariable {
|
friend class PIVariable;
|
||||||
public:
|
public:
|
||||||
PIVariable() {;}
|
enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
|
||||||
PIVariable(const PIString & str) {setVariable(str);}
|
|
||||||
~PIVariable() {;}
|
|
||||||
|
|
||||||
enum Type {Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, Bool};
|
PIVariant() {setValue(0.);}
|
||||||
typedef struct {
|
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 {
|
union {
|
||||||
|
bool vBool;
|
||||||
char vChar;
|
char vChar;
|
||||||
short vShort;
|
short vShort;
|
||||||
int vInt;
|
int vInt;
|
||||||
@@ -26,15 +93,32 @@ public:
|
|||||||
float vFloat;
|
float vFloat;
|
||||||
double vDouble;
|
double vDouble;
|
||||||
ldouble vLDouble;
|
ldouble vLDouble;
|
||||||
bool vBool;
|
|
||||||
};
|
};
|
||||||
PIVariable::Type type;
|
PIString vString;
|
||||||
} PIVariant;
|
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:
|
||||||
|
PIVariable() {;}
|
||||||
|
PIVariable(const PIString & str) {setVariable(str);}
|
||||||
|
~PIVariable() {;}
|
||||||
|
|
||||||
void setVariable(const PIString & str);
|
void setVariable(const PIString & str);
|
||||||
void writeVariable(char * dest);
|
void writeVariable(char * dest);
|
||||||
inline void readVariable(const char * var_ptr) {value_ = PIVariable::variableValue((char * )((int)var_ptr + offset), type_);}
|
inline void readVariable(const char * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
|
||||||
inline PIVariable::Type type() const {return type_;}
|
inline PIVariant::Type type() const {return type_;}
|
||||||
inline uint size() const {return size_;}
|
inline uint size() const {return size_;}
|
||||||
inline const PIString & name() {return name_;}
|
inline const PIString & name() {return name_;}
|
||||||
inline void setName(const PIString & str) {name_ = str;}
|
inline void setName(const PIString & str) {name_ = str;}
|
||||||
@@ -43,13 +127,8 @@ public:
|
|||||||
|
|
||||||
int offset;
|
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:
|
private:
|
||||||
PIVariable::Type type_;
|
PIVariant::Type type_;
|
||||||
uint size_;
|
uint size_;
|
||||||
PIString name_;
|
PIString name_;
|
||||||
double value_;
|
double value_;
|
||||||
@@ -95,3 +174,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIVARIABLE_H
|
#endif // PIVARIABLE_H
|
||||||
|
|
||||||
|
#/** PhEDIT attribute block
|
||||||
|
#-11:16777215
|
||||||
|
#0:7338:monospace10:-3:-3:0
|
||||||
|
#** PhEDIT attribute block ends (-0000117)**/
|
||||||
|
|||||||
Reference in New Issue
Block a user