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