json_parser_utils: Add parseUint16

Add new parseUint16() function to the json_parser_utils namespace. The
function parses a uint16_t value within a JSON element.

Tested:
* Ran automated test cases.

Change-Id: Id7c7c63f7a944a1910818927c3c70cb579f07dbd
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/json_parser_utils.cpp b/json_parser_utils.cpp
index 25b2e9a..78064fd 100644
--- a/json_parser_utils.cpp
+++ b/json_parser_utils.cpp
@@ -186,6 +186,17 @@
     return static_cast<uint8_t>(value);
 }
 
+uint16_t parseUint16(const nlohmann::json& element,
+                     const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if ((value < 0) || (value > UINT16_MAX))
+    {
+        throw std::invalid_argument{"Element is not a 16-bit unsigned integer"};
+    }
+    return static_cast<uint16_t>(value);
+}
+
 unsigned int parseUnsignedInteger(
     const nlohmann::json& element,
     const std::map<std::string, std::string>& variables)
diff --git a/json_parser_utils.hpp b/json_parser_utils.hpp
index 06ac19f..fa5e5c9 100644
--- a/json_parser_utils.hpp
+++ b/json_parser_utils.hpp
@@ -229,6 +229,21 @@
     const std::map<std::string, std::string>& variables = NO_VARIABLES);
 
 /**
+ * Parses a JSON element containing a 16-bit unsigned integer.
+ *
+ * Returns the corresponding C++ uint16_t value.
+ *
+ * Throws an exception if parsing fails.
+ *
+ * @param element JSON element
+ * @param variables variables map used to expand variables in element value
+ * @return uint16_t value
+ */
+uint16_t parseUint16(
+    const nlohmann::json& element,
+    const std::map<std::string, std::string>& variables = NO_VARIABLES);
+
+/**
  * Parses a JSON element containing an unsigned integer.
  *
  * Returns the corresponding C++ unsigned int value.
diff --git a/test/json_parser_utils_tests.cpp b/test/json_parser_utils_tests.cpp
index af49977..4660aa0 100644
--- a/test/json_parser_utils_tests.cpp
+++ b/test/json_parser_utils_tests.cpp
@@ -927,6 +927,80 @@
     }
 }
 
+TEST(JSONParserUtilsTests, ParseUint16)
+{
+    // Test where works: 0
+    {
+        const json element = R"( 0 )"_json;
+        uint16_t value = parseUint16(element);
+        EXPECT_EQ(value, 0);
+    }
+
+    // Test where works: UINT16_MAX
+    {
+        const json element = R"( 65535 )"_json;
+        uint16_t value = parseUint16(element);
+        EXPECT_EQ(value, 65535);
+    }
+
+    // Test where works: Variable specified
+    {
+        std::map<std::string, std::string> variables{{"var", "24699"}};
+        const json element = R"( "${var}" )"_json;
+        uint16_t value = parseUint16(element, variables);
+        EXPECT_EQ(value, 24699);
+    }
+
+    // Test where fails: Element is not an integer
+    try
+    {
+        const json element = R"( 1.03 )"_json;
+        parseUint16(element);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not an integer");
+    }
+
+    // Test where fails: Value < 0
+    try
+    {
+        const json element = R"( -1 )"_json;
+        parseUint16(element);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
+    }
+
+    // Test where fails: Value > UINT16_MAX
+    try
+    {
+        const json element = R"( 65536 )"_json;
+        parseUint16(element);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
+    }
+
+    // Test where fails: Variable specified: Value > UINT16_MAX
+    try
+    {
+        std::map<std::string, std::string> variables{{"var", "65536"}};
+        const json element = R"( "${var}" )"_json;
+        parseUint16(element, variables);
+        ADD_FAILURE() << "Should not have reached this line.";
+    }
+    catch (const std::invalid_argument& e)
+    {
+        EXPECT_STREQ(e.what(), "Element is not a 16-bit unsigned integer");
+    }
+}
+
 TEST(JSONParserUtilsTests, ParseUnsignedInteger)
 {
     // Test where works: 1