apt @VERSION@
cacheiterators.h
00001 // -*- mode: cpp; mode: fold -*-
00002 // Description                                                          /*{{{*/
00003 /* ######################################################################
00004    
00005    Cache Iterators - Iterators for navigating the cache structure
00006    
00007    The iterators all provides ++,==,!=,->,* and end for their type.
00008    The end function can be used to tell if the list has been fully
00009    traversed.
00010    
00011    Unlike STL iterators these contain helper functions to access the data
00012    that is being iterated over. This is because the data structures can't
00013    be formed in a manner that is intuitive to use and also mmapable.
00014    
00015    For each variable in the target structure that would need a translation
00016    to be accessed correctly a translating function of the same name is
00017    present in the iterator. If applicable the translating function will
00018    return an iterator.
00019 
00020    The DepIterator can iterate over two lists, a list of 'version depends'
00021    or a list of 'package reverse depends'. The type is determined by the
00022    structure passed to the constructor, which should be the structure
00023    that has the depends pointer as a member. The provide iterator has the
00024    same system.
00025    
00026    This header is not user includable, please use apt-pkg/pkgcache.h
00027    
00028    ##################################################################### */
00029                                                                         /*}}}*/
00030 #ifndef PKGLIB_CACHEITERATORS_H
00031 #define PKGLIB_CACHEITERATORS_H
00032 #include<iterator>
00033 
00034 #include<string.h>
00035 // abstract Iterator template                                           /*{{{*/
00036 /* This template provides the very basic iterator methods we
00037    need to have for doing some walk-over-the-cache magic */
00038 template<typename Str, typename Itr> class pkgCache::Iterator :
00039                         public std::iterator<std::forward_iterator_tag, Str> {
00040         protected:
00041         Str *S;
00042         pkgCache *Owner;
00043 
00052         virtual Str* OwnerPointer() const = 0;
00053 
00054         public:
00055         // Iteration
00056         virtual void operator ++(int) = 0;
00057         virtual void operator ++() = 0; // Should be {operator ++(0);};
00058         inline bool end() const {return Owner == 0 || S == OwnerPointer();};
00059 
00060         // Comparison
00061         inline bool operator ==(const Itr &B) const {return S == B.S;};
00062         inline bool operator !=(const Itr &B) const {return S != B.S;};
00063 
00064         // Accessors
00065         inline Str *operator ->() {return S;};
00066         inline Str const *operator ->() const {return S;};
00067         inline operator Str *() {return S == OwnerPointer() ? 0 : S;};
00068         inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;};
00069         inline Str &operator *() {return *S;};
00070         inline Str const &operator *() const {return *S;};
00071         inline pkgCache *Cache() const {return Owner;};
00072 
00073         // Mixed stuff
00074         inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;};
00075         inline bool IsGood() const { return S && Owner && ! end();};
00076         inline unsigned long Index() const {return S - OwnerPointer();};
00077 
00078         void ReMap(void const * const oldMap, void const * const newMap) {
00079                 if (Owner == 0 || S == 0)
00080                         return;
00081                 S += (Str*)(newMap) - (Str*)(oldMap);
00082         }
00083 
00084         // Constructors - look out for the variable assigning
00085         inline Iterator() : S(0), Owner(0) {};
00086         inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {};
00087 };
00088                                                                         /*}}}*/
00089 // Group Iterator                                                       /*{{{*/
00090 /* Packages with the same name are collected in a Group so someone only
00091    interest in package names can iterate easily over the names, so the
00092    different architectures can be treated as of the "same" package
00093    (apt internally treat them as totally different packages) */
00094 class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
00095         long HashIndex;
00096 
00097         protected:
00098         inline Group* OwnerPointer() const {
00099                 return (Owner != 0) ? Owner->GrpP : 0;
00100         };
00101 
00102         public:
00103         // This constructor is the 'begin' constructor, never use it.
00104         inline GrpIterator(pkgCache &Owner) : Iterator<Group, GrpIterator>(Owner), HashIndex(-1) {
00105                 S = OwnerPointer();
00106                 operator ++(0);
00107         };
00108 
00109         virtual void operator ++(int);
00110         virtual void operator ++() {operator ++(0);};
00111 
00112         inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
00113         inline PkgIterator PackageList() const;
00114         PkgIterator FindPkg(string Arch = "any") const;
00122         PkgIterator FindPreferredPkg(bool const &PreferNonVirtual = true) const;
00123         PkgIterator NextPkg(PkgIterator const &Pkg) const;
00124 
00125         // Constructors
00126         inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
00127                 if (S == 0)
00128                         S = OwnerPointer();
00129         };
00130         inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {};
00131 
00132 };
00133                                                                         /*}}}*/
00134 // Package Iterator                                                     /*{{{*/
00135 class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
00136         long HashIndex;
00137 
00138         protected:
00139         inline Package* OwnerPointer() const {
00140                 return (Owner != 0) ? Owner->PkgP : 0;
00141         };
00142 
00143         public:
00144         // This constructor is the 'begin' constructor, never use it.
00145         inline PkgIterator(pkgCache &Owner) : Iterator<Package, PkgIterator>(Owner), HashIndex(-1) {
00146                 S = OwnerPointer();
00147                 operator ++(0);
00148         };
00149 
00150         virtual void operator ++(int);
00151         virtual void operator ++() {operator ++(0);};
00152 
00153         enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
00154 
00155         // Accessors
00156         inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
00157         inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
00158         inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
00159                 (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);};
00160         inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;};
00161         inline GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);};
00162 
00163         inline VerIterator VersionList() const;
00164         inline VerIterator CurrentVer() const;
00165         inline DepIterator RevDependsList() const;
00166         inline PrvIterator ProvidesList() const;
00167         OkState State() const;
00168         const char *CandVersion() const;
00169         const char *CurVersion() const;
00170 
00171         //Nice printable representation
00172         friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
00173         std::string FullName(bool const &Pretty = false) const;
00174 
00175         // Constructors
00176         inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator<Package, PkgIterator>(Owner, Trg), HashIndex(0) {
00177                 if (S == 0)
00178                         S = OwnerPointer();
00179         };
00180         inline PkgIterator() : Iterator<Package, PkgIterator>(), HashIndex(0) {};
00181 };
00182                                                                         /*}}}*/
00183 // Version Iterator                                                     /*{{{*/
00184 class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
00185         protected:
00186         inline Version* OwnerPointer() const {
00187                 return (Owner != 0) ? Owner->VerP : 0;
00188         };
00189 
00190         public:
00191         // Iteration
00192         void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;};
00193         inline void operator ++() {operator ++(0);};
00194 
00195         // Comparison
00196         int CompareVer(const VerIterator &B) const;
00201         inline bool SimilarVer(const VerIterator &B) const {
00202                 return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0);
00203         };
00204 
00205         // Accessors
00206         inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
00207         inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
00208         inline const char *Arch() const {
00209                 if (S->MultiArch == pkgCache::Version::All)
00210                         return "all";
00211                 return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
00212         };
00213         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
00214 
00215         inline DescIterator DescriptionList() const;
00216         DescIterator TranslatedDescription() const;
00217         inline DepIterator DependsList() const;
00218         inline PrvIterator ProvidesList() const;
00219         inline VerFileIterator FileList() const;
00220         bool Downloadable() const;
00221         inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
00222         string RelStr() const;
00223 
00224         bool Automatic() const;
00225         VerFileIterator NewestFile() const;
00226 
00227         inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
00228                 if (S == 0)
00229                         S = OwnerPointer();
00230         };
00231         inline VerIterator() : Iterator<Version, VerIterator>() {};
00232 };
00233                                                                         /*}}}*/
00234 // Description Iterator                                                 /*{{{*/
00235 class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
00236         protected:
00237         inline Description* OwnerPointer() const {
00238                 return (Owner != 0) ? Owner->DescP : 0;
00239         };
00240 
00241         public:
00242         // Iteration
00243         void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
00244         inline void operator ++() {operator ++(0);};
00245 
00246         // Comparison
00247         int CompareDesc(const DescIterator &B) const;
00248 
00249         // Accessors
00250         inline const char *LanguageCode() const {return Owner->StrP + S->language_code;};
00251         inline const char *md5() const {return Owner->StrP + S->md5sum;};
00252         inline DescFileIterator FileList() const;
00253 
00254         inline DescIterator() : Iterator<Description, DescIterator>() {};
00255         inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
00256                 if (S == 0)
00257                         S = Owner.DescP;
00258         };
00259 };
00260                                                                         /*}}}*/
00261 // Dependency iterator                                                  /*{{{*/
00262 class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
00263         enum {DepVer, DepRev} Type;
00264 
00265         protected:
00266         inline Dependency* OwnerPointer() const {
00267                 return (Owner != 0) ? Owner->DepP : 0;
00268         };
00269 
00270         public:
00271         // Iteration
00272         void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
00273                 (Type == DepVer ? S->NextDepends : S->NextRevDepends);};
00274         inline void operator ++() {operator ++(0);};
00275 
00276         // Accessors
00277         inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;};
00278         inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
00279         inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
00280         inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
00281         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
00282         inline bool Reverse() const {return Type == DepRev;};
00283         bool IsCritical() const;
00284         bool IsNegative() const;
00285         void GlobOr(DepIterator &Start,DepIterator &End);
00286         Version **AllTargets() const;
00287         bool SmartTargetPkg(PkgIterator &Result) const;
00288         inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
00289         inline const char *DepType() const {return Owner->DepType(S->Type);};
00290 
00291         //Nice printable representation
00292         friend std::ostream& operator <<(std::ostream& out, DepIterator D);
00293 
00294         inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
00295                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
00296                 if (S == 0)
00297                         S = Owner.DepP;
00298         };
00299         inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
00300                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
00301                 if (S == 0)
00302                         S = Owner.DepP;
00303         };
00304         inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
00305 };
00306                                                                         /*}}}*/
00307 // Provides iterator                                                    /*{{{*/
00308 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
00309         enum {PrvVer, PrvPkg} Type;
00310 
00311         protected:
00312         inline Provides* OwnerPointer() const {
00313                 return (Owner != 0) ? Owner->ProvideP : 0;
00314         };
00315 
00316         public:
00317         // Iteration
00318         void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
00319                 (Type == PrvVer?S->NextPkgProv:S->NextProvides);};
00320         inline void operator ++() {operator ++(0);};
00321 
00322         // Accessors
00323         inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
00324         inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
00325         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
00326         inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
00327         inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
00328 
00329         inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
00330 
00331         inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
00332                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
00333                 if (S == 0)
00334                         S = Owner.ProvideP;
00335         };
00336         inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
00337                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
00338                 if (S == 0)
00339                         S = Owner.ProvideP;
00340         };
00341 };
00342                                                                         /*}}}*/
00343 // Package file                                                         /*{{{*/
00344 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
00345         protected:
00346         inline PackageFile* OwnerPointer() const {
00347                 return (Owner != 0) ? Owner->PkgFileP : 0;
00348         };
00349 
00350         public:
00351         // Iteration
00352         void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
00353         inline void operator ++() {operator ++(0);};
00354 
00355         // Accessors
00356         inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
00357         inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
00358         inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
00359         inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
00360         inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
00361         inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
00362         inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
00363         inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
00364         inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
00365         inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
00366 
00367         bool IsOk();
00368         string RelStr();
00369 
00370         // Constructors
00371         inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
00372         inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
00373         inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
00374 };
00375                                                                         /*}}}*/
00376 // Version File                                                         /*{{{*/
00377 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
00378         protected:
00379         inline VerFile* OwnerPointer() const {
00380                 return (Owner != 0) ? Owner->VerFileP : 0;
00381         };
00382 
00383         public:
00384         // Iteration
00385         void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
00386         inline void operator ++() {operator ++(0);};
00387 
00388         // Accessors
00389         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00390 
00391         inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
00392         inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
00393 };
00394                                                                         /*}}}*/
00395 // Description File                                                     /*{{{*/
00396 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
00397         protected:
00398         inline DescFile* OwnerPointer() const {
00399                 return (Owner != 0) ? Owner->DescFileP : 0;
00400         };
00401 
00402         public:
00403         // Iteration
00404         void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
00405         inline void operator ++() {operator ++(0);};
00406 
00407         // Accessors
00408         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00409 
00410         inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
00411         inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
00412 };
00413                                                                         /*}}}*/
00414 // Inlined Begin functions cant be in the class because of order problems /*{{{*/
00415 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
00416        {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
00417 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
00418        {return VerIterator(*Owner,Owner->VerP + S->VersionList);};
00419 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
00420        {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
00421 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
00422        {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
00423 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
00424        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00425 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
00426        {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
00427 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
00428        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00429 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
00430        {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
00431 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
00432        {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
00433 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
00434        {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
00435                                                                         /*}}}*/
00436 #endif