00001
00002
00003 #ifndef _GSTREAMERMM_ITERATOR_H
00004 #define _GSTREAMERMM_ITERATOR_H
00005
00006
00007 #include <glibmm.h>
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <gst/gstiterator.h>
00029 #include <stdexcept>
00030 #ifndef GLIBMM_EXCEPTIONS_ENABLED
00031 #include <iostream>
00032 #endif
00033
00034
00035 namespace Gst
00036 {
00037
00043 enum IteratorItem
00044 {
00045 ITERATOR_ITEM_SKIP,
00046 ITERATOR_ITEM_PASS,
00047 ITERATOR_ITEM_END
00048 };
00049
00050 }
00051
00052
00053 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00054 namespace Glib
00055 {
00056
00057 template <>
00058 class Value<Gst::IteratorItem> : public Glib::Value_Enum<Gst::IteratorItem>
00059 {
00060 public:
00061 static GType value_type() G_GNUC_CONST;
00062 };
00063
00064 }
00065 #endif
00066
00067
00068 namespace Gst
00069 {
00070
00074 enum IteratorResult
00075 {
00076 ITERATOR_DONE,
00077 ITERATOR_OK,
00078 ITERATOR_RESYNC,
00079 ITERATOR_ERROR
00080 };
00081
00082 }
00083
00084
00085 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00086 namespace Glib
00087 {
00088
00089 template <>
00090 class Value<Gst::IteratorResult> : public Glib::Value_Enum<Gst::IteratorResult>
00091 {
00092 public:
00093 static GType value_type() G_GNUC_CONST;
00094 };
00095
00096 }
00097 #endif
00098
00099
00100 namespace Gst
00101 {
00102
00103
00116 template <class CppType>
00117 class IteratorBase
00118 {
00119 public:
00124 virtual IteratorResult next();
00125
00132 void resync();
00133
00140 bool is_start() const;
00141
00147 bool is_end() const;
00148
00151 operator bool() const;
00152
00154 GstIterator* cobj() { return cobject_; };
00155
00157 const GstIterator* cobj() const { return cobject_; };
00158
00162 virtual ~IteratorBase();
00163
00164 protected:
00166 IteratorBase();
00167
00173 IteratorBase(const IteratorBase<CppType>&);
00174
00180 IteratorBase(GstIterator* castitem, bool take_ownership=true);
00181
00189 IteratorBase<CppType>& operator=(const IteratorBase<CppType>& other);
00190
00191 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00192 void* current;
00193 IteratorResult current_result;
00194 #endif
00195
00196 private:
00197 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00198 GstIterator* cobject_;
00199 bool take_ownership;
00200 #endif
00201
00202 private:
00203 void swap(IteratorBase<CppType>& other);
00204 };
00205
00212 template <class CppType>
00213 class IteratorBasic : public IteratorBase<CppType>
00214 {
00215 public:
00217 IteratorBasic();
00218
00227 IteratorBasic(GstIterator* castitem, bool take_ownership=true);
00228
00235 void begin();
00236
00239 CppType operator*() const;
00240
00243 CppType* operator->() const;
00244
00250 IteratorBasic<CppType>& operator++();
00251
00257 IteratorBasic<CppType> operator++(int);
00258 };
00259
00266 template <class CppType>
00267 class Iterator : public IteratorBasic<CppType>
00268 {
00269 public:
00271 Iterator();
00272
00281 Iterator(GstIterator* castitem, bool take_ownership=true);
00282
00287 IteratorResult next();
00288
00291 Glib::RefPtr<CppType> operator*() const;
00292
00295 CppType* operator->() const;
00296
00302 Iterator<CppType>& operator++();
00303
00309 Iterator<CppType> operator++(int);
00310 };
00311
00312 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00313
00314
00315
00316 template<class CppType>
00317 IteratorResult IteratorBase<CppType>::next()
00318 {
00319 current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), ¤t);
00320
00321
00322 if (current_result == Gst::ITERATOR_DONE)
00323 current = 0;
00324
00325 return current_result;
00326 }
00327
00328 template<class CppType>
00329 void IteratorBase<CppType>::resync()
00330 {
00331 gst_iterator_resync(cobj());
00332 current = 0;
00333 current_result = Gst::ITERATOR_OK;
00334 }
00335
00336 template<class CppType>
00337 bool IteratorBase<CppType>::is_start() const
00338 {
00339 return (current == 0 && current_result == Gst::ITERATOR_OK);
00340 }
00341
00342 template<class CppType>
00343 bool IteratorBase<CppType>::is_end() const
00344 {
00345 return (current_result == Gst::ITERATOR_DONE);
00346 }
00347
00348 template<class CppType>
00349 IteratorBase<CppType>::operator bool() const
00350 {
00351 return (current != 0);
00352 }
00353 template<class CppType>
00354 IteratorBase<CppType>::IteratorBase()
00355 : current(0),
00356 current_result(Gst::ITERATOR_OK),
00357 cobject_(0),
00358 take_ownership(true)
00359 {}
00360
00361 template<class CppType>
00362 IteratorBase<CppType>::IteratorBase(const IteratorBase<CppType>& other)
00363 : current(other.current),
00364 current_result(other.current_result),
00365 cobject_(const_cast<GstIterator*>(other.cobj())),
00366 take_ownership((other.cobj()) ? false : true)
00367 {}
00368
00369 template<class CppType>
00370 IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool take_ownership)
00371 : current(0),
00372 current_result(Gst::ITERATOR_OK),
00373 cobject_(castitem),
00374 take_ownership(take_ownership)
00375 {}
00376
00377 template<class CppType>
00378 IteratorBase<CppType>& IteratorBase<CppType>::operator=(const IteratorBase<CppType>& other)
00379 {
00380 IteratorBase temp(other);
00381 swap(temp);
00382 return *this;
00383 }
00384
00385 template<class CppType>
00386 void IteratorBase<CppType>::swap(IteratorBase<CppType>& other)
00387 {
00388 GstIterator *const temp_obj = cobject_;
00389 cobject_ = other.cobject_;
00390 other.cobject_ = temp_obj;
00391
00392 const bool temp_take_ownership = take_ownership;
00393 take_ownership = other.take_ownership;
00394 other.take_ownership = temp_take_ownership;
00395
00396 void* const temp_current = current;
00397 current = other.current;
00398 other.current = temp_current;
00399
00400 const IteratorResult temp_result = current_result;
00401 current_result = other.current_result;
00402 other.current_result = temp_result;
00403 }
00404
00405
00406 template<class CppType>
00407 IteratorBase<CppType>::~IteratorBase()
00408 {
00409 if (take_ownership && cobject_)
00410 {
00411 gst_iterator_free(cobject_);
00412 cobject_ = 0;
00413 }
00414 }
00415
00416
00417
00418 template <class CppType>
00419 IteratorBasic<CppType>::IteratorBasic()
00420 : IteratorBase<CppType>()
00421 {}
00422
00423 template <class CppType>
00424 IteratorBasic<CppType>::IteratorBasic(GstIterator* castitem, bool take_ownership)
00425 : IteratorBase<CppType>(castitem, take_ownership)
00426 {}
00427
00428 template<class CppType>
00429 void IteratorBasic<CppType>::begin()
00430 {
00431 this->resync();
00432 ++(*this);
00433 }
00434
00435 template <class CppType>
00436 CppType IteratorBasic<CppType>::operator*() const
00437 {
00438 typedef typename CppType::BaseObjectType CType;
00439
00440 if (this->current)
00441 return CppType((CType*)(this->current));
00442 else
00443 return CppType();
00444 }
00445
00446 template <class CppType>
00447 CppType* IteratorBasic<CppType>::operator->() const
00448 {
00449 static typename CppType::CppObjectType result;
00450
00451 if (this->current)
00452 {
00453 result = this->operator*();
00454 return &result;
00455 }
00456 else
00457 return (CppType*) 0;
00458 }
00459
00460 template<class CppType>
00461 IteratorBasic<CppType>& IteratorBasic<CppType>::operator++()
00462 {
00463 const IteratorResult result = this->next();
00464
00465 if (result == Gst::ITERATOR_RESYNC)
00466 #ifdef GLIBMM_EXCEPTIONS_ENABLED
00467 throw std::runtime_error("Concurrent update of iterator elements. Please resync.");
00468 #else
00469 std::cerr << "Concurrent update of iterator elements. Please resync." << std::endl;
00470 #endif
00471 else if (result == Gst::ITERATOR_ERROR)
00472 #ifdef GLIBMM_EXCEPTIONS_ENABLED
00473 throw std::runtime_error("Iterator error while incrementing.");
00474 #else
00475 std::cerr << "Iterator error while incrementing." << std::endl;
00476 #endif
00477
00478 return *this;
00479 }
00480
00481 template<class CppType>
00482 IteratorBasic<CppType> IteratorBasic<CppType>::operator++(int)
00483 {
00484 IteratorBasic<CppType> original = *this;
00485 ++(*this);
00486 return original;
00487 }
00488
00489
00490
00491 template <class CppType>
00492 Iterator<CppType>::Iterator()
00493 : IteratorBasic<CppType>()
00494 {}
00495
00496 template <class CppType>
00497 Iterator<CppType>::Iterator(GstIterator* castitem, bool take_ownership)
00498 : IteratorBasic<CppType>(castitem, take_ownership)
00499 {}
00500
00501 template <class CppType>
00502 IteratorResult Iterator<CppType>::next()
00503 {
00504 const IteratorResult result = IteratorBasic<CppType>::next();
00505
00506
00507
00508
00509 if (this->current)
00510 g_object_unref(this->current);
00511
00512 return result;
00513 }
00514
00515 template <class CppType>
00516 Glib::RefPtr<CppType> Iterator<CppType>::operator*() const
00517 {
00518 typedef typename CppType::BaseObjectType CType;
00519
00520 if (this->current)
00521 {
00522
00523
00524 return Glib::wrap((CType*)(this->current), true);
00525 }
00526 else
00527 return Glib::RefPtr<CppType>(0);
00528 }
00529
00530 template <class CppType>
00531 CppType* Iterator<CppType>::operator->() const
00532 {
00533 typedef typename CppType::BaseObjectType CType;
00534
00535 if (this->current)
00536 {
00537
00538
00539 return Glib::wrap((CType*)(this->current), true).operator->();
00540 }
00541 else
00542 return (CppType*) 0;
00543 }
00544 template<class CppType>
00545 Iterator<CppType>& Iterator<CppType>::operator++()
00546 {
00547 IteratorBasic<CppType>::operator++();
00548 return *this;
00549 }
00550
00551 template<class CppType>
00552 Iterator<CppType> Iterator<CppType>::operator++(int)
00553 {
00554 Iterator<CppType> original = *this;
00555 ++(*this);
00556 return original;
00557 }
00558
00559 #endif
00560
00561 }
00562
00563
00564 #endif
00565