From 56d8c9e0966563ea5b5a7dd47c42b03d5e2546f7 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Wed, 3 Mar 2021 14:20:07 +0100
Subject: [PATCH] Throw an exception in `contains()` if IDs are not well
 defined

---
 .../libraries/armem/core/MemoryID.cpp         | 25 +++++++++++++------
 .../armem/test/ArMemMemoryIDTest.cpp          |  7 +++---
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/source/RobotAPI/libraries/armem/core/MemoryID.cpp b/source/RobotAPI/libraries/armem/core/MemoryID.cpp
index 161b20f8c..61dd4836c 100644
--- a/source/RobotAPI/libraries/armem/core/MemoryID.cpp
+++ b/source/RobotAPI/libraries/armem/core/MemoryID.cpp
@@ -111,18 +111,16 @@ namespace armarx::armem
     bool MemoryID::hasGap() const
     {
         bool emptyFound = false;
-        for (const std::string& name : getAllItems())
+        for (const std::string& item : getAllItems())
         {
-            if (name.empty())
+            if (item.empty())
             {
                 emptyFound = true;
             }
-            else
+            else if (emptyFound)
             {
-                if (emptyFound)
-                {
-                    return true;
-                }
+                // Found a non-empty item after an empty item.
+                return true;
             }
         }
         return false;
@@ -417,6 +415,19 @@ namespace armarx::armem
 
     bool contains(const MemoryID& general, const MemoryID& specific)
     {
+        if (!general.isWellDefined())
+        {
+            std::stringstream ss;
+            ss << "ID `general` is not well-defined, which is required for `" << __FUNCTION__ << "()`.";
+            throw error::InvalidMemoryID(general, ss.str());
+        }
+        if (!specific.isWellDefined())
+        {
+            std::stringstream ss;
+            ss << "ID `specific` is not well-defined, which is required for `" << __FUNCTION__ << "()`.";
+            throw error::InvalidMemoryID(specific, ss.str());
+        }
+
         if (general.memoryName.empty())
         {
             return true;
diff --git a/source/RobotAPI/libraries/armem/test/ArMemMemoryIDTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemMemoryIDTest.cpp
index 79dada270..1f94d9adb 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemMemoryIDTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemMemoryIDTest.cpp
@@ -26,6 +26,7 @@
 
 #include <RobotAPI/Test.h>
 #include "../core/MemoryID.h"
+#include "../core/error.h"
 
 #include <iostream>
 
@@ -80,13 +81,13 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_contains)
         BOOST_CHECK(not armem::contains(specific, general));
     }
 
-    // with a gap - lower levels are ignored
+    // Not well-defined ID - throw an exception.
     specific.coreSegmentName.clear();
 
     BOOST_TEST_CONTEXT(VAROUT(general) << " | " << VAROUT(specific))
     {
-        BOOST_CHECK(armem::contains(general, specific));
-        BOOST_CHECK(armem::contains(specific, general));
+        BOOST_CHECK_THROW(armem::contains(general, specific), armem::error::InvalidMemoryID);
+        BOOST_CHECK_THROW(armem::contains(specific, general), armem::error::InvalidMemoryID);
     }
 }
 
-- 
GitLab