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