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)
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         void GlobOr(DepIterator &Start,DepIterator &End);
00287         Version **AllTargets() const;
00288         bool SmartTargetPkg(PkgIterator &Result) const;
00289         inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
00290         inline const char *DepType() const {return Owner->DepType(S->Type);};
00291 
00292         //Nice printable representation
00293         friend std::ostream& operator <<(std::ostream& out, DepIterator D);
00294 
00295         inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
00296                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
00297                 if (S == 0)
00298                         S = Owner.DepP;
00299         };
00300         inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
00301                 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
00302                 if (S == 0)
00303                         S = Owner.DepP;
00304         };
00305         inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
00306 };
00307                                                                         /*}}}*/
00308 // Provides iterator                                                    /*{{{*/
00309 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
00310         enum {PrvVer, PrvPkg} Type;
00311 
00312         protected:
00313         inline Provides* OwnerPointer() const {
00314                 return (Owner != 0) ? Owner->ProvideP : 0;
00315         };
00316 
00317         public:
00318         // Iteration
00319         void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
00320                 (Type == PrvVer?S->NextPkgProv:S->NextProvides);};
00321         inline void operator ++() {operator ++(0);};
00322 
00323         // Accessors
00324         inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
00325         inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
00326         inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
00327         inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
00328         inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
00329 
00330         inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
00331 
00332         inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
00333                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
00334                 if (S == 0)
00335                         S = Owner.ProvideP;
00336         };
00337         inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
00338                 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
00339                 if (S == 0)
00340                         S = Owner.ProvideP;
00341         };
00342 };
00343                                                                         /*}}}*/
00344 // Package file                                                         /*{{{*/
00345 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
00346         protected:
00347         inline PackageFile* OwnerPointer() const {
00348                 return (Owner != 0) ? Owner->PkgFileP : 0;
00349         };
00350 
00351         public:
00352         // Iteration
00353         void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
00354         inline void operator ++() {operator ++(0);};
00355 
00356         // Accessors
00357         inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
00358         inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
00359         inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
00360         inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
00361         inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
00362         inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
00363         inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
00364         inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
00365         inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
00366         inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
00367 
00368         bool IsOk();
00369         std::string RelStr();
00370 
00371         // Constructors
00372         inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
00373         inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
00374         inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
00375 };
00376                                                                         /*}}}*/
00377 // Version File                                                         /*{{{*/
00378 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
00379         protected:
00380         inline VerFile* OwnerPointer() const {
00381                 return (Owner != 0) ? Owner->VerFileP : 0;
00382         };
00383 
00384         public:
00385         // Iteration
00386         void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
00387         inline void operator ++() {operator ++(0);};
00388 
00389         // Accessors
00390         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00391 
00392         inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
00393         inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
00394 };
00395                                                                         /*}}}*/
00396 // Description File                                                     /*{{{*/
00397 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
00398         protected:
00399         inline DescFile* OwnerPointer() const {
00400                 return (Owner != 0) ? Owner->DescFileP : 0;
00401         };
00402 
00403         public:
00404         // Iteration
00405         void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
00406         inline void operator ++() {operator ++(0);};
00407 
00408         // Accessors
00409         inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
00410 
00411         inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
00412         inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
00413 };
00414                                                                         /*}}}*/
00415 // Inlined Begin functions cant be in the class because of order problems /*{{{*/
00416 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
00417        {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
00418 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
00419        {return VerIterator(*Owner,Owner->VerP + S->VersionList);};
00420 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
00421        {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
00422 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
00423        {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
00424 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
00425        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00426 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
00427        {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
00428 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
00429        {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
00430 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
00431        {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
00432 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
00433        {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
00434 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
00435        {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
00436                                                                         /*}}}*/
00437 #endif