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