]> git.saurik.com Git - apt.git/blame - apt-pkg/tagfile.cc
Sync
[apt.git] / apt-pkg / tagfile.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
6c139d6e 3// $Id: tagfile.cc,v 1.5 1998/07/07 04:17:06 jgg Exp $
578bfd0a
AL
4/* ######################################################################
5
6 Fast scanner for RFC-822 type header information
7
8 This uses a rotating 64K buffer to load the package information into.
9 The scanner runs over it and isolates and indexes a single section.
10
11 ##################################################################### */
12 /*}}}*/
13// Include Files /*{{{*/
6c139d6e
AL
14#ifdef __GNUG__
15#pragma implementation "pkglib/tagfile.h"
16#endif
17
578bfd0a
AL
18#include <pkglib/tagfile.h>
19#include <pkglib/error.h>
20
21#include <string>
22#include <stdio.h>
23 /*}}}*/
24
25// TagFile::pkgTagFile - Constructor /*{{{*/
26// ---------------------------------------------------------------------
27/* */
28pkgTagFile::pkgTagFile(File &Fd) : Fd(Fd)
29{
30 Buffer = new char[64*1024];
31 Start = End = Buffer + 64*1024;
32 Left = Fd.Size();
dcb79bae 33 iOffset = 0;
578bfd0a
AL
34 Fill();
35}
36 /*}}}*/
37// TagFile::Step - Advance to the next section /*{{{*/
38// ---------------------------------------------------------------------
39/* If the Section Scanner fails we refill the buffer and try again. */
40bool pkgTagFile::Step(pkgTagSection &Tag)
41{
42 if (Tag.Scan(Start,End - Start) == false)
43 {
44 if (Fill() == false)
45 return false;
46
47 if (Tag.Scan(Start,End - Start) == false)
48 return _error->Error("Unable to parse package file");
49 }
dcb79bae
AL
50 Start += Tag.size();
51 iOffset += Tag.size();
52
578bfd0a
AL
53 return true;
54}
55 /*}}}*/
56// TagFile::Fill - Top up the buffer /*{{{*/
57// ---------------------------------------------------------------------
58/* This takes the bit at the end of the buffer and puts it at the start
59 then fills the rest from the file */
60bool pkgTagFile::Fill()
61{
62 unsigned long Size = End - Start;
63
64 if (Left == 0)
65 {
66 if (Size <= 1)
67 return false;
68 return true;
69 }
70
71 memmove(Buffer,Start,Size);
72 Start = Buffer;
73
74 // See if only a bit of the file is left or if
75 if (Left < End - Buffer - Size)
76 {
77 if (Fd.Read(Buffer + Size,Left) == false)
78 return false;
79 End = Buffer + Size + Left;
80 Left = 0;
81 }
82 else
83 {
84 if (Fd.Read(Buffer + Size, End - Buffer - Size) == false)
85 return false;
86 Left -= End - Buffer - Size;
87 }
88 return true;
89}
90 /*}}}*/
91// TagSection::Scan - Scan for the end of the header information /*{{{*/
92// ---------------------------------------------------------------------
93/* This looks for the first double new line in the data stream. It also
94 indexes the tags in the section. */
95bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
96{
97 const char *End = Start + MaxLength;
98 Stop = Section = Start;
99
100 TagCount = 0;
101 Indexes[TagCount++] = Stop - Section;
102 Stop++;
103 for (; Stop < End; Stop++)
104 {
105 if (Stop[-1] != '\n')
106 continue;
107 if (Stop[0] == '\n')
108 {
109 // Extra one at the end to simplify find
110 Indexes[TagCount] = Stop - Section;
111 for (; Stop[0] == '\n' && Stop < End; Stop++);
112 return true;
113 break;
114 }
115
116 if (isspace(Stop[0]) == 0)
117 Indexes[TagCount++] = Stop - Section;
118
119 // Just in case.
120 if (TagCount > sizeof(Indexes)/sizeof(Indexes[0]))
121 TagCount = sizeof(Indexes)/sizeof(Indexes[0]);
122 }
123 return false;
124}
125 /*}}}*/
126// TagSection::Find - Locate a tag /*{{{*/
127// ---------------------------------------------------------------------
128/* This searches the section for a tag that matches the given string. */
129bool pkgTagSection::Find(const char *Tag,const char *&Start,
130 const char *&End)
131{
132 unsigned int Length = strlen(Tag);
133 for (unsigned int I = 0; I != TagCount; I++)
134 {
135 if (strncasecmp(Tag,Section + Indexes[I],Length) != 0)
136 continue;
137
138 // Make sure the colon is in the right place
139 const char *C = Section + Length + Indexes[I];
140 for (; isspace(*C) != 0; C++);
141 if (*C != ':')
142 continue;
143
144 // Strip off the gunk from the start end
145 Start = C;
146 End = Section + Indexes[I+1];
147 for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
148 for (; isspace(End[-1]) != 0 && End > Start; End--);
149 return true;
150 }
151 Start = End = 0;
152 return false;
153}
154 /*}}}*/
155
156#include <pkglib/pkgcachegen.h>
f55a958f 157#include <pkglib/deblistparser.h>
578bfd0a
AL
158
159int main(int argc,char *argv[])
160{
161 {
578bfd0a
AL
162 File CacheF("./cache",File::WriteEmpty);
163 DynamicMMap Map(CacheF,MMap::Public);
164 pkgCacheGenerator Gen(Map);
578bfd0a 165
dcb79bae
AL
166 for (int I = 1; I != argc; I++)
167 {
168 cout << "Merging in " << argv[I] << endl;
169 File F(argv[I],File::ReadOnly);
170 Gen.SelectFile(argv[I]);
171 debListParser Parser(F);
172 Gen.MergeList(Parser);
173 }
174 }
175/*
f55a958f
AL
176 {
177 File CacheF("./cache",File::WriteExists);
0149949b 178 MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
f55a958f
AL
179 pkgCache Cache(Map);
180 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
181 {
182 cout << "Package: " << I.Name() << endl;
0149949b
AL
183 for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
184 {
185 cout << "Version: " << V.VerStr() << endl;
186 cout << "Size: " << V->Size << endl;
187 cout << "Installed-Size: " << V->InstalledSize << endl;
188 cout << "Section: " << V.Section() << endl;
189 cout << "Priority: " << Cache.Priority(V->Priority) << endl;
dcb79bae
AL
190
191 pkgCache::PrvIterator P = V.ProvidesList();
192 if (P.end() == false)
193 {
194 cout << "Provides: ";
195 for (; P.end() == false; P++)
196 cout << P.Name() << ", ";
197 cout << endl;
198 }
199 }
0149949b
AL
200 cout << endl;
201 }
f55a958f 202 }
dcb79bae 203*/
578bfd0a
AL
204#if 0
205 pkgTagSection I;
206 while (Test.Step(I) == true)
207 {
208 const char *Start;
209 const char *End;
210 if (I.Find("Package",Start,End) == false)
211 {
212 cout << "Failed" << endl;
213 continue;
214 }
215
216 cout << "Package: " << string(Start,End - Start) << endl;
217
218/* for (const char *I = Start; I < End; I++)
219 {
220 const char *Begin = I;
221 bool Number = true;
222 while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End)
223 {
224 if (isalpha(*I) != 0)
225 Number = false;
226 I++;
227 }
228 if (Number == false)
229 cout << string(Begin,I-Begin) << endl;
230 while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End)
231 I++;
232 I--;
233 } */
234 }
235#endif
236 _error->DumpErrors();
237}