- Main Page
- Modules
- Namespaces
- Classes
- Files

# iterator.h

Go to the documentation of this file.

    00001 // -*- c++ -*-
    00002 // Generated by gtkmmproc -- DO NOT MODIFY!
    00003 #ifndef _GSTREAMERMM_ITERATOR_H
    00004 #define _GSTREAMERMM_ITERATOR_H
    00005
    00006
    00007 #include <glibmm.h>
    00008
    00009 /* gstreamermm - a C++ wrapper for gstreamer
    00010  *
    00011  * Copyright 2008 The gstreamermm Development Team
    00012  *
    00013  * This library is free software; you can redistribute it and/or
    00014  * modify it under the terms of the GNU Lesser General Public
    00015  * License as published by the Free Software Foundation; either
    00016  * version 2.1 of the License, or (at your option) any later version.
    00017  *
    00018  * This library is distributed in the hope that it will be useful,
    00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00021  * Lesser General Public License for more details.
    00022  *
    00023  * You should have received a copy of the GNU Lesser General Public
    00024  * License along with this library; if not, write to the Free
    00025  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00026  */
    00027
    00028 #include <gst/gstiterator.h>
    00029 #include <stdexcept>
    00030
    00031
    00032 namespace Gst
    00033 {
    00034
    00040 enum IteratorItem
    00041 {
    00042   ITERATOR_ITEM_SKIP,
    00043   ITERATOR_ITEM_PASS,
    00044   ITERATOR_ITEM_END
    00045 };
    00046
    00047 } // namespace Gst
    00048
    00049
    00050 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00051 namespace Glib
    00052 {
    00053
    00054 template <>
    00055 class Value<Gst::IteratorItem> : public Glib::Value_Enum<Gst::IteratorItem>
    00056 {
    00057 public:
    00058   static GType value_type() G_GNUC_CONST;
    00059 };
    00060
    00061 } // namespace Glib
    00062 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00063
    00064
    00065 namespace Gst
    00066 {
    00067
    00071 enum IteratorResult
    00072 {
    00073   ITERATOR_DONE,
    00074   ITERATOR_OK,
    00075   ITERATOR_RESYNC,
    00076   ITERATOR_ERROR
    00077 };
    00078
    00079 } // namespace Gst
    00080
    00081
    00082 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00083 namespace Glib
    00084 {
    00085
    00086 template <>
    00087 class Value<Gst::IteratorResult> : public Glib::Value_Enum<Gst::IteratorResult>
    00088 {
    00089 public:
    00090   static GType value_type() G_GNUC_CONST;
    00091 };
    00092
    00093 } // namespace Glib
    00094 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00095
    00096
    00097 namespace Gst
    00098 {
    00099
    00100
    00113 template <class CppType>
    00114 class IteratorBase
    00115 {
    00116 public:
    00121   virtual IteratorResult next();
    00122
    00129   void resync();
    00130
    00137   bool is_start() const;
    00138
    00144   bool is_end() const;
    00145
    00148   operator bool() const;
    00149
    00151   GstIterator*          cobj()          { return cobject_; };
    00152
    00154   const GstIterator*    cobj() const    { return cobject_; };
    00155
    00159   virtual ~IteratorBase();
    00160
    00161 protected:
    00163   IteratorBase();
    00164
    00170   IteratorBase(const IteratorBase<CppType>&);
    00171
    00177   IteratorBase(GstIterator* castitem, bool take_ownership=true);
    00178
    00186   IteratorBase<CppType>& operator=(const IteratorBase<CppType>& other);
    00187
    00188 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00189   void* current;         // The current element the iterator is referencing.
    00190   IteratorResult current_result; // The current result of a next() call.
    00191 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00192
    00193 private:
    00194 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00195   GstIterator* cobject_;    // The underlying  C object.
    00196   bool take_ownership;      // Whether to destroy C object with the wrapper.
    00197 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00198
    00199 private:
    00200   void swap(IteratorBase<CppType>& other);
    00201 };
    00202
    00209 template <class CppType>
    00210 class IteratorBasic : public IteratorBase<CppType>
    00211 {
    00212 public:
    00214   IteratorBasic();
    00215
    00224   IteratorBasic(GstIterator* castitem, bool take_ownership=true);
    00225
    00232   void begin();
    00233
    00236   CppType operator*() const;
    00237
    00240   CppType* operator->() const;
    00241
    00247   IteratorBasic<CppType>& operator++();
    00248
    00254   IteratorBasic<CppType> operator++(int);
    00255 };
    00256
    00263 template <class CppType>
    00264 class Iterator : public IteratorBasic<CppType>
    00265 {
    00266 public:
    00268   Iterator();
    00269
    00278   Iterator(GstIterator* castitem, bool take_ownership=true);
    00279
    00284   IteratorResult next();
    00285
    00288   Glib::RefPtr<CppType> operator*() const;
    00289
    00292   CppType* operator->() const;
    00293
    00299   Iterator<CppType>& operator++();
    00300
    00306   Iterator<CppType> operator++(int);
    00307 };
    00308
    00309 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00310
    00311 /***************** Gst::IteratorBase<CppType> ************************/
    00312
    00313 template<class CppType>
    00314 IteratorResult IteratorBase<CppType>::next()
    00315 {
    00316   current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), &current);
    00317
    00318   // Set current to NULL if iterator is done:
    00319   if (current_result == Gst::ITERATOR_DONE)
    00320     current = 0;
    00321
    00322   return current_result;
    00323 }
    00324
    00325 template<class CppType>
    00326 void IteratorBase<CppType>::resync()
    00327 {
    00328   gst_iterator_resync(cobj());
    00329   current = 0;
    00330   current_result = Gst::ITERATOR_OK;
    00331 }
    00332
    00333 template<class CppType>
    00334 bool IteratorBase<CppType>::is_start() const
    00335 {
    00336   return (current == 0 && current_result == Gst::ITERATOR_OK);
    00337 }
    00338
    00339 template<class CppType>
    00340 bool IteratorBase<CppType>::is_end() const
    00341 {
    00342   return (current_result == Gst::ITERATOR_DONE);
    00343 }
    00344
    00345 template<class CppType>
    00346 IteratorBase<CppType>::operator bool() const
    00347 {
    00348   return (current != 0);
    00349 }
    00350 template<class CppType>
    00351 IteratorBase<CppType>::IteratorBase()
    00352 : cobject_(0),
    00353   take_ownership(true),
    00354   current(0),
    00355   current_result(Gst::ITERATOR_OK)
    00356 {}
    00357
    00358 template<class CppType>
    00359 IteratorBase<CppType>::IteratorBase(const IteratorBase<CppType>& other)
    00360   : cobject_(const_cast<GstIterator*>(other.cobj())),
    00361     take_ownership((other.cobj()) ? false : true),
    00362     current(other.current),
    00363     current_result(other.current_result)
    00364 {}
    00365
    00366 template<class CppType>
    00367 IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool take_ownership)
    00368 : cobject_(castitem),
    00369   take_ownership(take_ownership),
    00370   current(0),
    00371   current_result(Gst::ITERATOR_OK)
    00372 {}
    00373
    00374 template<class CppType>
    00375 IteratorBase<CppType>& IteratorBase<CppType>::operator=(const IteratorBase<CppType>& other)
    00376 {
    00377   IteratorBase temp(other);
    00378   swap(temp);
    00379   return *this;
    00380 }
    00381
    00382 template<class CppType>
    00383 void IteratorBase<CppType>::swap(IteratorBase<CppType>& other)
    00384 {
    00385   GstIterator *const temp_obj = cobject_;
    00386   cobject_ = other.cobject_;
    00387   other.cobject_ = temp_obj;
    00388
    00389   const bool temp_take_ownership = take_ownership;
    00390   take_ownership = other.take_ownership;
    00391   other.take_ownership = temp_take_ownership;
    00392
    00393   void* const temp_current = current;
    00394   current = other.current;
    00395   other.current = temp_current;
    00396
    00397   const IteratorResult temp_result = current_result;
    00398   current_result = other.current_result;
    00399   other.current_result = temp_result;
    00400 }
    00401
    00402 //virtual
    00403 template<class CppType>
    00404 IteratorBase<CppType>::~IteratorBase()
    00405 {
    00406   if (take_ownership && cobject_)
    00407   {
    00408     gst_iterator_free(cobject_);
    00409     cobject_ = 0;
    00410   }
    00411 }
    00412
    00413 /***************** Gst::IteratorBasic<CppType> ***********************/
    00414
    00415 template <class CppType>
    00416 IteratorBasic<CppType>::IteratorBasic()
    00417   : IteratorBase<CppType>()
    00418 {}
    00419
    00420 template <class CppType>
    00421 IteratorBasic<CppType>::IteratorBasic(GstIterator* castitem, bool take_ownership)
    00422   : IteratorBase<CppType>(castitem, take_ownership)
    00423 {}
    00424
    00425 template<class CppType>
    00426 void IteratorBasic<CppType>::begin()
    00427 {
    00428   this->resync();
    00429   ++(*this);
    00430 }
    00431
    00432 template <class CppType>
    00433 CppType IteratorBasic<CppType>::operator*() const
    00434 {
    00435   typedef typename CppType::BaseObjectType CType;
    00436
    00437   if (this->current)
    00438     return CppType((CType*)(this->current));
    00439   else
    00440     return CppType();
    00441 }
    00442
    00443 template <class CppType>
    00444 CppType* IteratorBasic<CppType>::operator->() const
    00445 {
    00446   static typename CppType::CppObjectType result;
    00447
    00448   if (this->current)
    00449   {
    00450     result = this->operator*();
    00451     return &result;
    00452   }
    00453   else
    00454     return (CppType*) 0;
    00455 }
    00456
    00457 template<class CppType>
    00458 IteratorBasic<CppType>& IteratorBasic<CppType>::operator++()
    00459 {
    00460   const IteratorResult result = this->next();
    00461
    00462   if (result == Gst::ITERATOR_RESYNC)
    00463     throw std::runtime_error("Concurrent update of iterator elements.  Please resync.");
    00464   else if (result == Gst::ITERATOR_ERROR)
    00465     throw std::runtime_error("Iterator error while incrementing.");
    00466
    00467   return *this;
    00468 }
    00469
    00470 template<class CppType>
    00471 IteratorBasic<CppType> IteratorBasic<CppType>::operator++(int)
    00472 {
    00473   IteratorBasic<CppType> original = *this;
    00474   ++(*this);
    00475   return original;
    00476 }
    00477
    00478 /******************* Gst::Iterator<CppType> **************************/
    00479
    00480 template <class CppType>
    00481 Iterator<CppType>::Iterator()
    00482   : IteratorBasic<CppType>()
    00483 {}
    00484
    00485 template <class CppType>
    00486 Iterator<CppType>::Iterator(GstIterator* castitem, bool take_ownership)
    00487   : IteratorBasic<CppType>(castitem, take_ownership)
    00488 {}
    00489
    00490 template <class CppType>
    00491 IteratorResult Iterator<CppType>::next()
    00492 {
    00493   const IteratorResult result = IteratorBasic<CppType>::next();
    00494
    00495   // Remove extra reference that gst_iterator_next() takes because references
    00496   // are taken when using Gst::Iterator<CppType> dereferencing operators (* and
    00497   // ->).
    00498   if (this->current)
    00499     g_object_unref(this->current);
    00500
    00501   return result;
    00502 }
    00503
    00504 template <class CppType>
    00505 Glib::RefPtr<CppType> Iterator<CppType>::operator*() const
    00506 {
    00507   typedef typename CppType::BaseObjectType CType;
    00508
    00509   if (this->current)
    00510   {
    00511     //Take extra reference when dereferencing.  The reference will disappear
    00512     //when Glib::RefPtr<> is destroyed.
    00513     return Glib::wrap((CType*)(this->current), true);
    00514   }
    00515   else
    00516     return Glib::RefPtr<CppType>(0);
    00517 }
    00518
    00519 template <class CppType>
    00520 CppType* Iterator<CppType>::operator->() const
    00521 {
    00522   typedef typename CppType::BaseObjectType CType;
    00523
    00524   if (this->current)
    00525   {
    00526     //Take extra reference when dereferencing.  The reference will disappear
    00527     //when Glib::RefPtr<> is destroyed.
    00528     return Glib::wrap((CType*)(this->current), true).operator->();
    00529   }
    00530   else
    00531     return (CppType*) 0;
    00532 }
    00533 template<class CppType>
    00534 Iterator<CppType>& Iterator<CppType>::operator++()
    00535 {
    00536   IteratorBasic<CppType>::operator++();
    00537   return *this;
    00538 }
    00539
    00540 template<class CppType>
    00541 Iterator<CppType> Iterator<CppType>::operator++(int)
    00542 {
    00543   Iterator<CppType> original = *this;
    00544   ++(*this);
    00545   return original;
    00546 }
    00547
    00548 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00549
    00550 } //namespace Gst
    00551
    00552
    00553 #endif /* _GSTREAMERMM_ITERATOR_H */
    00554