apt  0.9.12.1
cacheiterators.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  Cache Iterators - Iterators for navigating the cache structure
6 
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
9  traversed.
10 
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.
14 
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
18  return an iterator.
19 
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
24  same system.
25 
26  This header is not user includable, please use apt-pkg/pkgcache.h
27 
28  ##################################################################### */
29  /*}}}*/
30 #ifndef PKGLIB_CACHEITERATORS_H
31 #define PKGLIB_CACHEITERATORS_H
32 #include<iterator>
33 
34 #include<string.h>
35 
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> {
41  protected:
42  Str *S;
43  pkgCache *Owner;
44 
53  virtual Str* OwnerPointer() const = 0;
54 
55  public:
56  // Iteration
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();};
60 
61  // Comparison
62  inline bool operator ==(const Itr &B) const {return S == B.S;};
63  inline bool operator !=(const Itr &B) const {return S != B.S;};
64 
65  // Accessors
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;};
73 
74  // Mixed stuff
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();};
78 
79  void ReMap(void const * const oldMap, void const * const newMap) {
80  if (Owner == 0 || S == 0)
81  return;
82  S += (Str*)(newMap) - (Str*)(oldMap);
83  }
84 
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) {};
88 };
89  /*}}}*/
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> {
96  long HashIndex;
97 
98  protected:
99  inline Group* OwnerPointer() const {
100  return (Owner != 0) ? Owner->GrpP : 0;
101  };
102 
103  public:
104  // This constructor is the 'begin' constructor, never use it.
105  inline GrpIterator(pkgCache &Owner) : Iterator<Group, GrpIterator>(Owner), HashIndex(-1) {
106  S = OwnerPointer();
107  operator ++(0);
108  };
109 
110  virtual void operator ++(int);
111  virtual void operator ++() {operator ++(0);};
112 
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;
123  PkgIterator FindPreferredPkg(bool const &PreferNonVirtual = true) const;
124  PkgIterator NextPkg(PkgIterator const &Pkg) const;
125 
126  // Constructors
127  inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
128  if (S == 0)
129  S = OwnerPointer();
130  };
131  inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {};
132 
133 };
134  /*}}}*/
135 // Package Iterator /*{{{*/
136 class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
137  long HashIndex;
138 
139  protected:
140  inline Package* OwnerPointer() const {
141  return (Owner != 0) ? Owner->PkgP : 0;
142  };
143 
144  public:
145  // This constructor is the 'begin' constructor, never use it.
146  inline PkgIterator(pkgCache &Owner) : Iterator<Package, PkgIterator>(Owner), HashIndex(-1) {
147  S = OwnerPointer();
148  operator ++(0);
149  };
150 
151  virtual void operator ++(int);
152  virtual void operator ++() {operator ++(0);};
153 
154  enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
155 
156  // Accessors
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);};
163 
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;
171 
172  //Nice printable representation
173  friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
174  std::string FullName(bool const &Pretty = false) const;
175 
176  // Constructors
177  inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator<Package, PkgIterator>(Owner, Trg), HashIndex(0) {
178  if (S == 0)
179  S = OwnerPointer();
180  };
181  inline PkgIterator() : Iterator<Package, PkgIterator>(), HashIndex(0) {};
182 };
183  /*}}}*/
184 // Version Iterator /*{{{*/
185 class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
186  protected:
187  inline Version* OwnerPointer() const {
188  return (Owner != 0) ? Owner->VerP : 0;
189  };
190 
191  public:
192  // Iteration
193  void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;};
194  inline void operator ++() {operator ++(0);};
195 
196  // Comparison
197  int CompareVer(const VerIterator &B) const;
202  inline bool SimilarVer(const VerIterator &B) const {
203  return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0);
204  };
205 
206  // Accessors
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 {
211  return "all";
212  return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
213  };
214  inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
215 
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  const char *MultiArchType() const;
224  std::string RelStr() const;
225 
226  bool Automatic() const;
227  VerFileIterator NewestFile() const;
228 
229  inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
230  if (S == 0)
231  S = OwnerPointer();
232  };
233  inline VerIterator() : Iterator<Version, VerIterator>() {};
234 };
235  /*}}}*/
236 // Description Iterator /*{{{*/
237 class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
238  protected:
239  inline Description* OwnerPointer() const {
240  return (Owner != 0) ? Owner->DescP : 0;
241  };
242 
243  public:
244  // Iteration
245  void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
246  inline void operator ++() {operator ++(0);};
247 
248  // Comparison
249  int CompareDesc(const DescIterator &B) const;
250 
251  // Accessors
252  inline const char *LanguageCode() const {return Owner->StrP + S->language_code;};
253  inline const char *md5() const {return Owner->StrP + S->md5sum;};
254  inline DescFileIterator FileList() const;
255 
256  inline DescIterator() : Iterator<Description, DescIterator>() {};
257  inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
258  if (S == 0)
259  S = Owner.DescP;
260  };
261 };
262  /*}}}*/
263 // Dependency iterator /*{{{*/
264 class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
265  enum {DepVer, DepRev} Type;
266 
267  protected:
268  inline Dependency* OwnerPointer() const {
269  return (Owner != 0) ? Owner->DepP : 0;
270  };
271 
272  public:
273  // Iteration
274  void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
275  (Type == DepVer ? S->NextDepends : S->NextRevDepends);};
276  inline void operator ++() {operator ++(0);};
277 
278  // Accessors
279  inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;};
280  inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
281  inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
282  inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
283  inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
284  inline bool Reverse() const {return Type == DepRev;};
285  bool IsCritical() const;
286  bool IsNegative() const;
287  bool IsIgnorable(PrvIterator const &Prv) const;
288  bool IsIgnorable(PkgIterator const &Pkg) const;
289  bool IsMultiArchImplicit() const;
290  bool IsSatisfied(VerIterator const &Ver) const;
291  bool IsSatisfied(PrvIterator const &Prv) const;
292  void GlobOr(DepIterator &Start,DepIterator &End);
293  Version **AllTargets() const;
294  bool SmartTargetPkg(PkgIterator &Result) const;
295  inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
296  inline const char *DepType() const {return Owner->DepType(S->Type);};
297 
298  //Nice printable representation
299  friend std::ostream& operator <<(std::ostream& out, DepIterator D);
300 
301  inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
302  Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
303  if (S == 0)
304  S = Owner.DepP;
305  };
306  inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
307  Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
308  if (S == 0)
309  S = Owner.DepP;
310  };
311  inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
312 };
313  /*}}}*/
314 // Provides iterator /*{{{*/
315 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
316  enum {PrvVer, PrvPkg} Type;
317 
318  protected:
319  inline Provides* OwnerPointer() const {
320  return (Owner != 0) ? Owner->ProvideP : 0;
321  };
322 
323  public:
324  // Iteration
325  void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
326  (Type == PrvVer?S->NextPkgProv:S->NextProvides);};
327  inline void operator ++() {operator ++(0);};
328 
329  // Accessors
330  inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
331  inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
332  inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
333  inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
334  inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
335 
336  bool IsMultiArchImplicit() const;
337 
338  inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
339  inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
340  Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
341  if (S == 0)
342  S = Owner.ProvideP;
343  };
344  inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
345  Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
346  if (S == 0)
347  S = Owner.ProvideP;
348  };
349 };
350  /*}}}*/
351 // Package file /*{{{*/
352 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
353  protected:
354  inline PackageFile* OwnerPointer() const {
355  return (Owner != 0) ? Owner->PkgFileP : 0;
356  };
357 
358  public:
359  // Iteration
360  void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
361  inline void operator ++() {operator ++(0);};
362 
363  // Accessors
364  inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
365  inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
366  inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
367  inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
368  inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
369  inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
370  inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
371  inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
372  inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
373  inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
374 
375  bool IsOk();
376  std::string RelStr();
377 
378  // Constructors
379  inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
380  inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
381  inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
382 };
383  /*}}}*/
384 // Version File /*{{{*/
385 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
386  protected:
387  inline VerFile* OwnerPointer() const {
388  return (Owner != 0) ? Owner->VerFileP : 0;
389  };
390 
391  public:
392  // Iteration
393  void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
394  inline void operator ++() {operator ++(0);};
395 
396  // Accessors
397  inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
398 
399  inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
400  inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
401 };
402  /*}}}*/
403 // Description File /*{{{*/
404 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
405  protected:
406  inline DescFile* OwnerPointer() const {
407  return (Owner != 0) ? Owner->DescFileP : 0;
408  };
409 
410  public:
411  // Iteration
412  void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
413  inline void operator ++() {operator ++(0);};
414 
415  // Accessors
416  inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
417 
418  inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
419  inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
420 };
421  /*}}}*/
422 // Inlined Begin functions cant be in the class because of order problems /*{{{*/
423 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
424  {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
425 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
426  {return VerIterator(*Owner,Owner->VerP + S->VersionList);};
427 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
428  {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
429 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
430  {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
431 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
432  {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
433 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
434  {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
435 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
436  {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
437 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
438  {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
439 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
440  {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
441 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
442  {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
443  /*}}}*/
444 #endif