diff --git a/main.cpp b/main.cpp index bc94fe44..6c3d4b45 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,5 @@ #include "pip.h" int main(int argc, char * argv[]) { - PIString s; - cout << "x: " << endl; + cout << PIString("Hello PIP!") << endl; }; diff --git a/piconfig.cpp b/piconfig.cpp index 08d75257..b8a44937 100644 --- a/piconfig.cpp +++ b/piconfig.cpp @@ -236,7 +236,8 @@ void PIConfig::parse() { sind = str.find('#'); if (sind > 0) { comm = str.right(str.size() - sind - 1).trimmed(); - setttype.push_back(comm[0]); + if (comm.length() > 0) setttype.push_back(comm[0]); + else setttype.push_back("s"); comm = comm.right(comm.size() - 1).trimmed(); settcom.push_back(comm); str = str.left(sind); diff --git a/piconsole.cpp b/piconsole.cpp index 3303867a..bd465e98 100644 --- a/piconsole.cpp +++ b/piconsole.cpp @@ -217,6 +217,7 @@ void PIConsole::begin() { void PIConsole::run() { uint cx, clen = 0; + string ts; #ifdef WINDOWS GetConsoleScreenBufferInfo(hOut, &sbi); width = sbi.srWindow.Right - sbi.srWindow.Left; @@ -262,8 +263,10 @@ void PIConsole::run() { case 13: clen = printValue(*tv.ull, tv.format); break; case 14: clen = printValue(bitsValue(tv.uc, tv.bitFrom, tv.bitCount), tv.format); break; } - if (clen + tv.offset < (uint)col_wid) - printf("%s", PIString(col_wid - clen - tv.offset, ' ').data()); + if (clen + tv.offset < (uint)col_wid) { + ts = PIString(col_wid - clen - tv.offset, ' ').stdString(); + printf("%s", ts.c_str()); + } newLine(); } } @@ -391,14 +394,19 @@ inline void PIConsole::printLine(const PIString & value, int dx, Flags= 0) couts((value + PIString(i, ' ')).stdString()); - else couts(value.left(value.size() + i).stdString()); - couts(fstr(Dec).stdString()); + string ts = fstr(format).stdString(); + couts(ts); + if (i >= 0) ts = (value + PIString(i, ' ')).stdString(); + else ts = value.left(value.size() + i).stdString(); + couts(ts); + ts = fstr(Dec).stdString(); + couts(ts); } inline int PIConsole::printValue(const PIString & value, Flags format) { - couts(fstr(format).stdString()); - int ret = couts(value.stdString()); + string ts = fstr(format).stdString(); + couts(ts); + ts = value.stdString(); + int ret = couts(ts); fstr(PIConsole::Dec); return ret; } diff --git a/pifile.cpp b/pifile.cpp index a820792a..1b976227 100644 --- a/pifile.cpp +++ b/pifile.cpp @@ -5,11 +5,11 @@ bool PIFile::open(const PIString & path_, Flags mode_) { cpath = path_; cmode = mode_; if (cmode[New]) { - stream.open(cpath, fstream::in | fstream::out | fstream::trunc); + stream.open(cpath.stdString().c_str(), fstream::in | fstream::out | fstream::trunc); stream.close(); cmode &= ~New; - stream.open(cpath, (fstream::openmode)(int)cmode | fstream::binary); - } else stream.open(cpath, (fstream::openmode)(int)cmode | fstream::binary); + stream.open(cpath.stdString().c_str(), (fstream::openmode)(int)cmode | fstream::binary); + } else stream.open(cpath.stdString().c_str(), (fstream::openmode)(int)cmode | fstream::binary); return isOpened(); } diff --git a/pifile.h b/pifile.h index 50ccfaba..40053045 100644 --- a/pifile.h +++ b/pifile.h @@ -17,7 +17,7 @@ public: bool open(const PIString & path, Flags mode = Read | Write); void close() {stream.close();} - void clear() {close(); stream.open(cpath, fstream::trunc | (fstream::openmode)(int)cmode);} + void clear() {close(); stream.open(cpath.stdString().c_str(), fstream::trunc | (fstream::openmode)(int)cmode);} void seek(int position); void resize(int new_size, char fill = 0); void fill(char c) {stream.fill(c);} diff --git a/piincludes.h b/piincludes.h index d9ede183..5259ef07 100644 --- a/piincludes.h +++ b/piincludes.h @@ -33,6 +33,7 @@ typedef unsigned short int ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned long long ullong; +typedef long double ldouble; using std::cout; using std::cin; diff --git a/pip.h b/pip.h index 055f0c3d..d5966f8f 100644 --- a/pip.h +++ b/pip.h @@ -1,4 +1,4 @@ #include "pitimer.h" -#include "piconfig.h" +#include "pivariable.h" #include "piconsole.h" #include "piprotocol.h" diff --git a/piserial.cpp b/piserial.cpp index e99c62db..79ec2f8a 100644 --- a/piserial.cpp +++ b/piserial.cpp @@ -19,22 +19,32 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { PISerial::~PISerial() { - stop(); - pthread_cancel(thread); + terminate(); + delete buffer; + delete sbuffer; +} + + +void PISerial::terminate() { + if (!initialized()) return; + if (isRunning()) { + stop(); + pthread_cancel(thread); + } #ifdef WINDOWS if (fd != -1) { SetCommState(hCom, &sdesc); SetCommMask(hCom, mask); CloseHandle(hCom); + fd = -1; } #else if (fd != -1) { tcsetattr(fd, TCSANOW, &sdesc); close(fd); + fd = -1; } #endif - delete buffer; - delete sbuffer; } @@ -52,7 +62,8 @@ void PISerial::begin() { void PISerial::run() { if (dataSize == 0) return; char b; - int i = 0, j; + uint i = 0; + int j; #ifdef WINDOWS WaitCommEvent(hCom, 0, 0); ReadFile(hCom, buffer, dataSize, &readed, 0); @@ -128,7 +139,7 @@ void PISerial::run() { if (!tryagain) i++; } } else { - for (int i = 0; i < readed; ++i) { + for (uint i = 0; i < readed; ++i) { b = buffer[i]; sbuffer[sbuffIndex] = b; if (sbuffIndex == dataSize - 1) { @@ -142,23 +153,15 @@ void PISerial::run() { void PISerial::end() { + terminate(); delete pbuffer; delete hbuffer; - if (fd == -1) return; -#ifdef WINDOWS - SetCommState(hCom, &sdesc); - CloseHandle(hCom); -#else - tcsetattr(fd, TCSANOW, &sdesc); - close(fd); -#endif - fd = -1; } bool PISerial::init() { #ifdef WINDOWS - hCom = CreateFile(devName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); + hCom = CreateFile(devName.stdString().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(hCom == INVALID_HANDLE_VALUE) { cout << "[PISerial] Unable to open " << devName << endl; return false; diff --git a/piserial.h b/piserial.h index 53121498..0e7185ec 100644 --- a/piserial.h +++ b/piserial.h @@ -31,7 +31,7 @@ class PISerial: public PIThread { public: // slot is any function format "bool (void*, char*)" - PISerial(PIString name, void * data, SerialFunc slot = 0); + PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0); ~PISerial(); enum Parameters {IgnoreParityControl = 0x01, TwoStopBits = 0x02}; @@ -42,6 +42,7 @@ public: void setInSpeed(int speed) {ispeed = speed;} void setDevice(const PIString & dev) {devName = dev;} void setParameters(Flags parameters) {params = parameters;} + void setData(void * d) {data = d;} void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; this->headerSize = headerSize; this->dataSize = dataSize;} @@ -49,6 +50,7 @@ public: bool send(char * data, int size); bool init(); bool initialized() const {return fd != -1;} + void terminate(); private: void begin(); @@ -61,7 +63,7 @@ private: DWORD readed, mask; #else termios desc, sdesc; - int readed; + uint readed; #endif int fd, ospeed, ispeed; PIString devName; diff --git a/pistring.cpp b/pistring.cpp index 78b1e70a..5677d864 100644 --- a/pistring.cpp +++ b/pistring.cpp @@ -101,7 +101,8 @@ PIString & PIString::trim() { for (int i = length() - 1; i >= 0; --i) if (at(i) != ' ' && at(i) != '\t') {fn = i; break;} - return cutMid(st, fn - st + 1); + *this = mid(st, fn - st + 1); + return *this; } diff --git a/pivariable.cpp b/pivariable.cpp new file mode 100644 index 00000000..438118a9 --- /dev/null +++ b/pivariable.cpp @@ -0,0 +1,144 @@ +#include "pivariable.h" + + +void PIVariable::setVariable(const PIString & str) { + type_ = PIVariable::fromString(str); + size_ = PIVariable::variableSize(type_); +} + + +PIVariable::Type PIVariable::fromString(const PIString & str) { + PIString s = str.trimmed().toLowerCase(); + if (s == "char" || s == "sbyte") return PIVariable::Char; + if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariable::Short; + if (s == "int" || s == "signed" || s == "signed int") return PIVariable::Int; + if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariable::Long; + if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariable::LLong; + if (s == "uchar" || s == "byte") return PIVariable::UChar; + if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariable::UShort; + if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariable::UInt; + if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariable::ULong; + if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariable::ULLong; + if (s == "float") return PIVariable::Float; + if (s == "double" || s == "real") return PIVariable::Double; + if (s == "ldouble" || s == "long double") return PIVariable::LDouble; + if (s == "bool") return PIVariable::Bool; + return PIVariable::Double; +} + + +PIString PIVariable::toString(const PIVariable::Type & var) { + switch (var) { + case PIVariable::Char: return "char"; + case PIVariable::Short: return "short"; + case PIVariable::Int: return "int"; + case PIVariable::Long: return "long"; + case PIVariable::LLong: return "llong"; + case PIVariable::UChar: return "uchar"; + case PIVariable::UShort: return "ushort"; + case PIVariable::UInt: return "uint"; + case PIVariable::ULong: return "ulong"; + case PIVariable::ULLong: return "ullong"; + case PIVariable::Float: return "float"; + case PIVariable::Double: return "double"; + case PIVariable::LDouble: return "ldouble"; + case PIVariable::Bool: return "bool"; + } + return "double"; +} + + +uint PIVariable::variableSize(const PIVariable::Type & var) { + switch (var) { + case PIVariable::Char: return sizeof(char); + case PIVariable::Short: return sizeof(short); + case PIVariable::Int: return sizeof(int); + case PIVariable::Long: return sizeof(long); + case PIVariable::LLong: return sizeof(llong); + case PIVariable::UChar: return sizeof(uchar); + case PIVariable::UShort: return sizeof(ushort); + case PIVariable::UInt: return sizeof(uint); + case PIVariable::ULong: return sizeof(ulong); + case PIVariable::ULLong: return sizeof(ullong); + case PIVariable::Float: return sizeof(float); + case PIVariable::Double: return sizeof(double); + case PIVariable::LDouble: return sizeof(ldouble); + case PIVariable::Bool: return sizeof(bool); + } + return sizeof(double); +} + + +double PIVariable::variableValue(const char * var_ptr, const PIVariable::Type & var) { + switch (var) { + case PIVariable::Char: return (double)(*((char * )var_ptr)); + case PIVariable::Short: return (double)(*((short * )var_ptr)); + case PIVariable::Int: return (double)(*((int * )var_ptr)); + case PIVariable::Long: return (double)(*((long * )var_ptr)); + case PIVariable::LLong: return (double)(*((llong * )var_ptr)); + case PIVariable::UChar: return (double)(*((uchar * )var_ptr)); + case PIVariable::UShort: return (double)(*((ushort * )var_ptr)); + case PIVariable::UInt: return (double)(*((uint * )var_ptr)); + case PIVariable::ULong: return (double)(*((ulong * )var_ptr)); + case PIVariable::ULLong: return (double)(*((ullong * )var_ptr)); + case PIVariable::Float: return (double)(*((float * )var_ptr)); + case PIVariable::Double: return (double)(*((double * )var_ptr)); + case PIVariable::LDouble: return (ldouble)(*((ldouble * )var_ptr)); + case PIVariable::Bool: return (double)(*((bool * )var_ptr)); + } + return 0.; +} + + +void PIVariable::writeVariable(char * dest) { + switch (type_) { + case PIVariable::Char: *((char * )((int)dest + offset)) = value_; return; + case PIVariable::Short: *((short * )((int)dest + offset)) = value_; return; + case PIVariable::Int: *((int * )((int)dest + offset)) = value_; return; + case PIVariable::Long: *((long * )((int)dest + offset)) = value_; return; + case PIVariable::LLong: *((llong * )((int)dest + offset)) = value_; return; + case PIVariable::UChar: *((uchar * )((int)dest + offset)) = value_; return; + case PIVariable::UShort: *((ushort * )((int)dest + offset)) = value_; return; + case PIVariable::UInt: *((uint * )((int)dest + offset)) = value_; return; + case PIVariable::ULong: *((ulong * )((int)dest + offset)) = value_; return; + case PIVariable::ULLong: *((ullong * )((int)dest + offset)) = value_; return; + case PIVariable::Float: *((float * )((int)dest + offset)) = value_; return; + case PIVariable::Double: *((double * )((int)dest + offset)) = value_; return; + case PIVariable::LDouble: *((ldouble * )((int)dest + offset)) = value_; return; + case PIVariable::Bool: *((bool * )((int)dest + offset)) = value_; return; + } +} + + +void PIStruct::parseFile(const PIString & file) { + PIConfig conf(file); + PIVariable var; + PIString ts; + uint sz = 0; + vars.clear(); + for (int i = 0; i < conf.numValues(); ++i) { + var.setVariable(conf.getValue(i)); + var.setName(conf.getName(i)); + var.offset = sz; + sz += var.size(); + ts = conf.getComment(i); + if (ts.length() > 0) + var.setValue(ts.toDouble()); + else var.setValue(0.); + vars.push_back(var); + } + size_ = sz; +} + + +void PIStruct::readData(const char * data) { + for (uint i = 0; i < vars.size(); ++i) + vars[i].readVariable(data); +} + + +void PIStruct::writeData(char * data) { + for (uint i = 0; i < vars.size(); ++i) + vars[i].writeVariable(data); +} + diff --git a/pivariable.h b/pivariable.h new file mode 100644 index 00000000..7c5d72d7 --- /dev/null +++ b/pivariable.h @@ -0,0 +1,97 @@ +#ifndef PIVARIABLE_H +#define PIVARIABLE_H + +#include "piconfig.h" + + +class PIVariable { +public: + PIVariable() {;} + PIVariable(const PIString & str) {setVariable(str);} + ~PIVariable() {;} + + enum Type {Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, Bool}; + typedef struct { + union { + char vChar; + short vShort; + int vInt; + long vLong; + llong vLLong; + uchar vUChar; + ushort vUShort; + uint vUInt; + ulong vULong; + ullong vULLong; + float vFloat; + double vDouble; + ldouble vLDouble; + bool vBool; + }; + PIVariable::Type type; + } PIVariant; + + void setVariable(const PIString & str); + void writeVariable(char * dest); + inline void readVariable(const char * var_ptr) {value_ = PIVariable::variableValue((char * )((int)var_ptr + offset), type_);} + inline PIVariable::Type type() const {return type_;} + inline uint size() const {return size_;} + inline const PIString & name() {return name_;} + inline void setName(const PIString & str) {name_ = str;} + inline double value() const {return value_;} + inline void setValue(const double & val) {value_ = val;} + + int offset; + + static PIVariable::Type fromString(const PIString & str); + static PIString toString(const PIVariable::Type & var); + static uint variableSize(const PIVariable::Type & var); + static double variableValue(const char * var_ptr, const PIVariable::Type & var); + +private: + PIVariable::Type type_; + uint size_; + PIString name_; + double value_; + +}; + + +/* + * PIStruct is abstract structure, described by *.conf file with format of each line: + * " = # ". + * e.g. "pi = double #f 3.1418" + * + * You can write or read binary content of this struct + * by functions "writeData" and "readData", e.g. + * "char * data = new char[struct.size()]; + * struct.writeData(data);" + * + * Access to each variable in struct is looks like + * "double value = struct["pi"].value();" +*/ + +class PIStruct { +public: + PIStruct() {;} + PIStruct(const PIString & str) {parseFile(str);} + + void parseFile(const PIString & file); + void readData(const char * data); + void writeData(char * data); + inline void clear() {vars.clear(); size_ = 0;} + inline uint count() const {return vars.size();} + inline uint size() const {return size_;} + inline const PIString & name() {return name_;} + inline void setName(const PIString & str) {name_ = str;} + inline PIVariable & operator[](const uint & index) {return vars[index];} + inline PIVariable & operator[](const PIString & name) {for (uint i = 0; i < vars.size(); ++i) if (vars[i].name() == name) return vars[i];} + +private: + uint size_; + PIString name_; + vector vars; + +}; + +#endif // PIVARIABLE_H