250 lines
10 KiB
Plaintext
250 lines
10 KiB
Plaintext
/*
|
|
PIP - Platform Independent Primitives
|
|
Variable, Struct (simple serialization)
|
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "pivariable.h"
|
|
|
|
|
|
bool PIVariant::operator ==(const PIVariant & v) const {
|
|
if (type != v.type) return false;
|
|
switch (type) {
|
|
case PIVariant::Bool: return vBool == v.vBool;
|
|
case PIVariant::Char: return vChar == v.vChar;
|
|
case PIVariant::Short: return vShort == v.vShort;
|
|
case PIVariant::Int: return vInt == v.vInt;
|
|
case PIVariant::Long: return vLong == v.vLong;
|
|
case PIVariant::LLong: return vLLong == v.vLLong;
|
|
case PIVariant::UChar: return vUChar == v.vUChar;
|
|
case PIVariant::UShort: return vUShort == v.vUShort;
|
|
case PIVariant::UInt: return vUInt == v.vUInt;
|
|
case PIVariant::ULong: return vULong == v.vULong;
|
|
case PIVariant::ULLong: return vULLong == v.vULLong;
|
|
case PIVariant::Float: return vFloat == v.vFloat;
|
|
case PIVariant::Double: return vDouble == v.vDouble;
|
|
case PIVariant::LDouble: return vLDouble == v.vLDouble;
|
|
case PIVariant::String: return vString == v.vString;
|
|
case PIVariant::StringList: return vStringList == v.vStringList;
|
|
};
|
|
return false;
|
|
}
|
|
|
|
|
|
void PIVariant::setValueOnly(const PIString & s) {
|
|
switch (type) {
|
|
case PIVariant::Bool: vBool = s.toBool(); break;
|
|
case PIVariant::Char: vChar = s.toChar(); break;
|
|
case PIVariant::Short: vShort = s.toShort(); break;
|
|
case PIVariant::Int: vInt = s.toInt(); break;
|
|
case PIVariant::Long: vLong = s.toLong(); break;
|
|
case PIVariant::LLong: vLLong = s.toLLong(); break;
|
|
case PIVariant::UChar: vUChar = s.toChar(); break;
|
|
case PIVariant::UShort: vUShort = s.toShort(); break;
|
|
case PIVariant::UInt: vUInt = s.toInt(); break;
|
|
case PIVariant::ULong: vULong = s.toLong(); break;
|
|
case PIVariant::ULLong: vULLong = s.toLLong(); break;
|
|
case PIVariant::Float: vFloat = s.toFloat(); break;
|
|
case PIVariant::Double: vDouble = s.toDouble(); break;
|
|
case PIVariant::LDouble: vLDouble = s.toLDouble(); break;
|
|
case PIVariant::String: vString = s; break;
|
|
case PIVariant::StringList: vStringList = s.split("%|%"); break;
|
|
};
|
|
}
|
|
|
|
|
|
PIString 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("%|%");
|
|
};
|
|
return vString;
|
|
}
|
|
|
|
|
|
PIVariant PIVariant::readFromString(const PIString & s) {
|
|
int i = s.find(':');
|
|
if (i < 0 || s.length() < 2) return PIVariant(s);
|
|
PIVariant ret;
|
|
ret.type = PIVariant::fromString(s.left(i));
|
|
ret.setValueOnly(s.right(s.length() - i - 1));
|
|
return ret;
|
|
}
|
|
|
|
|
|
PIVariant::Type PIVariant::fromString(const PIString & str) {
|
|
PIString s = str.trimmed().toLowerCase().replace(" ", "");
|
|
if (s == "bool") return PIVariant::Bool;
|
|
if (s == "char" || s == "sbyte") return PIVariant::Char;
|
|
if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariant::Short;
|
|
if (s == "int" || s == "signed" || s == "signed int") return PIVariant::Int;
|
|
if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariant::Long;
|
|
if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariant::LLong;
|
|
if (s == "uchar" || s == "byte") return PIVariant::UChar;
|
|
if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariant::UShort;
|
|
if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariant::UInt;
|
|
if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariant::ULong;
|
|
if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariant::ULLong;
|
|
if (s == "float") return PIVariant::Float;
|
|
if (s == "double" || s == "real") return PIVariant::Double;
|
|
if (s == "ldouble" || s == "long double") return PIVariant::LDouble;
|
|
if (s == "pistring" || s == "string") return PIVariant::String;
|
|
if (s == "pistringlist" || s == "vector<string>" || s == "vector<pistring>" || s == "pivector<string>" || s == "pivector<pistring>") return PIVariant::StringList;
|
|
return PIVariant::Double;
|
|
}
|
|
|
|
|
|
PIString PIVariant::toString(const PIVariant::Type & var) {
|
|
switch (var) {
|
|
case PIVariant::Bool: return "bool";
|
|
case PIVariant::Char: return "char";
|
|
case PIVariant::Short: return "short";
|
|
case PIVariant::Int: return "int";
|
|
case PIVariant::Long: return "long";
|
|
case PIVariant::LLong: return "llong";
|
|
case PIVariant::UChar: return "uchar";
|
|
case PIVariant::UShort: return "ushort";
|
|
case PIVariant::UInt: return "uint";
|
|
case PIVariant::ULong: return "ulong";
|
|
case PIVariant::ULLong: return "ullong";
|
|
case PIVariant::Float: return "float";
|
|
case PIVariant::Double: return "double";
|
|
case PIVariant::LDouble: return "ldouble";
|
|
case PIVariant::String: return "string";
|
|
case PIVariant::StringList: return "stringlist";
|
|
}
|
|
return "double";
|
|
}
|
|
|
|
|
|
uint PIVariant::variableSize(const PIVariant::Type & var) {
|
|
switch (var) {
|
|
case PIVariant::Bool: return sizeof(bool);
|
|
case PIVariant::Char: return sizeof(char);
|
|
case PIVariant::Short: return sizeof(short);
|
|
case PIVariant::Int: return sizeof(int);
|
|
case PIVariant::Long: return sizeof(long);
|
|
case PIVariant::LLong: return sizeof(llong);
|
|
case PIVariant::UChar: return sizeof(uchar);
|
|
case PIVariant::UShort: return sizeof(ushort);
|
|
case PIVariant::UInt: return sizeof(uint);
|
|
case PIVariant::ULong: return sizeof(ulong);
|
|
case PIVariant::ULLong: return sizeof(ullong);
|
|
case PIVariant::Float: return sizeof(float);
|
|
case PIVariant::Double: return sizeof(double);
|
|
case PIVariant::LDouble: return sizeof(ldouble);
|
|
default: break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
double PIVariant::variableValue(const void * var_ptr, const PIVariant::Type & var) {
|
|
switch (var) {
|
|
case PIVariant::Bool: return (double)(*((bool * )var_ptr));
|
|
case PIVariant::Char: return (double)(*((char * )var_ptr));
|
|
case PIVariant::Short: return (double)(*((short * )var_ptr));
|
|
case PIVariant::Int: return (double)(*((int * )var_ptr));
|
|
case PIVariant::Long: return (double)(*((long * )var_ptr));
|
|
case PIVariant::LLong: return (double)(*((llong * )var_ptr));
|
|
case PIVariant::UChar: return (double)(*((uchar * )var_ptr));
|
|
case PIVariant::UShort: return (double)(*((ushort * )var_ptr));
|
|
case PIVariant::UInt: return (double)(*((uint * )var_ptr));
|
|
case PIVariant::ULong: return (double)(*((ulong * )var_ptr));
|
|
case PIVariant::ULLong: return (double)(*((ullong * )var_ptr));
|
|
case PIVariant::Float: return (double)(*((float * )var_ptr));
|
|
case PIVariant::Double: return (double)(*((double * )var_ptr));
|
|
case PIVariant::LDouble: return (ldouble)(*((ldouble * )var_ptr));
|
|
default: break;
|
|
}
|
|
return 0.;
|
|
}
|
|
|
|
|
|
void PIVariable::setVariable(const PIString & str) {
|
|
type_ = PIVariant::fromString(str);
|
|
size_ = PIVariant::variableSize(type_);
|
|
}
|
|
|
|
|
|
void PIVariable::writeVariable(void * dest) {
|
|
switch (type_) {
|
|
case PIVariant::Bool: *((bool * )((ullong)dest + offset)) = value_ > 0.; return;
|
|
case PIVariant::Char: *((char * )((ullong)dest + offset)) = char(value_); return;
|
|
case PIVariant::Short: *((short * )((ullong)dest + offset)) = short(value_); return;
|
|
case PIVariant::Int: *((int * )((ullong)dest + offset)) = int(value_); return;
|
|
case PIVariant::Long: *((long * )((ullong)dest + offset)) = long(value_); return;
|
|
case PIVariant::LLong: *((llong * )((ullong)dest + offset)) = llong(value_); return;
|
|
case PIVariant::UChar: *((uchar * )((ullong)dest + offset)) = uchar(value_); return;
|
|
case PIVariant::UShort: *((ushort * )((ullong)dest + offset)) = ushort(value_); return;
|
|
case PIVariant::UInt: *((uint * )((ullong)dest + offset)) = uint(value_); return;
|
|
case PIVariant::ULong: *((ulong * )((ullong)dest + offset)) = ulong(value_); return;
|
|
case PIVariant::ULLong: *((ullong * )((ullong)dest + offset)) = ullong(value_); return;
|
|
case PIVariant::Float: *((float * )((ullong)dest + offset)) = float(value_); return;
|
|
case PIVariant::Double: *((double * )((ullong)dest + offset)) = value_; return;
|
|
case PIVariant::LDouble: *((ldouble * )((ullong)dest + offset)) = ldouble(value_); return;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
|
|
void PIStruct::parseFile(const PIString & file) {
|
|
PIConfig conf(file, PIIODevice::ReadOnly);
|
|
PIVariable var;
|
|
PIString ts;
|
|
uint sz = 0;
|
|
vars.clear();
|
|
for (int i = 0; i < conf.entriesCount(); ++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 void * data) {
|
|
for (uint i = 0; i < vars.size(); ++i)
|
|
vars[i].readVariable(data);
|
|
}
|
|
|
|
|
|
void PIStruct::writeData(void * data) {
|
|
for (uint i = 0; i < vars.size(); ++i)
|
|
vars[i].writeVariable(data);
|
|
}
|
|
|