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                     S->MultiArch == pkgCache::Version::AllForeign ||
00211                     S->MultiArch == pkgCache::Version::AllAllowed)
00212                         return "all";
00213                 return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
00214         };
00215         __deprecated inline const char *Arch(bool const pseudo) const {
00216                 return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
00217         };
00218         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
00219 
00220         inline DescIterator DescriptionList() const;
00221         DescIterator TranslatedDescription() const;
00222         inline DepIterator DependsList() const;
00223         inline PrvIterator ProvidesList() const;
00224         inline VerFileIterator FileList() const;
00225         bool Downloadable() const;
00226         inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
00227         string RelStr() const;
00228 
00229         bool Automatic() const;
00230         __deprecated bool Pseudo() const;
00231         VerFileIterator NewestFile() const;
00232 
00233         inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
00234                 if (S == 0)
00235                         S = OwnerPointer();
00236         };
00237         inline VerIterator() : Iterator<Version, VerIterator>() {};
00238 };
00239                                                                         /*}}}*/
00240 // Description Iterator                                                 /*{{{*/
00241 class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
00242         protected:
00243         inline Description* OwnerPointer() const {
00244                 return (Owner != 0) ? Owner->DescP : 0;
00245         };
00246 
00247         public:
00248         // Iteration
00249         void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
00250         inline void operator ++() {operator ++(0);};
00251 
00252         // Comparison
00253         int CompareDesc(const DescIterator &B) const;
00254 
00255         // Accessors
00256         inline const char *LanguageCode() const {return Owner->StrP + S->language_code;};
00257         inline const char *md5() const {return Owner->StrP + S->md5sum;};
00258         inline DescFileIterator FileList() const;
00259 
00260         inline DescIterator() : Iterator<Description, DescIterator>() {};
00261         inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
00262                 if (S == 0)
00263                         S = Owner.DescP;
00264         };
00265 };
00266                                                                         /*}}}*/
00267 // Dependency iterator                                                  /*{{{*/
00268 class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
00269         enum {DepVer, DepRev} Type;
00270 
00271         protected:
00272         inline Dependency* OwnerPointer() const {
00273                 return (Owner != 0) ? Owner->DepP : 0;
00274         };
00275 
00276         public:
00277         // Iteration
00278         void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
00279                 (Type == DepVer ? S->NextDepends : S->NextRevDepends);};
00280         inline void operator ++() {operator ++(0);};
00281 
00282         // Accessors
00283         inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;};
00284         inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
00285         inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
00286         inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
00287         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
00288         inline bool Reverse() const {return Type == DepRev;};
00289         bool IsCritical() const;
00290         bool IsNegative() const;
00291         void GlobOr(DepIterator &Start,DepIterator &End);
00292         Version **AllTargets() const;
00293         bool SmartTargetPkg(PkgIterator &Result) const;
00294         inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
00295         inline const char *DepType() const {return Owner->DepType(S->Type);};
00296 
00297         //Nice printable representation
00298         friend std::ostream& operator <<(std::ostream& out, DepIterator D);
00299 
00300         inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
00301                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
00302                 if (S == 0)
00303                         S = Owner.DepP;
00304         };
00305         inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
00306                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
00307                 if (S == 0)
00308                         S = Owner.DepP;
00309         };
00310         inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
00311 };
00312                                                                         /*}}}*/
00313 // Provides iterator                                                    /*{{{*/
00314 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
00315         enum {PrvVer, PrvPkg} Type;
00316 
00317         protected:
00318         inline Provides* OwnerPointer() const {
00319                 return (Owner != 0) ? Owner->ProvideP : 0;
00320         };
00321 
00322         public:
00323         // Iteration
00324         void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
00325                 (Type == PrvVer?S->NextPkgProv:S->NextProvides);};
00326         inline void operator ++() {operator ++(0);};
00327 
00328         // Accessors
00329         inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
00330         inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
00331         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
00332         inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
00333         inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
00334 
00335         inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
00336 
00337         inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
00338                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
00339                 if (S == 0)
00340                         S = Owner.ProvideP;
00341         };
00342         inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
00343                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
00344                 if (S == 0)
00345                         S = Owner.ProvideP;
00346         };
00347 };
00348                                                                         /*}}}*/
00349 // Package file                                                         /*{{{*/
00350 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
00351         protected:
00352         inline PackageFile* OwnerPointer() const {
00353                 return (Owner != 0) ? Owner->PkgFileP : 0;
00354         };
00355 
00356         public:
00357         // Iteration
00358         void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
00359         inline void operator ++() {operator ++(0);};
00360 
00361         // Accessors
00362         inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
00363         inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
00364         inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
00365         inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
00366         inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
00367         inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
00368         inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
00369         inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
00370         inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
00371         inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
00372 
00373         bool IsOk();
00374         string RelStr();
00375 
00376         // Constructors
00377         inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
00378         inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
00379         inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
00380 };
00381                                                                         /*}}}*/
00382 // Version File                                                         /*{{{*/
00383 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
00384         protected:
00385         inline VerFile* OwnerPointer() const {
00386                 return (Owner != 0) ? Owner->VerFileP : 0;
00387         };
00388 
00389         public:
00390         // Iteration
00391         void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
00392         inline void operator ++() {operator ++(0);};
00393 
00394         // Accessors
00395         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00396 
00397         inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
00398         inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
00399 };
00400                                                                         /*}}}*/
00401 // Description File                                                     /*{{{*/
00402 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
00403         protected:
00404         inline DescFile* OwnerPointer() const {
00405                 return (Owner != 0) ? Owner->DescFileP : 0;
00406         };
00407 
00408         public:
00409         // Iteration
00410         void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
00411         inline void operator ++() {operator ++(0);};
00412 
00413         // Accessors
00414         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00415 
00416         inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
00417         inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
00418 };
00419                                                                         /*}}}*/
00420 // Inlined Begin functions cant be in the class because of order problems /*{{{*/
00421 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
00422        {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
00423 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
00424        {return VerIterator(*Owner,Owner->VerP + S->VersionList);};
00425 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
00426        {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
00427 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
00428        {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
00429 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
00430        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00431 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
00432        {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
00433 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
00434        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00435 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
00436        {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
00437 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
00438        {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
00439 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
00440        {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
00441                                                                         /*}}}*/
00442 #endif