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