More fixes
[ntk/apt.git] / apt-pkg / srcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: srcrecords.cc,v 1.3 1999/10/18 04:15:24 jgg Exp $
4 /* ######################################################################
5
6 Source Package Records - Allows access to source package records
7
8 Parses and allows access to the list of source records and searching by
9 source name on that list.
10
11 ##################################################################### */
12 /*}}}*/
13 // Include Files /*{{{*/
14 #ifdef __GNUG__
15 #pragma implementation "apt-pkg/srcrecords.h"
16 #endif
17
18 #include <apt-pkg/srcrecords.h>
19 #include <apt-pkg/error.h>
20 #include <apt-pkg/configuration.h>
21 #include <apt-pkg/strutl.h>
22 #include <apt-pkg/debsrcrecords.h>
23 /*}}}*/
24
25 // SrcRecords::pkgSrcRecords - Constructor /*{{{*/
26 // ---------------------------------------------------------------------
27 /* Open all the source index files */
28 pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0)
29 {
30 pkgSourceList::const_iterator I = List.begin();
31
32 // Count how many items we will need
33 unsigned int Count = 0;
34 for (; I != List.end(); I++)
35 if (I->Type == pkgSourceList::Item::DebSrc)
36 Count++;
37
38 // Doesnt work without any source index files
39 if (Count == 0)
40 {
41 _error->Error("Sorry, you must put some 'source' uris"
42 " in your sources.list");
43 return;
44 }
45
46 Files = new Parser *[Count+1];
47 memset(Files,0,sizeof(*Files)*(Count+1));
48
49 // Create the parser objects
50 Count = 0;
51 string Dir = _config->FindDir("Dir::State::lists");
52 for (I = List.begin(); I != List.end(); I++)
53 {
54 if (I->Type != pkgSourceList::Item::DebSrc)
55 continue;
56
57 // Open the file
58 FileFd *FD = new FileFd(Dir + URItoFileName(I->PackagesURI()),
59 FileFd::ReadOnly);
60 if (_error->PendingError() == true)
61 {
62 delete FD;
63 return;
64 }
65
66 Files[Count] = new debSrcRecordParser(FD,I);
67 Count++;
68 }
69
70 Restart();
71 }
72 /*}}}*/
73 // SrcRecords::~pkgSrcRecords - Destructor /*{{{*/
74 // ---------------------------------------------------------------------
75 /* */
76 pkgSrcRecords::~pkgSrcRecords()
77 {
78 if (Files == 0)
79 return;
80
81 // Blow away all the parser objects
82 for (unsigned int Count = 0; Files[Count] != 0; Count++)
83 delete Files[Count];
84 }
85 /*}}}*/
86 // SrcRecords::Restart - Restart the search /*{{{*/
87 // ---------------------------------------------------------------------
88 /* Return all of the parsers to their starting position */
89 bool pkgSrcRecords::Restart()
90 {
91 Current = Files;
92 for (Parser **I = Files; *I != 0; I++)
93 (*I)->Restart();
94
95 return true;
96 }
97 /*}}}*/
98 // SrcRecords::Find - Find the first source package with the given name /*{{{*/
99 // ---------------------------------------------------------------------
100 /* This searches on both source package names and output binary names and
101 returns the first found. A 'cursor' like system is used to allow this
102 function to be called multiple times to get successive entries */
103 pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool SrcOnly)
104 {
105 if (*Current == 0)
106 return 0;
107
108 while (true)
109 {
110 // Step to the next record, possibly switching files
111 while ((*Current)->Step() == false)
112 {
113 if (_error->PendingError() == true)
114 return 0;
115 Current++;
116 if (*Current == 0)
117 return 0;
118 }
119
120 // IO error somehow
121 if (_error->PendingError() == true)
122 return 0;
123
124 // Source name hit
125 if ((*Current)->Package() == Package)
126 return *Current;
127
128 if (SrcOnly == true)
129 continue;
130
131 // Check for a binary hit
132 const char **I = (*Current)->Binaries();
133 for (; I != 0 && *I != 0; I++)
134 if (strcmp(Package,*I) == 0)
135 return *Current;
136 }
137 }
138 /*}}}*/
139