[gstreamermm] Gst::Iterator: fix iterator build



commit 2a195b23bda7fef980a2dd00aedd9f1decab7a89
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Sun Jul 2 13:48:29 2017 +0100

    Gst::Iterator: fix iterator build
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783678

 .gitignore                |    1 +
 gstreamer/src/iterator.hg |   63 ++++++++++++++++++++++-----------------------
 tests/Makefile.am         |    2 +
 tests/test-iterator.cc    |   62 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+), 32 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index a808800..1e54c80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -551,6 +551,7 @@ tests/test-capsfeatures
 tests/test-element
 tests/test-ghostpad
 tests/test-init
+tests/test-iterator
 tests/test-memory
 tests/test-message
 tests/test-miniobject
diff --git a/gstreamer/src/iterator.hg b/gstreamer/src/iterator.hg
index 6f10417..f76c34d 100644
--- a/gstreamer/src/iterator.hg
+++ b/gstreamer/src/iterator.hg
@@ -125,9 +125,6 @@ private:
   GstIterator* cobject_;    // The underlying  C object.
   bool take_ownership;      // Whether to destroy C object with the wrapper.
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-private:
-  void swap(IteratorBase<CppType>& other);
 };
 
 /**  A class used to retrieve multiple elements in a thread safe way.
@@ -243,18 +240,25 @@ template<class CppType>
 IteratorBase<CppType>::IteratorBase()
 : current(G_VALUE_INIT),
   current_result(Gst::ITERATOR_OK),
-  cobject_(0),
+  cobject_(nullptr),
   take_ownership(true)
 {
 }
 
 template<class CppType>
 IteratorBase<CppType>::IteratorBase(const IteratorBase<CppType>& other)
-  : current(other.current),
+  : current(G_VALUE_INIT),
     current_result(other.current_result),
-    cobject_(const_cast<GstIterator*>(other.cobj())),
-    take_ownership((other.cobj()) ? false : true)
-{}
+    take_ownership(other.take_ownership)
+{
+  cobject_ = other.take_ownership ? gst_iterator_copy(other.cobject_) : other.cobject_;
+
+  if (G_IS_VALUE (&other.current))
+  {
+    g_value_init(&current, G_VALUE_TYPE(&other.current));
+    g_value_copy(&other.current, &current);
+  }
+}
 
 template<class CppType>
 IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool take_ownership)
@@ -267,8 +271,25 @@ IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool take_ownership)
 template<class CppType>
 IteratorBase<CppType>& IteratorBase<CppType>::operator=(const IteratorBase<CppType>& other)
 {
-  IteratorBase temp(other);
-  swap(temp);
+  if (cobject_ && take_ownership)
+  {
+    gst_iterator_free(cobject_);
+  }
+
+  if (G_IS_VALUE(&current))
+  {
+    g_value_unset(&current);
+  }
+
+  current_result = other.current_result;
+  cobject_ = other.take_ownership ? gst_iterator_copy(other.cobject_) : other.cobject_;
+
+  if (G_IS_VALUE (&other.current))
+  {
+    g_value_init(&current, G_VALUE_TYPE(&other.current));
+    g_value_copy(&other.current, &current);
+  }
+
   return *this;
 }
 
@@ -315,28 +336,6 @@ IteratorBase<CppType>::operator bool() const
   return (! G_VALUE_HOLDS_OBJECT(&current));
 }
 
-template<class CppType>
-void IteratorBase<CppType>::swap(IteratorBase<CppType>& other)
-{
-  GstIterator *const temp_obj = cobject_;
-  cobject_ = other.cobject_;
-  other.cobject_ = temp_obj;
-
-  const bool temp_take_ownership = take_ownership;
-  take_ownership = other.take_ownership;
-  other.take_ownership = temp_take_ownership;
-
-  GValue temp_current = G_VALUE_INIT;
-  g_value_init(&temp_current, G_VALUE_TYPE(current));
-  g_value_copy(&current, &temp_current);
-  g_value_copy(other.current, &current);
-  g_value_copy(&temp_current, other.current);
-
-  const IteratorResult temp_result = current_result;
-  current_result = other.current_result;
-  other.current_result = temp_result;
-}
-
 //virtual
 template<class CppType>
 IteratorBase<CppType>::~IteratorBase()
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c734b62..1d931a9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -31,6 +31,7 @@ check_PROGRAMS =                                \
         test-element                            \
         test-ghostpad                           \
         test-init                               \
+        test-iterator                           \
         test-memory                             \
         test-message                            \
         test-miniobject                         \
@@ -74,6 +75,7 @@ test_caps_SOURCES                               = $(TEST_GTEST_SOURCES) test-cap
 test_element_SOURCES                            = $(TEST_GTEST_SOURCES) test-element.cc
 test_ghostpad_SOURCES                           = $(TEST_GTEST_SOURCES) test-ghostpad.cc
 test_init_SOURCES                               = $(TEST_GTEST_SOURCES) test-init.cc
+test_iterator_SOURCES                           = $(TEST_GTEST_SOURCES) test-iterator.cc
 test_memory_SOURCES                             = $(TEST_GTEST_SOURCES) test-memory.cc
 test_message_SOURCES                            = $(TEST_GTEST_SOURCES) test-message.cc
 test_miniobject_SOURCES                         = $(TEST_GTEST_SOURCES) test-miniobject.cc
diff --git a/tests/test-iterator.cc b/tests/test-iterator.cc
new file mode 100644
index 0000000..0a90a5b
--- /dev/null
+++ b/tests/test-iterator.cc
@@ -0,0 +1,62 @@
+#include "mmtest.h"
+#include <gstreamermm.h>
+
+using namespace Gst;
+using Glib::RefPtr;
+
+TEST(IteratorTest, AssignmentOperatorShouldCopyIterator)
+{
+  Glib::RefPtr<Gst::Element> element = Gst::ElementFactory::create_element("fakesink");
+
+  Gst::Iterator<Gst::Pad> iter = element->iterate_pads();
+  Gst::Iterator<Gst::Pad> iter2;
+  iter2 = iter;
+
+  while (iter.next())
+  {
+    ASSERT_STREQ("sink", iter->get_name().c_str());
+  }
+
+  while(iter2.next())
+  {
+    ASSERT_STREQ("sink", iter2->get_name().c_str());
+  }
+}
+
+
+TEST(IteratorTest, BeginShouldResetIterator)
+{
+  Glib::RefPtr<Gst::Element> element = Gst::ElementFactory::create_element("fakesink");
+
+  Gst::Iterator<Gst::Pad> iter = element->iterate_pads();
+  
+  while (iter.next())
+  {
+    ASSERT_STREQ("sink", iter->get_name().c_str());
+  }
+
+  iter.begin();
+  while (iter.next())
+  {
+    ASSERT_STREQ("sink", iter->get_name().c_str());
+  }
+}
+
+TEST(IteratorTest, CopyConstructorShouldCopyIteratorAndItsState)
+{
+  Glib::RefPtr<Gst::Element> element = Gst::ElementFactory::create_element("fakesink");
+
+  Gst::Iterator<Gst::Pad> iter = element->iterate_pads();
+
+  while (iter.next())
+  {
+    ASSERT_STREQ("sink", iter->get_name().c_str());
+  }
+
+  ASSERT_FALSE(iter.next());
+
+  Gst::Iterator<Gst::Pad> iter2 = iter;
+
+  ASSERT_FALSE(iter.next());
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]