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