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
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 }
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 }
00062 #endif
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 }
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 }
00094 #endif
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;
00190 IteratorResult current_result;
00191 #endif
00192
00193 private:
00194 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00195 GstIterator* cobject_;
00196 bool take_ownership;
00197 #endif
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
00312
00313 template<class CppType>
00314 IteratorResult IteratorBase<CppType>::next()
00315 {
00316 current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), ¤t);
00317
00318
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
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
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
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
00496
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
00512
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
00527
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
00549
00550 }
00551
00552
00553 #endif
00554