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 #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 }
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 }
00066 #endif
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 }
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 }
00098 #endif
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;
00194 IteratorResult current_result;
00195 #endif
00196
00197 private:
00198 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00199 GstIterator* cobject_;
00200 bool take_ownership;
00201 #endif
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
00319
00320 template<class CppType>
00321 IteratorResult IteratorBase<CppType>::next()
00322 {
00323 current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), ¤t);
00324
00325
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
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
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
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
00513
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
00529
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
00544
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
00566
00567 }
00568
00569
00570 #endif
00571