1
// -*- mode: cpp; mode: fold -*-
3
/* ######################################################################
5
Cache Iterators - Iterators for navigating the cache structure
7
The iterators all provides ++,==,!=,->,* and end for their type.
8
The end function can be used to tell if the list has been fully
11
Unlike STL iterators these contain helper functions to access the data
12
that is being iterated over. This is because the data structures can't
13
be formed in a manner that is intuitive to use and also mmapable.
15
For each variable in the target structure that would need a translation
16
to be accessed correctly a translating function of the same name is
17
present in the iterator. If applicable the translating function will
20
The DepIterator can iterate over two lists, a list of 'version depends'
21
or a list of 'package reverse depends'. The type is determined by the
22
structure passed to the constructor, which should be the structure
23
that has the depends pointer as a member. The provide iterator has the
26
This header is not user includable, please use apt-pkg/pkgcache.h
28
##################################################################### */
30
#ifndef PKGLIB_CACHEITERATORS_H
31
#define PKGLIB_CACHEITERATORS_H
36
// abstract Iterator template /*{{{*/
37
/* This template provides the very basic iterator methods we
38
need to have for doing some walk-over-the-cache magic */
39
template<typename Str, typename Itr> class pkgCache::Iterator :
40
public std::iterator<std::forward_iterator_tag, Str> {
45
/** \brief Returns the Pointer for this struct in the owner
46
* The implementation of this method should be pretty short
47
* as it will only return the Pointer into the mmap stored
48
* in the owner but the name of this pointer is different for
49
* each stucture and we want to abstract here at least for the
50
* basic methods from the actual structure.
51
* \return Pointer to the first structure of this type
53
virtual Str* OwnerPointer() const = 0;
57
virtual void operator ++(int) = 0;
58
virtual void operator ++() = 0; // Should be {operator ++(0);};
59
inline bool end() const {return Owner == 0 || S == OwnerPointer();};
62
inline bool operator ==(const Itr &B) const {return S == B.S;};
63
inline bool operator !=(const Itr &B) const {return S != B.S;};
66
inline Str *operator ->() {return S;};
67
inline Str const *operator ->() const {return S;};
68
inline operator Str *() {return S == OwnerPointer() ? 0 : S;};
69
inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;};
70
inline Str &operator *() {return *S;};
71
inline Str const &operator *() const {return *S;};
72
inline pkgCache *Cache() const {return Owner;};
75
inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;};
76
inline bool IsGood() const { return S && Owner && ! end();};
77
inline unsigned long Index() const {return S - OwnerPointer();};
79
void ReMap(void const * const oldMap, void const * const newMap) {
80
if (Owner == 0 || S == 0)
82
S += (Str*)(newMap) - (Str*)(oldMap);
85
// Constructors - look out for the variable assigning
86
inline Iterator() : S(0), Owner(0) {};
87
inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {};
90
// Group Iterator /*{{{*/
91
/* Packages with the same name are collected in a Group so someone only
92
interest in package names can iterate easily over the names, so the
93
different architectures can be treated as of the "same" package
94
(apt internally treat them as totally different packages) */
95
class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
99
inline Group* OwnerPointer() const {
100
return (Owner != 0) ? Owner->GrpP : 0;
104
// This constructor is the 'begin' constructor, never use it.
105
inline GrpIterator(pkgCache &Owner) : Iterator<Group, GrpIterator>(Owner), HashIndex(-1) {
110
virtual void operator ++(int);
111
virtual void operator ++() {operator ++(0);};
113
inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
114
inline PkgIterator PackageList() const;
115
PkgIterator FindPkg(std::string Arch = "any") const;
116
/** \brief find the package with the "best" architecture
118
The best architecture is either the "native" or the first
119
in the list of Architectures which is not an end-Pointer
121
\param PreferNonVirtual tries to respond with a non-virtual package
122
and only if this fails returns the best virtual package */
123
PkgIterator FindPreferredPkg(bool const &PreferNonVirtual = true) const;
124
PkgIterator NextPkg(PkgIterator const &Pkg) const;
127
inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
131
inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {};
135
// Package Iterator /*{{{*/
136
class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
140
inline Package* OwnerPointer() const {
141
return (Owner != 0) ? Owner->PkgP : 0;
145
// This constructor is the 'begin' constructor, never use it.
146
inline PkgIterator(pkgCache &Owner) : Iterator<Package, PkgIterator>(Owner), HashIndex(-1) {
151
virtual void operator ++(int);
152
virtual void operator ++() {operator ++(0);};
154
enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
157
inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
158
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
159
inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
160
(S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);};
161
inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;};
162
inline GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);};
164
inline VerIterator VersionList() const;
165
inline VerIterator CurrentVer() const;
166
inline DepIterator RevDependsList() const;
167
inline PrvIterator ProvidesList() const;
168
OkState State() const;
169
const char *CandVersion() const;
170
const char *CurVersion() const;
172
//Nice printable representation
173
friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
174
std::string FullName(bool const &Pretty = false) const;
177
inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator<Package, PkgIterator>(Owner, Trg), HashIndex(0) {
181
inline PkgIterator() : Iterator<Package, PkgIterator>(), HashIndex(0) {};
184
// Version Iterator /*{{{*/
185
class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
187
inline Version* OwnerPointer() const {
188
return (Owner != 0) ? Owner->VerP : 0;
193
void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;};
194
inline void operator ++() {operator ++(0);};
197
int CompareVer(const VerIterator &B) const;
198
/** \brief compares two version and returns if they are similar
200
This method should be used to identify if two pseudo versions are
201
refering to the same "real" version */
202
inline bool SimilarVer(const VerIterator &B) const {
203
return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0);
207
inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
208
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
209
inline const char *Arch() const {
210
if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All)
212
return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
214
inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
216
inline DescIterator DescriptionList() const;
217
DescIterator TranslatedDescription() const;
218
inline DepIterator DependsList() const;
219
inline PrvIterator ProvidesList() const;
220
inline VerFileIterator FileList() const;
221
bool Downloadable() const;
222
inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
223
std::string RelStr() const;
225
bool Automatic() const;
226
VerFileIterator NewestFile() const;
228
inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
232
inline VerIterator() : Iterator<Version, VerIterator>() {};
235
// Description Iterator /*{{{*/
236
class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
238
inline Description* OwnerPointer() const {
239
return (Owner != 0) ? Owner->DescP : 0;
244
void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
245
inline void operator ++() {operator ++(0);};
248
int CompareDesc(const DescIterator &B) const;
251
inline const char *LanguageCode() const {return Owner->StrP + S->language_code;};
252
inline const char *md5() const {return Owner->StrP + S->md5sum;};
253
inline DescFileIterator FileList() const;
255
inline DescIterator() : Iterator<Description, DescIterator>() {};
256
inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
262
// Dependency iterator /*{{{*/
263
class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
264
enum {DepVer, DepRev} Type;
267
inline Dependency* OwnerPointer() const {
268
return (Owner != 0) ? Owner->DepP : 0;
273
void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
274
(Type == DepVer ? S->NextDepends : S->NextRevDepends);};
275
inline void operator ++() {operator ++(0);};
278
inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;};
279
inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
280
inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
281
inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
282
inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
283
inline bool Reverse() const {return Type == DepRev;};
284
bool IsCritical() const;
285
bool IsNegative() const;
286
bool IsIgnorable(PrvIterator const &Prv) const;
287
bool IsIgnorable(PkgIterator const &Pkg) const;
288
void GlobOr(DepIterator &Start,DepIterator &End);
289
Version **AllTargets() const;
290
bool SmartTargetPkg(PkgIterator &Result) const;
291
inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
292
inline const char *DepType() const {return Owner->DepType(S->Type);};
294
//Nice printable representation
295
friend std::ostream& operator <<(std::ostream& out, DepIterator D);
297
inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
298
Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
302
inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
303
Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
307
inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
310
// Provides iterator /*{{{*/
311
class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
312
enum {PrvVer, PrvPkg} Type;
315
inline Provides* OwnerPointer() const {
316
return (Owner != 0) ? Owner->ProvideP : 0;
321
void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
322
(Type == PrvVer?S->NextPkgProv:S->NextProvides);};
323
inline void operator ++() {operator ++(0);};
326
inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
327
inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
328
inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
329
inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
330
inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
332
inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
334
inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
335
Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
339
inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
340
Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
346
// Package file /*{{{*/
347
class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
349
inline PackageFile* OwnerPointer() const {
350
return (Owner != 0) ? Owner->PkgFileP : 0;
355
void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
356
inline void operator ++() {operator ++(0);};
359
inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
360
inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
361
inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
362
inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
363
inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
364
inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
365
inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
366
inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
367
inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
368
inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
371
std::string RelStr();
374
inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
375
inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
376
inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
379
// Version File /*{{{*/
380
class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
382
inline VerFile* OwnerPointer() const {
383
return (Owner != 0) ? Owner->VerFileP : 0;
388
void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
389
inline void operator ++() {operator ++(0);};
392
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
394
inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
395
inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
398
// Description File /*{{{*/
399
class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
401
inline DescFile* OwnerPointer() const {
402
return (Owner != 0) ? Owner->DescFileP : 0;
407
void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
408
inline void operator ++() {operator ++(0);};
411
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
413
inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
414
inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
417
// Inlined Begin functions cant be in the class because of order problems /*{{{*/
418
inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
419
{return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
420
inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
421
{return VerIterator(*Owner,Owner->VerP + S->VersionList);};
422
inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
423
{return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
424
inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
425
{return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
426
inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
427
{return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
428
inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
429
{return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
430
inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
431
{return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
432
inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
433
{return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
434
inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
435
{return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
436
inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
437
{return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};