apt  0.9.7.1ubuntu2
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  std::string RelStr() const;
224 
225  bool Automatic() const;
226  VerFileIterator NewestFile() const;
227 
228  inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
229  if (S == 0)
230  S = OwnerPointer();
231  };
232  inline VerIterator() : Iterator<Version, VerIterator>() {};
233 };
234  /*}}}*/
235 // Description Iterator /*{{{*/
236 class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
237  protected:
238  inline Description* OwnerPointer() const {
239  return (Owner != 0) ? Owner->DescP : 0;
240  };
241 
242  public:
243  // Iteration
244  void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
245  inline void operator ++() {operator ++(0);};
246 
247  // Comparison
248  int CompareDesc(const DescIterator &B) const;
249 
250  // Accessors
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;
254 
255  inline DescIterator() : Iterator<Description, DescIterator>() {};
256  inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
257  if (S == 0)
258  S = Owner.DescP;
259  };
260 };
261  /*}}}*/
262 // Dependency iterator /*{{{*/
263 class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
264  enum {DepVer, DepRev} Type;
265 
266  protected:
267  inline Dependency* OwnerPointer() const {
268  return (Owner != 0) ? Owner->DepP : 0;
269  };
270 
271  public:
272  // Iteration
273  void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
274  (Type == DepVer ? S->NextDepends : S->NextRevDepends);};
275  inline void operator ++() {operator ++(0);};
276 
277  // Accessors
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  bool IsMultiArchImplicit() const;
289  void GlobOr(DepIterator &Start,DepIterator &End);
290  Version **AllTargets() const;
291  bool SmartTargetPkg(PkgIterator &Result) const;
292  inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
293  inline const char *DepType() const {return Owner->DepType(S->Type);};
294 
295  //Nice printable representation
296  friend std::ostream& operator <<(std::ostream& out, DepIterator D);
297 
298  inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
299  Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
300  if (S == 0)
301  S = Owner.DepP;
302  };
303  inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
304  Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
305  if (S == 0)
306  S = Owner.DepP;
307  };
308  inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
309 };
310  /*}}}*/
311 // Provides iterator /*{{{*/
312 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
313  enum {PrvVer, PrvPkg} Type;
314 
315  protected:
316  inline Provides* OwnerPointer() const {
317  return (Owner != 0) ? Owner->ProvideP : 0;
318  };
319 
320  public:
321  // Iteration
322  void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
323  (Type == PrvVer?S->NextPkgProv:S->NextProvides);};
324  inline void operator ++() {operator ++(0);};
325 
326  // Accessors
327  inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
328  inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
329  inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
330  inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
331  inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
332 
333  bool IsMultiArchImplicit() const;
334 
335  inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
336  inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
337  Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
338  if (S == 0)
339  S = Owner.ProvideP;
340  };
341  inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
342  Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
343  if (S == 0)
344  S = Owner.ProvideP;
345  };
346 };
347  /*}}}*/
348 // Package file /*{{{*/
349 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
350  protected:
351  inline PackageFile* OwnerPointer() const {
352  return (Owner != 0) ? Owner->PkgFileP : 0;
353  };
354 
355  public:
356  // Iteration
357  void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
358  inline void operator ++() {operator ++(0);};
359 
360  // Accessors
361  inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
362  inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
363  inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
364  inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
365  inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
366  inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
367  inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
368  inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
369  inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
370  inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
371 
372  bool IsOk();
373  std::string RelStr();
374 
375  // Constructors
376  inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
377  inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
378  inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
379 };
380  /*}}}*/
381 // Version File /*{{{*/
382 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
383  protected:
384  inline VerFile* OwnerPointer() const {
385  return (Owner != 0) ? Owner->VerFileP : 0;
386  };
387 
388  public:
389  // Iteration
390  void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
391  inline void operator ++() {operator ++(0);};
392 
393  // Accessors
394  inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
395 
396  inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
397  inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
398 };
399  /*}}}*/
400 // Description File /*{{{*/
401 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
402  protected:
403  inline DescFile* OwnerPointer() const {
404  return (Owner != 0) ? Owner->DescFileP : 0;
405  };
406 
407  public:
408  // Iteration
409  void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
410  inline void operator ++() {operator ++(0);};
411 
412  // Accessors
413  inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};
414 
415  inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
416  inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
417 };
418  /*}}}*/
419 // Inlined Begin functions cant be in the class because of order problems /*{{{*/
420 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
421  {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
422 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
423  {return VerIterator(*Owner,Owner->VerP + S->VersionList);};
424 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
425  {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
426 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
427  {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
428 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
429  {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
430 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
431  {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
432 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
433  {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
434 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
435  {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
436 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
437  {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
438 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
439  {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
440  /*}}}*/
441 #endif