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