- 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 #ifndef GLIBMM_EXCEPTIONS_ENABLED
    00032 #include <iostream>
    00033 #endif
    00034
    00035
    00036 namespace Gst
    00037 {
    00038
    00044 enum IteratorItem
    00045 {
    00046   ITERATOR_ITEM_SKIP,
    00047   ITERATOR_ITEM_PASS,
    00048   ITERATOR_ITEM_END
    00049 };
    00050
    00051 } // namespace Gst
    00052
    00053
    00054 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00055 namespace Glib
    00056 {
    00057
    00058 template <>
    00059 class Value<Gst::IteratorItem> : public Glib::Value_Enum<Gst::IteratorItem>
    00060 {
    00061 public:
    00062   static GType value_type() G_GNUC_CONST;
    00063 };
    00064
    00065 } // namespace Glib
    00066 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00067
    00068
    00069 namespace Gst
    00070 {
    00071
    00075 enum IteratorResult
    00076 {
    00077   ITERATOR_DONE,
    00078   ITERATOR_OK,
    00079   ITERATOR_RESYNC,
    00080   ITERATOR_ERROR
    00081 };
    00082
    00083 } // namespace Gst
    00084
    00085
    00086 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00087 namespace Glib
    00088 {
    00089
    00090 template <>
    00091 class Value<Gst::IteratorResult> : public Glib::Value_Enum<Gst::IteratorResult>
    00092 {
    00093 public:
    00094   static GType value_type() G_GNUC_CONST;
    00095 };
    00096
    00097 } // namespace Glib
    00098 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00099
    00100
    00101 namespace Gst
    00102 {
    00103
    00104
    00117 template <class CppType>
    00118 class IteratorBase
    00119 {
    00120 public:
    00125   virtual IteratorResult next();
    00126
    00133   void resync();
    00134
    00141   bool is_start() const;
    00142
    00148   bool is_end() const;
    00149
    00152   operator bool() const;
    00153
    00155   GstIterator*          cobj()          { return cobject_; };
    00156
    00158   const GstIterator*    cobj() const    { return cobject_; };
    00159
    00163   virtual ~IteratorBase();
    00164
    00165 protected:
    00167   IteratorBase();
    00168
    00174   IteratorBase(const IteratorBase<CppType>&);
    00175
    00181   IteratorBase(GstIterator* castitem, bool take_ownership=true);
    00182
    00190   IteratorBase<CppType>& operator=(const IteratorBase<CppType>& other);
    00191
    00192 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00193   void* current;         // The current element the iterator is referencing.
    00194   IteratorResult current_result; // The current result of a next() call.
    00195 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00196
    00197 private:
    00198 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00199   GstIterator* cobject_;    // The underlying  C object.
    00200   bool take_ownership;      // Whether to destroy C object with the wrapper.
    00201 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00202
    00203 private:
    00204   void swap(IteratorBase<CppType>& other);
    00205 };
    00206
    00213 template <class CppType>
    00214 class IteratorBasic : public IteratorBase<CppType>
    00215 {
    00216 public:
    00218   IteratorBasic();
    00219
    00228   IteratorBasic(GstIterator* castitem, bool take_ownership=true);
    00229
    00236   void begin();
    00237
    00240   CppType operator*() const;
    00241
    00244   CppType* operator->() const;
    00245
    00251   IteratorBasic<CppType>& operator++();
    00252
    00258   IteratorBasic<CppType> operator++(int);
    00259
    00260 private:
    00261   void handle_error(const Glib::ustring& message);
    00262 };
    00263
    00270 template <class CppType>
    00271 class Iterator : public IteratorBasic<CppType>
    00272 {
    00273 public:
    00275   Iterator();
    00276
    00285   Iterator(GstIterator* castitem, bool take_ownership=true);
    00286
    00291   IteratorResult next();
    00292
    00295   Glib::RefPtr<CppType> operator*() const;
    00296
    00299   CppType* operator->() const;
    00300
    00306   Iterator<CppType>& operator++();
    00307
    00313   Iterator<CppType> operator++(int);
    00314 };
    00315
    00316 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00317
    00318 /***************** Gst::IteratorBase<CppType> ************************/
    00319
    00320 template<class CppType>
    00321 IteratorResult IteratorBase<CppType>::next()
    00322 {
    00323   current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), &current);
    00324
    00325   // Set current to null if iterator is done:
    00326   if(current_result == Gst::ITERATOR_DONE)
    00327     current = 0;
    00328
    00329   return current_result;
    00330 }
    00331
    00332 template<class CppType>
    00333 void IteratorBase<CppType>::resync()
    00334 {
    00335   gst_iterator_resync(cobj());
    00336   current = 0;
    00337   current_result = Gst::ITERATOR_OK;
    00338 }
    00339
    00340 template<class CppType>
    00341 bool IteratorBase<CppType>::is_start() const
    00342 {
    00343   return (current == 0 && current_result == Gst::ITERATOR_OK);
    00344 }
    00345
    00346 template<class CppType>
    00347 bool IteratorBase<CppType>::is_end() const
    00348 {
    00349   return (current_result == Gst::ITERATOR_DONE);
    00350 }
    00351
    00352 template<class CppType>
    00353 IteratorBase<CppType>::operator bool() const
    00354 {
    00355   return (current != 0);
    00356 }
    00357 template<class CppType>
    00358 IteratorBase<CppType>::IteratorBase()
    00359 : current(0),
    00360   current_result(Gst::ITERATOR_OK),
    00361   cobject_(0),
    00362   take_ownership(true)
    00363 {}
    00364
    00365 template<class CppType>
    00366 IteratorBase<CppType>::IteratorBase(const IteratorBase<CppType>& other)
    00367   : current(other.current),
    00368     current_result(other.current_result),
    00369     cobject_(const_cast<GstIterator*>(other.cobj())),
    00370     take_ownership((other.cobj()) ? false : true)
    00371 {}
    00372
    00373 template<class CppType>
    00374 IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool take_ownership)
    00375 : current(0),
    00376   current_result(Gst::ITERATOR_OK),
    00377   cobject_(castitem),
    00378   take_ownership(take_ownership)
    00379 {}
    00380
    00381 template<class CppType>
    00382 IteratorBase<CppType>& IteratorBase<CppType>::operator=(const IteratorBase<CppType>& other)
    00383 {
    00384   IteratorBase temp(other);
    00385   swap(temp);
    00386   return *this;
    00387 }
    00388
    00389 template<class CppType>
    00390 void IteratorBase<CppType>::swap(IteratorBase<CppType>& other)
    00391 {
    00392   GstIterator *const temp_obj = cobject_;
    00393   cobject_ = other.cobject_;
    00394   other.cobject_ = temp_obj;
    00395
    00396   const bool temp_take_ownership = take_ownership;
    00397   take_ownership = other.take_ownership;
    00398   other.take_ownership = temp_take_ownership;
    00399
    00400   void* const temp_current = current;
    00401   current = other.current;
    00402   other.current = temp_current;
    00403
    00404   const IteratorResult temp_result = current_result;
    00405   current_result = other.current_result;
    00406   other.current_result = temp_result;
    00407 }
    00408
    00409 //virtual
    00410 template<class CppType>
    00411 IteratorBase<CppType>::~IteratorBase()
    00412 {
    00413   if(take_ownership && cobject_)
    00414   {
    00415     gst_iterator_free(cobject_);
    00416     cobject_ = 0;
    00417   }
    00418 }
    00419
    00420 /***************** Gst::IteratorBasic<CppType> ***********************/
    00421
    00422 template <class CppType>
    00423 IteratorBasic<CppType>::IteratorBasic()
    00424   : IteratorBase<CppType>()
    00425 {}
    00426
    00427 template <class CppType>
    00428 IteratorBasic<CppType>::IteratorBasic(GstIterator* castitem, bool take_ownership)
    00429   : IteratorBase<CppType>(castitem, take_ownership)
    00430 {}
    00431
    00432 template<class CppType>
    00433 void IteratorBasic<CppType>::begin()
    00434 {
    00435   this->resync();
    00436   ++(*this);
    00437 }
    00438
    00439 template <class CppType>
    00440 CppType IteratorBasic<CppType>::operator*() const
    00441 {
    00442   typedef typename CppType::BaseObjectType CType;
    00443
    00444   if(this->current)
    00445     return CppType((CType*)(this->current));
    00446   else
    00447     return CppType();
    00448 }
    00449
    00450 template <class CppType>
    00451 CppType* IteratorBasic<CppType>::operator->() const
    00452 {
    00453   static typename CppType::CppObjectType result;
    00454
    00455   if(this->current)
    00456   {
    00457     result = this->operator*();
    00458     return &result;
    00459   }
    00460   else
    00461     return (CppType*) 0;
    00462 }
    00463
    00464 template<class CppType>
    00465 IteratorBasic<CppType>& IteratorBasic<CppType>::operator++()
    00466 {
    00467   const IteratorResult result = this->next();
    00468
    00469   if(result == Gst::ITERATOR_RESYNC)
    00470     handle_error("Concurrent update of iterator elements.  Please resync.");
    00471   else if(result == Gst::ITERATOR_ERROR)
    00472     handle_error("Iterator error while incrementing.");
    00473
    00474   return *this;
    00475 }
    00476
    00477 template<class CppType>
    00478 IteratorBasic<CppType> IteratorBasic<CppType>::operator++(int)
    00479 {
    00480   IteratorBasic<CppType> original = *this;
    00481   ++(*this);
    00482   return original;
    00483 }
    00484
    00485 template<class CppType>
    00486 void IteratorBasic<CppType>::handle_error(const Glib::ustring& message)
    00487 {
    00488 #ifdef GLIBMM_EXCEPTIONS_ENABLED
    00489   throw std::runtime_error(message);
    00490 #else
    00491   std::cerr << "gstreamermm: " << message << std::endl;
    00492 #endif
    00493 }
    00494
    00495 /******************* Gst::Iterator<CppType> **************************/
    00496
    00497 template <class CppType>
    00498 Iterator<CppType>::Iterator()
    00499   : IteratorBasic<CppType>()
    00500 {}
    00501
    00502 template <class CppType>
    00503 Iterator<CppType>::Iterator(GstIterator* castitem, bool take_ownership)
    00504   : IteratorBasic<CppType>(castitem, take_ownership)
    00505 {}
    00506
    00507 template <class CppType>
    00508 IteratorResult Iterator<CppType>::next()
    00509 {
    00510   const IteratorResult result = IteratorBasic<CppType>::next();
    00511
    00512   // Remove extra reference that gst_iterator_next() takes because references
    00513   // are taken when using Gst::Iterator<CppType> dereferencing operators (* and
    00514   // ->).
    00515   if(this->current)
    00516     g_object_unref(this->current);
    00517
    00518   return result;
    00519 }
    00520
    00521 template <class CppType>
    00522 Glib::RefPtr<CppType> Iterator<CppType>::operator*() const
    00523 {
    00524   typedef typename CppType::BaseObjectType CType;
    00525
    00526   if(this->current)
    00527   {
    00528     //Take extra reference when dereferencing.  The reference will disappear
    00529     //when Glib::RefPtr<> is destroyed.
    00530     return Glib::wrap((CType*)(this->current), true);
    00531   }
    00532   else
    00533     return Glib::RefPtr<CppType>(0);
    00534 }
    00535
    00536 template <class CppType>
    00537 CppType* Iterator<CppType>::operator->() const
    00538 {
    00539   typedef typename CppType::BaseObjectType CType;
    00540
    00541   if(this->current)
    00542   {
    00543     //Take extra reference when dereferencing.  The reference will disappear
    00544     //when Glib::RefPtr<> is destroyed.
    00545     return Glib::wrap((CType*)(this->current), true).operator->();
    00546   }
    00547   else
    00548     return (CppType*) 0;
    00549 }
    00550 template<class CppType>
    00551 Iterator<CppType>& Iterator<CppType>::operator++()
    00552 {
    00553   IteratorBasic<CppType>::operator++();
    00554   return *this;
    00555 }
    00556
    00557 template<class CppType>
    00558 Iterator<CppType> Iterator<CppType>::operator++(int)
    00559 {
    00560   Iterator<CppType> original = *this;
    00561   ++(*this);
    00562   return original;
    00563 }
    00564
    00565 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
    00566
    00567 } //namespace Gst
    00568
    00569
    00570 #endif /* _GSTREAMERMM_ITERATOR_H */
    00571