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