added method remove() to iterators
authorVictor Kirhenshtein <victor@netxms.org>
Fri, 15 Jan 2016 12:20:23 +0000 (14:20 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Fri, 15 Jan 2016 12:20:23 +0000 (14:20 +0200)
include/nms_util.h
src/libnetxms/array.cpp
src/libnetxms/hashmapbase.cpp
tests/test-libnetxms/test-libnetxms.cpp

index 8c93d03..5be0a6f 100644 (file)
@@ -362,6 +362,7 @@ public:
 
    virtual bool hasNext() = 0;
    virtual void *next() = 0;
+   virtual void remove() = 0;
 };
 
 /**
@@ -378,6 +379,7 @@ public:
 
    bool hasNext() { return m_worker->hasNext(); }
    T *next() { return (T *)m_worker->next(); }
+   void remove() { m_worker->remove(); }
 };
 
 /**
@@ -432,14 +434,15 @@ public:
 class LIBNETXMS_EXPORTABLE ArrayIterator : public AbstractIterator
 {
 private:
-   const Array *m_array;
+   Array *m_array;
    int m_pos;
 
 public:
-   ArrayIterator(const Array *array);
+   ArrayIterator(Array *array);
 
    virtual bool hasNext();
    virtual void *next();
+   virtual void remove();
 };
 
 /**
@@ -465,7 +468,7 @@ public:
        void unlink(int index) { Array::unlink(index); }
    void unlink(T *object) { Array::unlink((void *)object); }
 
-   Iterator<T> *iterator() const { return new Iterator<T>(new ArrayIterator(this)); }
+   Iterator<T> *iterator() { return new Iterator<T>(new ArrayIterator(this)); }
 };
 
 /**
@@ -760,6 +763,7 @@ public:
 
    virtual bool hasNext();
    virtual void *next();
+   virtual void remove();
 };
 
 /**
index 77587a9..4f1eb1c 100644 (file)
@@ -233,7 +233,7 @@ void *Array::find(const void *key, int (*cb)(const void *, const void *)) const
 /**
  * Array iterator
  */
-ArrayIterator::ArrayIterator(const Array *array)
+ArrayIterator::ArrayIterator(Array *array)
 {
    m_array = array;
    m_pos = -1;
@@ -258,3 +258,15 @@ void *ArrayIterator::next()
    m_pos++;
    return m_array->get(m_pos);
 }
+
+/**
+ * Remove current element
+ */
+void ArrayIterator::remove()
+{
+   if (((m_pos + 1) >= m_array->size()) || (m_pos < 0))
+      return;
+
+   m_array->remove(m_pos);
+   m_pos--;
+}
index 5ece01c..f491726 100644 (file)
@@ -41,7 +41,7 @@ struct HashMapEntry
 /**
  * Delete key
  */
-#define DELETE_KEY(e) do { if (m_keylen > 16) free(e->key.p); } while(0)
+#define DELETE_KEY(m, e) do { if ((m)->m_keylen > 16) free((e)->key.p); } while(0)
 
 /**
  * Get pointer to key
@@ -84,7 +84,7 @@ void HashMapBase::clear()
    HASH_ITER(hh, m_data, entry, tmp)
    {
       HASH_DEL(m_data, entry);
-      DELETE_KEY(entry);
+      DELETE_KEY(this, entry);
       destroyObject(entry->value);
       free(entry);
    }
@@ -150,7 +150,7 @@ void HashMapBase::_remove(const void *key)
    if (entry != NULL)
    {
       HASH_DEL(m_data, entry);
-      DELETE_KEY(entry);
+      DELETE_KEY(this, entry);
                if (m_objectOwner)
          destroyObject(entry->value);
       free(entry);
@@ -244,3 +244,18 @@ void *HashMapIterator::next()
    }
    return m_curr->value;
 }
+
+/**
+ * Remove current element
+ */
+void HashMapIterator::remove()
+{
+   if (m_curr == NULL)
+      return;
+
+   HASH_DEL(m_hashMap->m_data, m_curr);
+   DELETE_KEY(m_hashMap, m_curr);
+   if (m_hashMap->m_objectOwner)
+      m_hashMap->destroyObject(m_curr->value);
+   free(m_curr);
+}
index 5bd23d5..ff881a7 100644 (file)
@@ -460,6 +460,23 @@ static void TestHashMap()
    delete it;
    EndTest();
 
+   StartTest(_T("HashMap: iterator remove"));
+   it = hashMap->iterator();
+   AssertTrue(it->hasNext());
+   AssertNotNull(it->next());
+   s = it->next();
+   AssertNotNull(s);
+   it->remove();
+   AssertTrue(it->hasNext());
+   AssertNotNull(it->next());
+   AssertFalse(it->hasNext());
+   AssertNull(it->next());
+   delete it;
+   AssertNotNull(hashMap->get(k1));
+   AssertNull(hashMap->get(k2));
+   AssertNotNull(hashMap->get(k3));
+   EndTest();
+
    StartTest(_T("HashMap: remove"));
    hashMap->remove(k3);
    AssertNull(hashMap->get(k3));