00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _qtpod_itunesdb_utils_H_
00025 #define _qtpod_itunesdb_utils_H_
00026
00027
00028
00029
00030
00031 #ifdef QTPOD_USE_BOOST_SHAREDPTR
00032
00033 #include <boost/shared_ptr.hpp>
00034 #define QTPOD_SHARED_PTR_IMPL_DEF boost::shared_ptr
00035
00036 #else
00037
00038 #include <tr1/memory>
00039 #define QTPOD_SHARED_PTR_IMPL_DEF std::tr1::shared_ptr
00040
00041 #endif
00042
00043 #include <vector>
00044
00045 #define MAC_EPOCH_DELTA 2082844800
00046
00047 #if QT_VERSION >= 0x040000
00048
00049 static QString NullQString = QString();
00050 #define absolutePathQT43compat(dir) (dir.absolutePath())
00051 #define absoluteFilePathQT43compat(dir, file) (dir.absoluteFilePath(file))
00052 #define splitQStringQT43compat(string,delim) string.split( delim, QString::SkipEmptyParts )
00053
00054 #else
00055
00056 #define NullQString QString::null
00057 #define absolutePathQT43compat(dir) (dir.absPath())
00058 #define absoluteFilePathQT43compat(dir, file) (dir.absFilePath(file))
00059 #define splitQStringQT43compat(string,delim) QStringList::split( string, delim, false )
00060
00061 #endif
00062
00063
00064 namespace itunesdb {
00065
00066 namespace utils {
00067
00068
00069
00070
00071
00072
00073
00074
00075 template <class Iter, class TUnaryPredicate>
00076 Iter findFirst( Iter pos, Iter end, const TUnaryPredicate& predicate ) {
00077 for (; pos != end; ++pos) {
00078 if (predicate(*pos)) {
00079 return pos;
00080 }
00081 }
00082 return end;
00083 }
00084
00085
00086
00087
00088 template <class Iter, class TUnaryFunction>
00089 Iter max( Iter pos, Iter end, const TUnaryFunction& fn ) {
00090 Iter currentMax = pos;
00091 for ( ; pos != end; ++pos ) {
00092 if ( fn( *pos ) > fn ( *currentMax ) ) {
00093 currentMax = pos;
00094 }
00095 }
00096 return currentMax;
00097 }
00098
00099
00100
00101
00102
00103 struct TRUEPredicate {};
00104
00105
00106
00107
00108 template < typename IterType, typename Iter, typename TUnaryPredicate, typename TDereferenceFun >
00109 struct RangeIteratorFunctions {
00110 TUnaryPredicate pred;
00111 TDereferenceFun deref;
00112
00113 RangeIteratorFunctions( const TUnaryPredicate& p, const TDereferenceFun& d ) :
00114 pred( p ), deref( d ) {}
00115
00116 Iter successor( const Iter& current, const Iter& end ) const {
00117 Iter result = current;
00118 while ( ++result != end && !pred( deref( result ) ) );
00119 return result;
00120 }
00121
00122 bool isValid( const Iter& i ) const { return pred( deref( i ) ); }
00123
00124 unsigned int remaining( const Iter& next, const Iter& end ) {
00125 Iter i = next;
00126 unsigned int result = 0;
00127 while ( i != end ) {
00128 result++;
00129 i = successor( i, end );
00130 }
00131 return result;
00132 }
00133 };
00134
00135
00136
00137
00138 template < typename IterType, typename Iter, typename TDereferenceFun >
00139 struct RangeIteratorFunctions<IterType, Iter, TRUEPredicate, TDereferenceFun> {
00140 RangeIteratorFunctions( const TRUEPredicate&, const TDereferenceFun& ) {}
00141
00142 Iter successor( const Iter& current, const Iter& ) const {
00143 Iter result = current;
00144 return ++result;
00145 }
00146
00147 bool isValid( const Iter& ) const { return true; }
00148
00149 unsigned int remaining( const Iter& next, const Iter& end ) {
00150 return end - next;
00151 }
00152 };
00153
00154
00155
00156
00157 template <typename PType, typename Iter> struct DefaultDeref {
00158
00159
00160
00161
00162
00163
00164 const PType operator()( const Iter& iter ) const {
00165 return *iter;
00166 }
00167 };
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 template <typename IterType, typename Iter, typename TUnaryPredicate = TRUEPredicate, typename TDereferenceFun = DefaultDeref< IterType, Iter > >
00189 class RangeIterator {
00190 Iter m_current;
00191 Iter m_next;
00192 Iter m_end;
00193
00194 protected:
00195
00196
00197
00198
00199 TDereferenceFun m_dereferenceFun;
00200
00201
00202
00203
00204 RangeIteratorFunctions<IterType, Iter, TUnaryPredicate, TDereferenceFun> m_helper;
00205
00206
00207
00208
00209 void setRange( Iter pos, Iter end ) {
00210 m_end = end;
00211 m_current = pos;
00212 if ( m_current != m_end && !m_helper.isValid( m_current ) ) {
00213 m_current = m_helper.successor( m_current, m_end );
00214 }
00215 m_next = m_current;
00216 }
00217
00218
00219
00220
00221
00222 Iter currentPos() {
00223 return m_current;
00224 }
00225
00226
00227
00228
00229
00230 bool empty() const {
00231 return m_current == m_end;
00232 }
00233
00234 public:
00235
00236
00237
00238
00239 RangeIterator(Iter start, Iter end, const TUnaryPredicate& predicate = TUnaryPredicate(), TDereferenceFun deref = TDereferenceFun() )
00240 : m_dereferenceFun( deref ), m_helper( predicate, deref )
00241 {
00242 setRange( start, end );
00243 }
00244
00245
00246
00247
00248
00249 bool hasNext() const {
00250 return m_next != m_end;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 IterType next() {
00266 m_current = m_next;
00267 m_next = m_helper.successor( m_current, m_end );
00268 return current();
00269 }
00270
00271
00272
00273
00274
00275 IterType current() const {
00276 return m_dereferenceFun( m_current );
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 unsigned int remaining() const {
00288 return m_helper.remaining( m_next, m_end );
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 IterType last() const {
00299 Iter result = m_end;
00300 while( result != m_current && !m_helper.isValid( --result ) );
00301 return m_dereferenceFun( result );
00302 }
00303
00304 };
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 template <typename IterType, typename Iter, typename TDereferenceFun = DefaultDeref<IterType, Iter> >
00335 class DereferencingRangeIterator : public RangeIterator<IterType, Iter, TRUEPredicate, TDereferenceFun> {
00336 public:
00337
00338
00339
00340
00341 DereferencingRangeIterator( Iter start, Iter end )
00342 : RangeIterator< IterType, Iter, TRUEPredicate, TDereferenceFun >( start, end, TRUEPredicate() )
00343 {
00344 }
00345 };
00346
00347
00348 template <class Comparable_T>
00349 class Comparator {
00350 public:
00351 virtual ~Comparator() {}
00352
00353
00354
00355
00356
00357
00358
00359 virtual int compare( const Comparable_T& c1, const Comparable_T& c2 ) const = 0;
00360 };
00361
00362
00363
00364
00365
00366 template <class ElemType>
00367 class SortablePtrVector : protected std::vector<ElemType*> {
00368
00369 typedef typename std::vector<ElemType*>::iterator PrivateIterator;
00370 typedef typename std::vector<ElemType*>::const_iterator PrivateConstIterator;
00371 typedef std::vector<ElemType*> BaseContainerType;
00372
00373 unsigned long m_version;
00374
00375 public:
00376
00377
00378
00379
00380 typedef Comparator<ElemType> SortableVectorElemComparator;
00381
00382
00383
00384
00385 typedef QTPOD_SHARED_PTR_IMPL_DEF< SortableVectorElemComparator > ComparatorPtr;
00386
00387
00388
00389
00390
00391 template < typename Container_T, typename Iter_T, typename TUnaryPredicate = TRUEPredicate >
00392 class ContainerVersionAwareIterator : public RangeIterator<ElemType*, Iter_T, TUnaryPredicate > {
00393 protected:
00394
00395
00396
00397
00398
00399
00400 Container_T& m_container;
00401
00402
00403
00404
00405
00406
00407 unsigned long m_containerversion;
00408
00409
00410
00411
00412 typedef RangeIterator< ElemType*, Iter_T, TUnaryPredicate > BaseRangeIterator;
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 ContainerVersionAwareIterator( Container_T& container, const TUnaryPredicate& pred = TUnaryPredicate() )
00424 : BaseRangeIterator( container.begin(), container.end(), pred ),
00425 m_container( container ),
00426 m_containerversion( container.m_version ) {}
00427
00428 public:
00429
00430
00431
00432
00433
00434 bool isValid() const {
00435 return m_container.m_version == m_containerversion;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 bool hasNext() const {
00445 return isValid() && BaseRangeIterator::hasNext();
00446 }
00447
00448 };
00449
00450
00451
00452
00453 template < typename TUnaryPredicate = TRUEPredicate >
00454 class FilteredIterator : public ContainerVersionAwareIterator<SortablePtrVector, PrivateIterator, TUnaryPredicate > {
00455 friend class SortablePtrVector;
00456
00457 typedef ContainerVersionAwareIterator<SortablePtrVector, PrivateIterator, TUnaryPredicate > IteratorBase;
00458
00459 unsigned long incrementContainerVersion() {
00460 if ( IteratorBase::isValid() ) {
00461 return IteratorBase::m_containerversion = ++IteratorBase::m_container.m_version;
00462 }
00463 return 0;
00464 }
00465
00466 public:
00467
00468
00469
00470
00471
00472
00473 FilteredIterator( SortablePtrVector& container, const TUnaryPredicate& predicate = TUnaryPredicate() )
00474 : IteratorBase( container, predicate ) {}
00475
00476
00477
00478
00479
00480 bool remove() {
00481 if ( IteratorBase::empty() || !IteratorBase::isValid() ) {
00482 return false;
00483 }
00484 incrementContainerVersion();
00485 ElemType * element = IteratorBase::current();
00486 PrivateIterator newpos = IteratorBase::m_container.erase( IteratorBase::currentPos() );
00487 IteratorBase::setRange( newpos, IteratorBase::m_container.end() );
00488 if ( IteratorBase::m_container.m_deleteElements ) {
00489 delete element;
00490 }
00491 return true;
00492 }
00493
00494
00495
00496
00497
00498
00499 bool removeRemaining() {
00500 if ( !IteratorBase::hasNext() ) {
00501 return false;
00502 }
00503 do {
00504 IteratorBase::next();
00505 remove();
00506 } while ( IteratorBase::hasNext() );
00507 return true;
00508 }
00509 };
00510
00511
00512
00513
00514 typedef FilteredIterator<> Iterator;
00515
00516
00517
00518
00519
00520 template < typename TUnaryPredicate = TRUEPredicate >
00521 struct FilteredConstIterator : public ContainerVersionAwareIterator<const SortablePtrVector, PrivateConstIterator, TUnaryPredicate > {
00522 friend class SortablePtrVector;
00523
00524
00525
00526
00527
00528
00529 FilteredConstIterator( const SortablePtrVector& container, const TUnaryPredicate& predicate = TUnaryPredicate() )
00530 : ContainerVersionAwareIterator<const SortablePtrVector, PrivateConstIterator, TUnaryPredicate >( container, predicate ) {}
00531 };
00532
00533
00534
00535
00536
00537 typedef FilteredConstIterator<> ConstIterator;
00538
00539 private:
00540 bool m_deleteElements;
00541 ComparatorPtr m_comparator;
00542
00543 public:
00544
00545
00546
00547
00548 SortablePtrVector( bool deleteElements = false )
00549 : BaseContainerType(), m_version( 0 ), m_deleteElements( deleteElements ) {}
00550
00551
00552
00553
00554
00555
00556 template < typename IterT >
00557 SortablePtrVector( IterT elements, bool deleteElements = false )
00558 : BaseContainerType(), m_version( 0 ), m_deleteElements( deleteElements )
00559 {
00560 addAll( elements );
00561 }
00562
00563 virtual ~SortablePtrVector() {
00564 clear();
00565 }
00566
00567
00568
00569
00570
00571 void setComparator( SortableVectorElemComparator * comparator ) {
00572 m_comparator = ComparatorPtr( comparator );
00573 }
00574
00575
00576
00577
00578
00579 void setComparator( const ComparatorPtr& comparator ) {
00580 m_comparator = comparator;
00581 }
00582
00583
00584
00585
00586
00587 const ComparatorPtr& getComparator() const {
00588 return m_comparator;
00589 }
00590
00591
00592
00593
00594
00595
00596 void sort() {
00597 if ( m_comparator ) {
00598 ++m_version;
00599 std::sort( BaseContainerType::begin(), BaseContainerType::end(), SmallerBinaryPredicate( m_comparator ) );
00600 }
00601 }
00602
00603
00604
00605
00606 void randomize() {
00607 ++m_version;
00608 std::random_shuffle( BaseContainerType::begin(), BaseContainerType::end() );
00609 }
00610
00611 struct SmallerBinaryPredicate {
00612 ComparatorPtr m_comparator;
00613 SmallerBinaryPredicate( ComparatorPtr& ptr ) : m_comparator( ptr ) {}
00614 bool operator() ( const ElemType * i1, const ElemType * i2 ) {
00615 return m_comparator->compare( *i1, *i2 ) < 0;
00616 }
00617 };
00618 struct FindFirstNotLessThan {
00619 SmallerBinaryPredicate& m_predicate;
00620 ElemType * m_item;
00621 FindFirstNotLessThan( SmallerBinaryPredicate& pred, ElemType * item )
00622 : m_predicate( pred ), m_item( item ) {}
00623 bool operator() ( const ElemType * i ) {
00624 return m_predicate( m_item, i );
00625 }
00626 };
00627
00628
00629
00630
00631
00632
00633
00634 unsigned int inSort( ElemType * item ) {
00635 unsigned int idx = 0;
00636
00637 ++m_version;
00638
00639 if ( !m_comparator ) {
00640 idx = BaseContainerType::size();
00641 BaseContainerType::push_back( item );
00642 return idx;
00643 }
00644
00645 SmallerBinaryPredicate pred( m_comparator );
00646 FindFirstNotLessThan finder( pred, item );
00647
00648 PrivateIterator pos = std::find_if( BaseContainerType::begin(), BaseContainerType::end(), finder );
00649 if ( pos == BaseContainerType::end() ) {
00650 idx = BaseContainerType::size();
00651 BaseContainerType::push_back( item );
00652 } else {
00653 idx = pos - BaseContainerType::begin();
00654 BaseContainerType::insert( pos, item );
00655 }
00656
00657 return idx;
00658 }
00659
00660
00661
00662
00663
00664 template <typename IterT>
00665 void addAll( IterT elemIter ) {
00666 while ( elemIter.hasNext() ) {
00667 append( elemIter.next() );
00668 }
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678 bool remove( unsigned int pos ) {
00679 if ( pos > BaseContainerType::size() -1 ) {
00680 return false;
00681 }
00682
00683 ++m_version;
00684
00685 PrivateIterator posIter = BaseContainerType::begin() + pos;
00686 if ( m_deleteElements ) {
00687 delete *posIter;
00688 }
00689 erase( posIter );
00690
00691 return true;
00692 }
00693
00694
00695
00696
00697
00698 unsigned int count() const { return BaseContainerType::size(); }
00699
00700
00701
00702
00703
00704 bool isEmpty() const { return BaseContainerType::empty(); }
00705
00706
00707
00708
00709
00710 Iterator iterator() { return Iterator ( *this ); }
00711
00712
00713
00714
00715
00716 ConstIterator iterator() const { return ConstIterator( *this ); }
00717
00718
00719
00720
00721
00722 ConstIterator const_iterator() const { return ConstIterator( *this ); }
00723
00724
00725
00726
00727
00728
00729 template <typename TUnaryPredicate>
00730 FilteredIterator<TUnaryPredicate> filteredElements( const TUnaryPredicate& pred ) {
00731 return FilteredIterator<TUnaryPredicate>( *this, pred );
00732 }
00733
00734
00735
00736
00737
00738
00739 template <typename TUnaryPredicate>
00740 FilteredConstIterator<TUnaryPredicate> filteredElements( const TUnaryPredicate& pred ) const {
00741 return FilteredConstIterator<TUnaryPredicate>( *this, pred );
00742 }
00743
00744
00745
00746
00747
00748 void append( ElemType * item ) { BaseContainerType::push_back( item ); }
00749
00750
00751
00752
00753
00754
00755 ElemType * operator[] ( unsigned int pos ) const {
00756 return BaseContainerType::operator[] ( pos );
00757 }
00758
00759
00760
00761
00762
00763
00764 ElemType *& operator[] ( unsigned int pos ) {
00765 return BaseContainerType::operator[] ( pos );
00766 }
00767
00768
00769
00770
00771
00772 ElemType * last() const {
00773 return BaseContainerType::back();
00774 }
00775
00776
00777
00778
00779 void clear() {
00780 #if 0
00781
00782 iterator().removeRemaining();
00783 printf( "%d number of items left after clear\n" , count() );
00784 #else
00785 if ( m_deleteElements ) {
00786 PrivateIterator iter = BaseContainerType::begin();
00787 for ( ; iter != BaseContainerType::end(); ++iter ) {
00788 delete *iter;
00789 }
00790 }
00791 BaseContainerType::clear();
00792 #endif
00793 }
00794 };
00795
00796
00797
00798
00799
00800 class NonCopyAble {
00801 private:
00802 NonCopyAble( const NonCopyAble& ) {}
00803 protected:
00804 NonCopyAble() {}
00805 public:
00806 virtual ~NonCopyAble() {}
00807 };
00808
00809
00810
00811
00812
00813 template <class Stream_T>
00814 inline void seekRelative( Stream_T& stream, unsigned int numbytes ) {
00815 if ( numbytes > 0 ) {
00816 char * buffer = new char[ numbytes ];
00817 stream.readRawBytes( buffer, numbytes );
00818 delete [] buffer;
00819 }
00820 }
00821
00822
00823 }
00824
00825 }
00826
00827 #endif