From 84ef13de8a1ae9e161791c828288bb0fc501a949 Mon Sep 17 00:00:00 2001
From: Steven Murray <Steven.Murray@cern.ch>
Date: Wed, 4 Dec 2019 18:12:58 +0100
Subject: [PATCH] Added utils::toUint32()

---
 common/utils/UtilsTest.cpp | 45 ++++++++++++++++++++++++++++++++++++++
 common/utils/utils.cpp     | 36 ++++++++++++++++++++++++++++++
 common/utils/utils.hpp     |  8 +++++++
 3 files changed, 89 insertions(+)

diff --git a/common/utils/UtilsTest.cpp b/common/utils/UtilsTest.cpp
index 8cecc84d34..762235cb7b 100644
--- a/common/utils/UtilsTest.cpp
+++ b/common/utils/UtilsTest.cpp
@@ -321,6 +321,51 @@ TEST_F(cta_UtilsTest, toUint16_too_big) {
   ASSERT_THROW(utils::toUint16("65536"), std::exception);
 }
 
+TEST_F(cta_UtilsTest, toUint32_12345) {
+  using namespace cta;
+
+  uint32_t i = 0;
+
+  ASSERT_NO_THROW(i = utils::toUint32("12345"));
+  ASSERT_EQ((uint32_t)12345, i);
+}
+
+TEST_F(cta_UtilsTest, toUint32_zero) {
+  using namespace cta;
+
+  uint32_t i = 0;
+
+  ASSERT_NO_THROW(i = utils::toUint32("0"));
+  ASSERT_EQ((uint32_t)0, i);
+}
+
+TEST_F(cta_UtilsTest, toUint32_4294967295) {
+  using namespace cta;
+
+  uint32_t i = 0;
+
+  ASSERT_NO_THROW(i = utils::toUint32("4294967295"));
+  ASSERT_EQ((uint32_t)4294967295, i);
+}
+
+TEST_F(cta_UtilsTest, toUint32_empty_string) {
+  using namespace cta;
+
+  ASSERT_THROW(utils::toUint32(""), std::exception);
+}
+
+TEST_F(cta_UtilsTest, toUint32_negative) {
+  using namespace cta;
+
+  ASSERT_THROW(utils::toUint32("-12345"), std::exception);
+}
+
+TEST_F(cta_UtilsTest, toUint32_too_big) {
+  using namespace cta;
+
+  ASSERT_THROW(utils::toUint32("4294967296"), std::exception);
+}
+
 TEST_F(cta_UtilsTest, toUid_12345) {
   using namespace cta;
 
diff --git a/common/utils/utils.cpp b/common/utils/utils.cpp
index 441f3c3b59..5d6ca059b4 100644
--- a/common/utils/utils.cpp
+++ b/common/utils/utils.cpp
@@ -524,6 +524,42 @@ uint16_t toUint16(const std::string &str) {
   return value;
 }
 
+//------------------------------------------------------------------------------
+// toUint32
+//------------------------------------------------------------------------------
+uint32_t toUint32(const std::string &str) {
+  if(str.empty()) {
+    std::ostringstream msg;
+    msg << "Failed to convert empty string to uint32_t: An empty string is not"
+           " a valid unsigned integer";
+    throw exception::Exception(msg.str());
+  }
+
+  errno = 0;
+  const long int value = strtol(str.c_str(), (char **) NULL, 10);
+  const int savedErrno = errno;
+  if(savedErrno) {
+    std::ostringstream msg;
+    msg << "Failed to convert \'" << str << "' to uint32_t: " <<
+      errnoToString(savedErrno);
+    throw exception::Exception(msg.str());
+  }
+
+  if(0 > value) {
+    std::ostringstream msg;
+    msg << "Failed to convert \'" << str << "' to uint32_t: Negative number";
+    throw exception::Exception(msg.str());
+  }
+
+  if(4294967295 < value) {
+    std::ostringstream msg;
+    msg << "Failed to convert \'" << str << "' to uint32_t: Number too big";
+    throw exception::Exception(msg.str());
+  }
+
+  return value;
+}
+
 //------------------------------------------------------------------------------
 // toUid
 //------------------------------------------------------------------------------
diff --git a/common/utils/utils.hpp b/common/utils/utils.hpp
index a0d0afa2f9..000aa85524 100644
--- a/common/utils/utils.hpp
+++ b/common/utils/utils.hpp
@@ -247,6 +247,14 @@ namespace utils {
    */
   uint16_t toUint16(const std::string &str);
 
+  /**
+   * Converts the specified string to an unsigned integer.
+   *
+   * @param str The string.
+   * @return The unsigned integer.
+   */
+  uint32_t toUint32(const std::string &str);
+
   /**
    * Converts the specified string to a uid.
    *
-- 
GitLab