From fd77363f184631ddf6012591612d8b50ac12a005 Mon Sep 17 00:00:00 2001
From: Grigoris Pavlakis <grigpavl@ece.auth.gr>
Date: Sun, 15 Mar 2020 00:21:38 +0200
Subject: [PATCH] Add warning for the Parameter setter's type safety

---
 CMakeLists.txt                |  1 -
 inc/Parameters/Parameters.hpp |  5 +++
 inc/Services/Parameter.hpp    | 69 ++++++++++++++---------------------
 src/Services/Parameter.cpp    |  1 -
 4 files changed, 32 insertions(+), 44 deletions(-)
 create mode 100644 inc/Parameters/Parameters.hpp
 delete mode 100644 src/Services/Parameter.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d75c7315..d56b1c4e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,6 @@ add_library(common OBJECT
         src/Helpers/TimeHelper.cpp
         src/Services/EventReportService.cpp
         src/Services/MemoryManagementService.cpp
-        src/Services/Parameter.cpp
         src/Services/ParameterService.cpp
         src/Services/RequestVerificationService.cpp
         src/Services/TestService.cpp
diff --git a/inc/Parameters/Parameters.hpp b/inc/Parameters/Parameters.hpp
new file mode 100644
index 00000000..d225fbfa
--- /dev/null
+++ b/inc/Parameters/Parameters.hpp
@@ -0,0 +1,5 @@
+#include "Services/Parameter.hpp"
+
+namespace SystemParameters {
+    // initialize all system parameters here
+}
\ No newline at end of file
diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp
index 2587008d..20b8e8c5 100644
--- a/inc/Services/Parameter.hpp
+++ b/inc/Services/Parameter.hpp
@@ -9,76 +9,61 @@
  * Fully compliant with the standard's requirements.
  *
  * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
+ * @author Athanasios Theocharis <athatheo@csd.auth.gr>
+ * 
+ * 
+ * The Parameter class implements a way of storing and updating system parameters
+ * of arbitrary size and type, while avoiding std::any and dynamic memory allocation.
+ * 
+ * It is split in two parts: an abstract ParameterBase class which contains the setter,
+ * and a 
  */
 
 /**
  * Useful type definitions
- *
+ * (DEPRECATED - MARK FOR REMOVAL)
  * @typedef ParamId: the unique ID of a parameter, used for searching
  */
 typedef uint16_t ParamId;
 
-/**
- * Parameter class - Breakdown of fields
+/*
+ * MILLION DOLLAR QUESTIONS:
+ * setCurrentValue is templated. Since Parameter (a template class) inherits ParameterBase
+ * (a class containing a template member), does a specialization of Parameter also specialize
+ * setCurrentValue? If not, we have a problem, since Parameter won't necessarily specialize
+ * setCurrentValue with the correct type => our setter is *not* typesafe.
  *
- * @private ptr: Pointer of the function that will update the parameter
- * @private currentValue: The current (as in last good) value of the parameter
+ * Answer: NO! After a discussion on ##C++-general@Freenode, it turns out that this specialization
+ * does not happen! What this means is that, while a Parameter can be specialized as e.g. int, there
+ * is no way to prevent the setter from being called with a non-int (e.g. string or float) argument,
+ * resulting in an attempt to write data inside the Parameter that have a different type from what the
+ * template is carrying.
  *
+ * Proof of concept:
+ *      Parameter<int> ircTest = Parameter<int>(1337);
+ *		ircTest.setCurrentValue("Hello this is a problem speaking");
+ *		auto s = ircTest.getValueAsString();
  *
+ * This snippet will overwrite the 4 bytes of the Parameter field with garbage and most importantly,
+ * it will do so silently.
  *
- * Methods:
- * @public Parameter(uint32_t initialValue = 0, UpdatePtr newPtr = nullptr):
- * Create a new Parameter object with initialValue as its starting value and newPtr
- * as its update function pointer. Arguments initialValue and newPtr are optional, and have default values of
- * 0 and nullptr respectively.
  *
- * @public setCurrentValue(): Changes the current value of the parameter
- * @public getCurrentValue(): Gets the current value of the parameter
  */
 
-// class DataField {
-// protected:
-// 	uint8_t sizeInBytes;
-// 	void* dataFieldAddress;
-// 	// possible race: setCurrentValue may be ran when dataFieldAddress is uninitialized
-// public:
-// 	template <typename DataType>
-// 	void setCurrentValue(DataType newValue) {
-// 		DataType* typedDataFieldAddress = reinterpret_cast<DataType*>(dataFieldAddress);
-// 		*typedDataFieldAddress = newValue;
-// 	}
-// };
-
-/**
- * Highly likely that valuePtr is redundant! Then, ParameterBase could only contain
- * virtual methods and act as a mere interface, moving all specific functionality to
- * the Parameter class and ensuring type safety.
- */ 
-
 class ParameterBase {
 protected:
 	uint8_t sizeInBytes;
-	void* valuePtr = nullptr;
+	void* valuePtr;
 public:
 
 	virtual String<ECSS_ST_20_MAX_STRING_LENGTH> getValueAsString() = 0;
 
 	template <typename ValueType>
 	void setCurrentValue(ValueType newVal) {
-		if (valuePtr == nullptr) {
-			std::cout << "THIS IS NULL!" << std::endl;
-		}
 		*reinterpret_cast<ValueType*>(valuePtr) = newVal;
 	}
 };
 
-/**
- * MILLION DOLLAR QUESTIONS:
- * setCurrentValue is templated. Since Parameter (a template class) inherits ParameterBase
- * (a class containing a template member), does a specialization of Parameter also specialize
- * setCurrentValue? If not, we have a problem, since Parameter won't necessarily specialize
- * setCurrentValue with the correct type => our setter is *not* typesafe.
- */
 
 template <typename ValueType>
 class Parameter : public ParameterBase {
diff --git a/src/Services/Parameter.cpp b/src/Services/Parameter.cpp
deleted file mode 100644
index 526f4d6e..00000000
--- a/src/Services/Parameter.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "Services/Parameter.hpp"
-- 
GitLab