]> git.saurik.com Git - apt.git/blob - apt-pkg/cacheiterators.h
301da6fc495a0c57099f22d4980039827262ac03
[apt.git] / apt-pkg / 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<apt-pkg/pkgcache.h>
33 #include<apt-pkg/macros.h>
34
35 #include<iterator>
36 #include <iosfwd>
37 #include <string>
38
39 #include<string.h>
40
41 // abstract Iterator template /*{{{*/
42 /* This template provides the very basic iterator methods we
43 need to have for doing some walk-over-the-cache magic */
44 template<typename Str, typename Itr> class pkgCache::Iterator :
45 public std::iterator<std::forward_iterator_tag, Str> {
46 protected:
47 Str *S;
48 pkgCache *Owner;
49
50 /** \brief Returns the Pointer for this struct in the owner
51 * The implementation of this method should be pretty short
52 * as it will only return the Pointer into the mmap stored
53 * in the owner but the name of this pointer is different for
54 * each structure and we want to abstract here at least for the
55 * basic methods from the actual structure.
56 * \return Pointer to the first structure of this type
57 */
58 virtual Str* OwnerPointer() const = 0;
59
60 public:
61 // Iteration
62 virtual void operator ++(int) = 0;
63 virtual void operator ++() = 0; // Should be {operator ++(0);}
64 inline bool end() const {return Owner == 0 || S == OwnerPointer();}
65
66 // Comparison
67 inline bool operator ==(const Itr &B) const {return S == B.S;}
68 inline bool operator !=(const Itr &B) const {return S != B.S;}
69
70 // Accessors
71 inline Str *operator ->() {return S;}
72 inline Str const *operator ->() const {return S;}
73 inline operator Str *() {return S == OwnerPointer() ? 0 : S;}
74 inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;}
75 inline Str &operator *() {return *S;}
76 inline Str const &operator *() const {return *S;}
77 inline pkgCache *Cache() const {return Owner;}
78
79 // Mixed stuff
80 inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;}
81 inline bool IsGood() const { return S && Owner && ! end();}
82 inline unsigned long Index() const {return S - OwnerPointer();}
83
84 void ReMap(void const * const oldMap, void const * const newMap) {
85 if (Owner == 0 || S == 0)
86 return;
87 S += (Str const * const)(newMap) - (Str const * const)(oldMap);
88 }
89
90 // Constructors - look out for the variable assigning
91 inline Iterator() : S(0), Owner(0) {}
92 inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {}
93 };
94 /*}}}*/
95 // Group Iterator /*{{{*/
96 /* Packages with the same name are collected in a Group so someone only
97 interest in package names can iterate easily over the names, so the
98 different architectures can be treated as of the "same" package
99 (apt internally treat them as totally different packages) */
100 class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
101 long HashIndex;
102
103 protected:
104 inline Group* OwnerPointer() const {
105 return (Owner != 0) ? Owner->GrpP : 0;
106 }
107
108 public:
109 // This constructor is the 'begin' constructor, never use it.
110 inline GrpIterator(pkgCache &Owner) : Iterator<Group, GrpIterator>(Owner), HashIndex(-1) {
111 S = OwnerPointer();
112 operator ++(0);
113 }
114
115 virtual void operator ++(int);
116 virtual void operator ++() {operator ++(0);}
117
118 inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}
119 inline PkgIterator PackageList() const;
120 PkgIterator FindPkg(std::string Arch = "any") const;
121 /** \brief find the package with the "best" architecture
122
123 The best architecture is either the "native" or the first
124 in the list of Architectures which is not an end-Pointer
125
126 \param PreferNonVirtual tries to respond with a non-virtual package
127 and only if this fails returns the best virtual package */
128 PkgIterator FindPreferredPkg(bool const &PreferNonVirtual = true) const;
129 PkgIterator NextPkg(PkgIterator const &Pkg) const;
130
131 // Constructors
132 inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
133 if (S == 0)
134 S = OwnerPointer();
135 }
136 inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {}
137
138 };
139 /*}}}*/
140 // Package Iterator /*{{{*/
141 class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
142 long HashIndex;
143
144 protected:
145 inline Package* OwnerPointer() const {
146 return (Owner != 0) ? Owner->PkgP : 0;
147 }
148
149 public:
150 // This constructor is the 'begin' constructor, never use it.
151 inline PkgIterator(pkgCache &Owner) : Iterator<Package, PkgIterator>(Owner), HashIndex(-1) {
152 S = OwnerPointer();
153 operator ++(0);
154 }
155
156 virtual void operator ++(int);
157 virtual void operator ++() {operator ++(0);}
158
159 enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
160
161 // Accessors
162 inline const char *Name() const { return Group().Name(); }
163 // Versions have sections - and packages can have different versions with different sections
164 // so this interface is broken by design. Run as fast as you can to Version.Section().
165 APT_DEPRECATED inline const char *Section() const {
166 APT_IGNORE_DEPRECATED_PUSH
167 return S->Section == 0?0:Owner->StrP + S->Section;
168 APT_IGNORE_DEPRECATED_POP
169 }
170 inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
171 (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);}
172 inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}
173 inline APT_PURE GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);}
174
175 inline VerIterator VersionList() const APT_PURE;
176 inline VerIterator CurrentVer() const APT_PURE;
177 inline DepIterator RevDependsList() const APT_PURE;
178 inline PrvIterator ProvidesList() const APT_PURE;
179 OkState State() const APT_PURE;
180 const char *CandVersion() const APT_PURE;
181 const char *CurVersion() const APT_PURE;
182
183 //Nice printable representation
184 friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
185 std::string FullName(bool const &Pretty = false) const;
186
187 // Constructors
188 inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator<Package, PkgIterator>(Owner, Trg), HashIndex(0) {
189 if (S == 0)
190 S = OwnerPointer();
191 }
192 inline PkgIterator() : Iterator<Package, PkgIterator>(), HashIndex(0) {}
193 };
194 /*}}}*/
195 // Version Iterator /*{{{*/
196 class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
197 protected:
198 inline Version* OwnerPointer() const {
199 return (Owner != 0) ? Owner->VerP : 0;
200 }
201
202 public:
203 // Iteration
204 void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;}
205 inline void operator ++() {operator ++(0);}
206
207 // Comparison
208 int CompareVer(const VerIterator &B) const;
209 /** \brief compares two version and returns if they are similar
210
211 This method should be used to identify if two pseudo versions are
212 referring to the same "real" version */
213 inline bool SimilarVer(const VerIterator &B) const {
214 return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0);
215 }
216
217 // Accessors
218 inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}
219 inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}
220 #if APT_PKG_ABI >= 413
221 /** \brief source package name this version comes from
222 Always contains the name, even if it is the same as the binary name */
223 inline const char *SourcePkgName() const {return Owner->StrP + S->SourcePkgName;}
224 /** \brief source version this version comes from
225 Always contains the version string, even if it is the same as the binary version */
226 inline const char *SourceVerStr() const {return Owner->StrP + S->SourceVerStr;}
227 #endif
228 inline const char *Arch() const {
229 if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All)
230 return "all";
231 return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
232 }
233 inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}
234
235 inline DescIterator DescriptionList() const;
236 DescIterator TranslatedDescription() const;
237 inline DepIterator DependsList() const;
238 inline PrvIterator ProvidesList() const;
239 inline VerFileIterator FileList() const;
240 bool Downloadable() const;
241 inline const char *PriorityType() const {return Owner->Priority(S->Priority);}
242 const char *MultiArchType() const APT_PURE;
243 std::string RelStr() const;
244
245 bool Automatic() const;
246 VerFileIterator NewestFile() const;
247
248 inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
249 if (S == 0)
250 S = OwnerPointer();
251 }
252 inline VerIterator() : Iterator<Version, VerIterator>() {}
253 };
254 /*}}}*/
255 // Description Iterator /*{{{*/
256 class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
257 protected:
258 inline Description* OwnerPointer() const {
259 return (Owner != 0) ? Owner->DescP : 0;
260 }
261
262 public:
263 // Iteration
264 void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;}
265 inline void operator ++() {operator ++(0);}
266
267 // Comparison
268 int CompareDesc(const DescIterator &B) const;
269
270 // Accessors
271 inline const char *LanguageCode() const {return Owner->StrP + S->language_code;}
272 inline const char *md5() const {return Owner->StrP + S->md5sum;}
273 inline DescFileIterator FileList() const;
274
275 inline DescIterator() : Iterator<Description, DescIterator>() {}
276 inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
277 if (S == 0)
278 S = Owner.DescP;
279 }
280 };
281 /*}}}*/
282 // Dependency iterator /*{{{*/
283 class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
284 enum {DepVer, DepRev} Type;
285
286 protected:
287 inline Dependency* OwnerPointer() const {
288 return (Owner != 0) ? Owner->DepP : 0;
289 }
290
291 public:
292 // Iteration
293 void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
294 (Type == DepVer ? S->NextDepends : S->NextRevDepends);}
295 inline void operator ++() {operator ++(0);}
296
297 // Accessors
298 inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;}
299 inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);}
300 inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}
301 inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);}
302 inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);}
303 inline bool Reverse() const {return Type == DepRev;}
304 bool IsCritical() const APT_PURE;
305 bool IsNegative() const APT_PURE;
306 bool IsIgnorable(PrvIterator const &Prv) const APT_PURE;
307 bool IsIgnorable(PkgIterator const &Pkg) const APT_PURE;
308 bool IsMultiArchImplicit() const APT_PURE;
309 bool IsSatisfied(VerIterator const &Ver) const APT_PURE;
310 bool IsSatisfied(PrvIterator const &Prv) const APT_PURE;
311 void GlobOr(DepIterator &Start,DepIterator &End);
312 Version **AllTargets() const;
313 bool SmartTargetPkg(PkgIterator &Result) const;
314 inline const char *CompType() const {return Owner->CompType(S->CompareOp);}
315 inline const char *DepType() const {return Owner->DepType(S->Type);}
316
317 //Nice printable representation
318 friend std::ostream& operator <<(std::ostream& out, DepIterator D);
319
320 inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
321 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
322 if (S == 0)
323 S = Owner.DepP;
324 }
325 inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
326 Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
327 if (S == 0)
328 S = Owner.DepP;
329 }
330 inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {}
331 };
332 /*}}}*/
333 // Provides iterator /*{{{*/
334 class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
335 enum {PrvVer, PrvPkg} Type;
336
337 protected:
338 inline Provides* OwnerPointer() const {
339 return (Owner != 0) ? Owner->ProvideP : 0;
340 }
341
342 public:
343 // Iteration
344 void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
345 (Type == PrvVer?S->NextPkgProv:S->NextProvides);}
346 inline void operator ++() {operator ++(0);}
347
348 // Accessors
349 inline const char *Name() const {return ParentPkg().Name();}
350 inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;}
351 inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}
352 inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);}
353 inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);}
354
355 bool IsMultiArchImplicit() const APT_PURE;
356
357 inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {}
358 inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
359 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
360 if (S == 0)
361 S = Owner.ProvideP;
362 }
363 inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
364 Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
365 if (S == 0)
366 S = Owner.ProvideP;
367 }
368 };
369 /*}}}*/
370 // Release file /*{{{*/
371 class pkgCache::RlsFileIterator : public Iterator<ReleaseFile, RlsFileIterator> {
372 protected:
373 inline ReleaseFile* OwnerPointer() const {
374 return (Owner != 0) ? Owner->RlsFileP : 0;
375 }
376
377 public:
378 // Iteration
379 void operator ++(int) {if (S != Owner->RlsFileP) S = Owner->RlsFileP + S->NextFile;}
380 inline void operator ++() {operator ++(0);}
381
382 // Accessors
383 inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}
384 inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;}
385 inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;}
386 inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;}
387 inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;}
388 inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;}
389 inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;}
390 inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return (S->Flags & flag) == flag; }
391
392 bool IsOk();
393 std::string RelStr();
394
395 // Constructors
396 inline RlsFileIterator() : Iterator<ReleaseFile, RlsFileIterator>() {}
397 inline RlsFileIterator(pkgCache &Owner) : Iterator<ReleaseFile, RlsFileIterator>(Owner, Owner.RlsFileP) {}
398 inline RlsFileIterator(pkgCache &Owner,ReleaseFile *Trg) : Iterator<ReleaseFile, RlsFileIterator>(Owner, Trg) {}
399 };
400 /*}}}*/
401 // Package file /*{{{*/
402 class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
403 protected:
404 inline PackageFile* OwnerPointer() const {
405 return (Owner != 0) ? Owner->PkgFileP : 0;
406 }
407
408 public:
409 // Iteration
410 void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;}
411 inline void operator ++() {operator ++(0);}
412
413 // Accessors
414 inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}
415 inline pkgCache::RlsFileIterator ReleaseFile() const {return RlsFileIterator(*Owner, Owner->RlsFileP + S->Release);}
416 inline const char *Archive() const {return S->Release == 0 ? Component() : ReleaseFile().Archive();}
417 inline const char *Version() const {return S->Release == 0 ? NULL : ReleaseFile().Version();}
418 inline const char *Origin() const {return S->Release == 0 ? NULL : ReleaseFile().Origin();}
419 inline const char *Codename() const {return S->Release == 0 ? NULL : ReleaseFile().Codename();}
420 inline const char *Label() const {return S->Release == 0 ? NULL : ReleaseFile().Label();}
421 inline const char *Site() const {return S->Release == 0 ? NULL : ReleaseFile().Site();}
422 inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return S->Release== 0 ? false : ReleaseFile().Flagged(flag);}
423 inline bool Flagged(pkgCache::Flag::PkgFFlags const flag) const {return (S->Flags & flag) == flag;}
424 inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;}
425 inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;}
426 inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;}
427
428 bool IsOk();
429 std::string RelStr();
430
431 // Constructors
432 inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {}
433 inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {}
434 inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {}
435 };
436 /*}}}*/
437 // Version File /*{{{*/
438 class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
439 protected:
440 inline VerFile* OwnerPointer() const {
441 return (Owner != 0) ? Owner->VerFileP : 0;
442 }
443
444 public:
445 // Iteration
446 void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;}
447 inline void operator ++() {operator ++(0);}
448
449 // Accessors
450 inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);}
451
452 inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {}
453 inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {}
454 };
455 /*}}}*/
456 // Description File /*{{{*/
457 class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
458 protected:
459 inline DescFile* OwnerPointer() const {
460 return (Owner != 0) ? Owner->DescFileP : 0;
461 }
462
463 public:
464 // Iteration
465 void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;}
466 inline void operator ++() {operator ++(0);}
467
468 // Accessors
469 inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);}
470
471 inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {}
472 inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {}
473 };
474 /*}}}*/
475 // Inlined Begin functions can't be in the class because of order problems /*{{{*/
476 inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
477 {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);}
478 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
479 {return VerIterator(*Owner,Owner->VerP + S->VersionList);}
480 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
481 {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);}
482 inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
483 {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);}
484 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
485 {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);}
486 inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
487 {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);}
488 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
489 {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);}
490 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
491 {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);}
492 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
493 {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);}
494 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
495 {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);}
496 /*}}}*/
497 #endif