/* 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 Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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); }