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