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