From c657fb16f2cd3b79369c8469d8dc6c1b39b4a088 Mon Sep 17 00:00:00 2001
From: aschwinn <al.schwinn@gsi.de>
Date: Tue, 30 Jan 2018 17:51:00 +0100
Subject: [PATCH] #40 move string to value method(s) to silecs-communication
 utils

---
 .../interface/equipment/SilecsRegister.cpp    | 108 ++++++++
 .../interface/equipment/SilecsRegister.h      |   7 +
 .../interface/utility/StringUtilities.h       |  13 +
 .../diagnostictoolmainview.cpp                |   6 -
 .../src/silecs-diagnostic/silecsmodule.cpp    | 247 ++----------------
 .../src/silecs-diagnostic/silecsmodule.h      |   1 +
 .../src/silecs-diagnostic/utils.cpp           |   6 -
 .../src/silecs-diagnostic/utils.h             |   5 -
 8 files changed, 153 insertions(+), 240 deletions(-)

diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
index 321fde7..8685283 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
@@ -1317,6 +1317,114 @@ std::string Register::getValAsByteString(void* pValue, unsigned long maxSize)
     return os.str();
 }
 
+void Register::setScalarfromString(std::string stringValue)
+{
+    if(!isScalar())
+        throw SilecsException(__FILE__, __LINE__,"The type of register " + name_ + " is not a scalar type.");
+
+    switch(format_)
+    {
+        case uInt8:
+        {
+            //Casting to uint16 and later to uint 8 to avoid it being converted for his ASCII character
+            uint16_t val = 0;
+            if(!StringUtilities::from_string<uint16_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to uInt8 failed for register '" + name_ + "'");
+            setValUInt8((uint16_t)val);
+            break;
+        }
+        case Int8:
+        {
+            int8_t val;
+            if(!StringUtilities::from_string<int8_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Int8 failed for register '" + name_ + "'");
+            setValInt8(val);
+            break;
+        }
+        case uInt16:
+        {
+            uint16_t val;
+            if(!StringUtilities::from_string<uint16_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to uInt16 failed for register '" + name_ + "'");
+            setValUInt16(val);
+            break;
+        }
+        case Int16:
+        {
+            int16_t val;
+            if(!StringUtilities::from_string<int16_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Int16 failed for register '" + name_ + "'");
+            setValInt16(val);
+            break;
+        }
+        case uInt32:
+        {
+            uint32_t val;
+            if(!StringUtilities::from_string<uint32_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to uInt32 failed for register '" + name_ + "'");
+            setValUInt32(val);
+            break;
+        }
+        case Int32:
+        {
+            int32_t val;
+            if(!StringUtilities::from_string<int32_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Int32 failed for register '" + name_ + "'");
+            setValInt32(val);
+            break;
+        }
+        case uInt64:
+        {
+            uint64_t val;
+            if(!StringUtilities::from_string<uint64_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to uInt64 failed for register '" + name_ + "'");
+            setValUInt64(val);
+            break;
+        }
+        case Int64:
+        {
+            int64_t val;
+            if(!StringUtilities::from_string<int64_t>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Int64 failed for register '" + name_ + "'");
+            setValInt64(val);
+            break;
+        }
+        case Float32:
+        {
+            float val;
+            if(!StringUtilities::from_string<float>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Float32 failed for register '" + name_ + "'");
+            setValFloat32(val);
+            break;
+        }
+        case Float64:
+        {
+            double val;
+            if(!StringUtilities::from_string<double>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Float64 failed for register '" + name_ + "'");
+            setValFloat64(val);
+            break;
+        }
+        case String:
+        {
+            setValString(stringValue);
+            break;
+        }
+        case Date:
+        {
+            double val;
+            if(!StringUtilities::from_string<double>(val, stringValue, std::dec))
+                throw SilecsException(__FILE__, __LINE__,"Conversion from string '" + stringValue + "'to Date failed for register '" + name_ + "'");
+            setValDate(val);
+            break;
+        }
+        default:
+            throw SilecsException(__FILE__, __LINE__, "Register '" + name_+ "' has a unknown format type");
+    }
+}
+
+
+
 std::string Register::getValAsString(void* pValue, unsigned long i, unsigned long j)
 {
     struct tm dscst;
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
index 2b0e2b6..3bc0838 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
@@ -1631,6 +1631,13 @@ public:
     bool isInitialized();
     /// @endcond
 
+    /*!
+     * \fn setScalarfromString
+     * \brief transformes the passed string to a register value
+     * \param stringValue a scalar value in string representation
+     */
+    void setScalarfromString(std::string stringValue);
+
     /// @cond
 protected:
     Register(Device* theDevice, ElementXML* registerNode);
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h
index 385600d..6ca5e0d 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h
@@ -44,6 +44,7 @@ public:
     static std::string toString(const void * ptr);
     static void toLower(std::string& str);
 
+    // TODO: Merge both fromString methods ( std::ios_base argument is anyhwo always the same )
     /*!
      * \brief transform a string into any integer-type
      * \param str the string to transform
@@ -51,6 +52,11 @@ public:
      */
     template <typename T> static void fromString(T& value, const std::string& str);
 
+    /**
+     * Convert from string to a generic numeric type
+     */
+    template <class T> static bool from_string(T& t,const std::string& s, std::ios_base& (*f)(std::ios_base&));
+
 };
 
 template <typename T>
@@ -65,6 +71,13 @@ inline void StringUtilities::fromString(T& value, const std::string& str)
     }
 }
 
+template <class T>
+inline bool StringUtilities::from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
+{
+    std::istringstream iss(s);
+    return !(iss >> f >> t).fail();
+}
+
 } // namespace
 
 #endif //_STRING_UTILITIES_H_
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
index 661c35e..d9f49b5 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
@@ -22,12 +22,6 @@ Contributors:
 extern silecsModule *mysilecs;
 extern std::string UserName;
 
-template <class T>bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
-{
-    std::istringstream iss(s);
-    return !(iss >> f >> t).fail();
-}
-
 diagnosticToolMainView::diagnosticToolMainView(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::diagnosticToolMainView)
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
index 33c11e5..108193a 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
@@ -13,19 +13,10 @@ Contributors:
 
 #include <silecs-diagnostic/silecsmodule.h>
 #include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
 
 extern std::string UserName;
 
-//---------------------------------------------------------------------------------
-// TODO: to move this to utility
-// remove then from diagnostictoolmainview as well!
-
-template <class T>bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
-{
-    std::istringstream iss(s);
-    return !(iss >> f >> t).fail();
-}
-//---------------------------------------------------------------------------------
 
 silecsModule::silecsModule(std::string logTopics, QTextBrowser *messageConsole):
 		messageConsole_(messageConsole), debugLoggingEnabled_(false)
@@ -246,204 +237,14 @@ void silecsModule::setScalarDataInDeviceFromItem(Item *currentItem, std::string
         }
 
         std::string stringValue = currentItem->child(registerIndex)->text(3).toStdString();
+        if(reg->isScalar()) //TODO: What happens for non-scalar values ?
+            reg->setScalarfromString(stringValue);
 
-        Silecs::FormatType format = reg->getFormat();
-
-        switch(format)
-        {
-            case uInt8:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "uInt8";
-                    //Casting to uint16 and later to uint 8 to avoid it being converted for his ASCII character
-                    uint16_t val;
-                    if(!from_string<uint16_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to unsigned uInt8 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
-                    }
-                    reg->setValUInt8((uint16_t)val);
-                }
-                break;
-            }
-
-            case Int8:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Int8";
-                    int8_t val;
-                    if(stringValue.length()!=1)
-                    {
-                        qDebug()<< "Conversion from string to Int8 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int8 ");
-                    }
-                    else
-                    {
-                        val = (int8_t)stringValue[0];
-                    }
-                    reg->setValInt8(val);
-                }
-                break;
-            }
-
-            case uInt16:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "uInt16";
-                    uint16_t val;
-                    if(!from_string<uint16_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to uInt16 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
-                    }
-                    reg->setValUInt16(val);
-                }
-                break;
-            }
-
-            case Int16:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Int16";
-                    int16_t val;
-                    if(!from_string<int16_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Int16 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
-                    }
-                    reg->setValInt16(val);
-                }
-                break;
-            }
-
-            case uInt32:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "uInt32";
-                    uint32_t val;
-                    if(!from_string<uint32_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to uInt32 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
-                    }
-                    reg->setValUInt32(val);
-                }
-                break;
-            }
-
-            case Int32:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Int32";
-                    int32_t val;
-                    if(!from_string<int32_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Int32 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
-                    }
-                    reg->setValInt32(val);
-                }
-                break;
-            }
-
-            case uInt64:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "uInt64";
-                    uint64_t val;
-                    if(!from_string<uint64_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to uInt64 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
-                    }
-                    reg->setValUInt64(val);
-                }
-                break;
-            }
-
-            case Int64:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Int64";
-                    int64_t val;
-                    if(!from_string<int64_t>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Int64 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
-                    }
-                    reg->setValInt64(val);
-                }
-                break;
-            }
-
-            case Float32:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Float32";
-                    float val;
-                    if(!from_string<float>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Float32 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
-                    }
-                    reg->setValFloat32(val);
-                }
-                break;
-            }
-
-            case Float64:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Float64";
-                    double val;
-                    if(!from_string<double>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Float64 failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
-                    }
-                    reg->setValFloat64(val);
-                }
-                break;
-            }
-            case String:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "String";
-                    reg->setValString(stringValue);
-                }
-                break;
-            }
-            case Date:
-            {
-                if(reg->isScalar())
-                {
-                    qDebug() << "Date";
-                    double val;
-                    if(!from_string<double>(val, stringValue, std::dec))
-                    {
-                        qDebug()<< "Conversion from string to Date failed";
-                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Date (Epoch value)");
-                    }
-                    reg->setValDate(val);
-                }
-                break;
-            }
-        }
     }while(registerListSplitted);
 }
 
 
+// FIXME TODO move to class 'Silecs::SilecsRegister', like done for 'setScalarfromString', so it can be reused internally ( e.g. default values for configuration fields )
 void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dataVector)
 {
     Silecs::Register* reg = (Silecs::Register*)currentItem->getLinkedObject();
@@ -469,7 +270,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
                         else
                             vector[i][j] = (uint8_t)val;
@@ -486,7 +287,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
                     else
                         vector[i] = (uint8_t)val;
@@ -544,7 +345,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
                         else
                             vector[i][j] = val;
@@ -560,7 +361,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
                     else
                         vector[i] = val;
@@ -582,7 +383,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<short>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<short>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
                         else
                             vector[i][j] = val;
@@ -598,7 +399,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<short>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<short>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
                     else
                         vector[i] = val;
@@ -620,7 +421,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<uint32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<uint32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
                         else
                             vector[i][j] = val;
@@ -636,7 +437,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<uint32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<uint32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
                     else
                         vector[i] = val;
@@ -658,7 +459,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<int32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<int32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
                         else
                             vector[i][j] = val;
@@ -674,7 +475,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<int32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<int32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
                     else
                         vector[i] = val;
@@ -696,7 +497,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<uint64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<uint64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
                         else
                             vector[i][j] = val;
@@ -712,7 +513,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<uint64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<uint64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
                     else
                         vector[i] = val;
@@ -734,7 +535,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<int64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<int64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
                         else
                             vector[i][j] = val;
@@ -750,7 +551,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<int64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<int64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
                     else
                         vector[i] = val;
@@ -772,7 +573,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<float>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<float>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
                         else
                             vector[i][j] = val;
@@ -788,7 +589,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<float>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<float>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
                     else
                         vector[i] = val;
@@ -810,7 +611,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<double>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<double>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
                         else
                             vector[i][j] = val;
@@ -826,7 +627,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<double>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<double>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
                     else
                         vector[i] = val;
@@ -883,7 +684,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                     for(unsigned long j=0; j<reg->getDimension2(); j++)
                     {
                         qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
-                        if(!from_string<double>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                        if(!StringUtilities::from_string<double>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
                             throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Date (Epoch value)");
                         else
                             vector[i][j] = val;
@@ -899,7 +700,7 @@ void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dat
                 for(unsigned long i=0;i<reg->getDimension1();i++)
                 {
                     qDebug() << QString((*dataVector)[i]);
-                    if(!from_string<double>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                    if(!StringUtilities::from_string<double>(val, QString((*dataVector)[i]).toStdString(), std::dec))
                         throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Date (Epoch value)");
                     else
                         vector[i] = val;
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h
index 69d95c2..b6bba2c 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h
@@ -84,6 +84,7 @@ public:
       * from the string present in the GUI
       * in case of error returns a string exception with the message
       */
+    // FIXME TODO move to class 'Silecs::SilecsRegister', like done for 'setScalarfromString', so it can be reused internally ( e.g. default values for configuration fields )
     void setArrayRegValue(Item *currentItem,std::vector<QString> *dataVector);
 
     /**
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp
index 1c52f32..8b68651 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp
@@ -108,12 +108,6 @@ char* Utils::chop(char *string)
     return newstring;
 }
 
-template<class T> bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
-{
-    std::istringstream iss(s);
-    return ! (iss >> f >> t).fail();
-}
-
 void Utils::displayClusterInformation(Silecs::Cluster *cluster, QTextEdit *console)
 {
     std::string text = "";
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h
index 5bacad4..b1dfc25 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h
@@ -78,11 +78,6 @@ namespace Utils {
      */
     char* chop(char *string);
 
-    /**
-     * Convert from string to a generic numeric type
-     */
-    template <class T>bool from_string(T& t,const std::string& s, std::ios_base& (*f)(std::ios_base&));
-
     /**
      * Display information about the cluster in the given console
      */
-- 
GitLab