/*
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 .
*/
#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(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(vULong));
case PIVariant::ULLong: return PIString::fromNumber(static_cast(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" || s == "vector" || s == "pivector" || s == "pivector") 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);
}