[gstreamermm] Gst::Structure: add methods for getting/setting all datatypes in structure



commit 6790ec0fd83260896e8c71b1f7e9714a8a00b0be
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Thu Sep 17 08:11:05 2015 +0000

    Gst::Structure: add methods for getting/setting all datatypes in structure
    
        * gstreamer/src/structure.hg: overload methods add_field() and
          get_field() to be able accept all data types. If data type is not
          registred as GType, it is done automatically.
        * tests/test-structure.cc: add tests for new methods.

 gstreamer/src/structure.hg |  110 ++++++++++++++++++++++++++++++++++++++-----
 tests/test-structure.cc    |   18 +++++++
 2 files changed, 115 insertions(+), 13 deletions(-)
---
diff --git a/gstreamer/src/structure.hg b/gstreamer/src/structure.hg
index 47ffa52..642dd86 100644
--- a/gstreamer/src/structure.hg
+++ b/gstreamer/src/structure.hg
@@ -71,18 +71,7 @@ public:
    * should be passed as field name and value
    */
   template<class ...DataTypes>
-  explicit Structure(const Glib::ustring &name, DataTypes... data)
-  {
-    gobject_ = gst_structure_new_empty(name.c_str());
-    set_fields(data...);
-  }
-
-  template<class DataType, class ...DataTypes>
-  void set_fields(const Glib::ustring & name, const DataType& data, DataTypes ...further_data)
-  {
-    this->set_field(name, data);
-    this->set_fields(further_data...);
-  }
+  explicit Structure(const Glib::ustring &name, DataTypes... data);
 
   /** Creates a Gst::Structure from a string representation.
    *
@@ -109,6 +98,14 @@ public:
    */
   void get_field(const Glib::ustring& fieldname, Glib::ValueBase& value) const;
 
+  /** Get the value of the field with name @fieldname.
+   *
+   * @param fieldname The name of the field to get.
+   * @param value The Value class in which to store the value.
+   */
+  template<typename DataType>
+  void get_field(const Glib::ustring& fieldname, Glib::Value<DataType>& value) const;
+
   // These are ignored because they are useful in the C API but are either
   // variable argument functions or their functionality is already provided.
   _IGNORE(gst_structure_id_get_value,
@@ -132,6 +129,26 @@ public:
     gst_structure_set_valist
   )
 
+  /** Sets the field with name @fieldname to value. If the field does not
+   * exist, it is created. If the field exists, the previous value is replaced
+   * and freed.
+   *
+   * @param fieldname The name of the field to set.
+   * @param value The value to set the field to.
+   */
+  template<typename DataType>
+  void set_field(const Glib::ustring& fieldname, const Glib::Value<DataType>& value);
+
+  /** Sets the fields with name @fieldname to values. If one of the fields does not
+   * exist, it is created. If the field exists, the previous value is replaced
+   * and freed.
+   *
+   * @param fieldname The name of the field to set.
+   * @param value The value to set the field to.
+   */
+  template<class DataType, class ...DataTypes>
+  void set_fields(const Glib::ustring & fieldname, const DataType& value, DataTypes ...further_data);
+
   /** Sets the field with name @a fieldname to the boolean @a value. If the
    * field does not exist, it is created. If the field exists, the previous
    * value is replaced and freed.
@@ -298,6 +315,20 @@ public:
    */
   void set_field(const Glib::ustring& fieldname, const Gst::FractionRange& value);
 
+  /** Sets the field with name @fieldname field to the DataType @value.
+   * If the field does not exist, it is created. If the field exists,
+   * the previous value is replaced and freed. Please note that when setting
+   * fields to special types such as Gst::Fourcc and Gst::Fraction and
+   * Glib::Date they are converted to the GStreamer GTypes and thus when
+   * attempting to get these fields back as GValues, they will have the
+   * GStreamer GType.
+   *
+   * @param fieldname The name of the field to set.
+   * @param value The value to set the field to.
+   */
+  template<typename DataType>
+  void set_field(const Glib::ustring& fieldname, const DataType& value);
+
   // These take ownership of the GValue so they are not wrapped.
   _IGNORE(gst_structure_take_value, gst_structure_id_take_value)
 
@@ -538,6 +569,16 @@ public:
    */
   bool get_field(const Glib::ustring& fieldname, Gst::FractionRange& value) const;
 
+  /** Gets the value of field @a fieldname into DataType @value.
+   * The caller is responsible for making sure the field exists and has the
+   * correct type.
+   *
+   * @param fieldname The name of a field.
+   * @param value The DataType to set.
+   */
+  template<typename DataType>
+  void get_field(const Glib::ustring& fieldname, DataType& value) const;
+
   /** For example,
    * bool on_map(const Glib::ustring& id, Glib::ValueBase& value);.
    * The map function should return true if the map operation should continue,
@@ -591,8 +632,51 @@ public:
 private:
   // This method is used for varadic template recursion
   void set_fields() {}
+};
 
+template<class ...DataTypes>
+Structure::Structure(const Glib::ustring &name, DataTypes... data)
+{
+  gobject_ = gst_structure_new_empty(name.c_str());
+  set_fields(data...);
+}
 
-};
+template<class DataType, class ...DataTypes>
+void Structure::set_fields(const Glib::ustring & name, const DataType& data, DataTypes ...further_data)
+{
+  this->set_field(name, data);
+  this->set_fields(further_data...);
+}
+
+template<typename DataType>
+void Structure::get_field(const Glib::ustring& fieldname, DataType& value) const
+{
+  typedef Glib::Value<DataType> ValueType;
+  ValueType v;
+  this->get_field(fieldname, reinterpret_cast<Glib::ValueBase&>(v));
+  value = v.get();
+}
+
+template<typename DataType>
+void Structure::set_field(const Glib::ustring& fieldname, const DataType& value)
+{
+  typedef Glib::Value<DataType> ValueType;
+  ValueType v;
+  v.init(ValueType::value_type());
+  v.set(value);
+  this->set_field(fieldname, reinterpret_cast<const Glib::ValueBase&>(v));
+}
+
+template<typename DataType>
+void Structure::get_field(const Glib::ustring& fieldname, Glib::Value<DataType>& value) const
+{
+  get_field(fieldname, reinterpret_cast<Glib::ValueBase&>(value));
+}
+
+template<typename DataType>
+void Structure::set_field(const Glib::ustring& fieldname, const Glib::Value<DataType>& value)
+{
+  set_field(fieldname, reinterpret_cast<const Glib::Value<DataType>&>(value));
+}
 
 } //namespace Gst
diff --git a/tests/test-structure.cc b/tests/test-structure.cc
index 0594d60..2b11873 100644
--- a/tests/test-structure.cc
+++ b/tests/test-structure.cc
@@ -109,3 +109,21 @@ TEST_F(StructureTest, CreateStructureFromFieldsList)
   CheckGetField(Glib::ustring("sample string"), "field1");
   CheckGetField(12, "field2");
 }
+
+struct StructureTestStruct
+{
+  int x = 0;
+  StructureTestStruct(int x) : x(x) {}
+  StructureTestStruct() {}
+};
+
+TEST_F(StructureTest, CreateStructureWithCustomFields)
+{
+  structure = Structure("first", "field1", StructureTestStruct(14), "field2", StructureTestStruct(85));
+  StructureTestStruct d1;
+  Glib::Value<StructureTestStruct> d2;
+  structure.get_field("field1", d1);
+  structure.get_field("field2", d2);
+  ASSERT_EQ(14, d1.x);
+  ASSERT_EQ(85, d2.get().x);
+}


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