1 // -*- mode: cpp; mode: fold -*-
3 // $Id: tagfile.cc,v 1.2 1998/07/04 05:57:39 jgg Exp $
4 /* ######################################################################
6 Fast scanner for RFC-822 type header information
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.
11 ##################################################################### */
13 // Include Files /*{{{*/
14 #include <pkglib/tagfile.h>
15 #include <pkglib/error.h>
21 // TagFile::pkgTagFile - Constructor /*{{{*/
22 // ---------------------------------------------------------------------
24 pkgTagFile::pkgTagFile(File
&Fd
) : Fd(Fd
)
26 Buffer
= new char[64*1024];
27 Start
= End
= Buffer
+ 64*1024;
32 // TagFile::Step - Advance to the next section /*{{{*/
33 // ---------------------------------------------------------------------
34 /* If the Section Scanner fails we refill the buffer and try again. */
35 bool pkgTagFile::Step(pkgTagSection
&Tag
)
37 if (Tag
.Scan(Start
,End
- Start
) == false)
42 if (Tag
.Scan(Start
,End
- Start
) == false)
43 return _error
->Error("Unable to parse package file");
45 Start
+= Tag
.Length();
49 // TagFile::Fill - Top up the buffer /*{{{*/
50 // ---------------------------------------------------------------------
51 /* This takes the bit at the end of the buffer and puts it at the start
52 then fills the rest from the file */
53 bool pkgTagFile::Fill()
55 unsigned long Size
= End
- Start
;
64 memmove(Buffer
,Start
,Size
);
67 // See if only a bit of the file is left or if
68 if (Left
< End
- Buffer
- Size
)
70 if (Fd
.Read(Buffer
+ Size
,Left
) == false)
72 End
= Buffer
+ Size
+ Left
;
77 if (Fd
.Read(Buffer
+ Size
, End
- Buffer
- Size
) == false)
79 Left
-= End
- Buffer
- Size
;
84 // TagSection::Scan - Scan for the end of the header information /*{{{*/
85 // ---------------------------------------------------------------------
86 /* This looks for the first double new line in the data stream. It also
87 indexes the tags in the section. */
88 bool pkgTagSection::Scan(const char *Start
,unsigned long MaxLength
)
90 const char *End
= Start
+ MaxLength
;
91 Stop
= Section
= Start
;
94 Indexes
[TagCount
++] = Stop
- Section
;
96 for (; Stop
< End
; Stop
++)
102 // Extra one at the end to simplify find
103 Indexes
[TagCount
] = Stop
- Section
;
104 for (; Stop
[0] == '\n' && Stop
< End
; Stop
++);
109 if (isspace(Stop
[0]) == 0)
110 Indexes
[TagCount
++] = Stop
- Section
;
113 if (TagCount
> sizeof(Indexes
)/sizeof(Indexes
[0]))
114 TagCount
= sizeof(Indexes
)/sizeof(Indexes
[0]);
119 // TagSection::Find - Locate a tag /*{{{*/
120 // ---------------------------------------------------------------------
121 /* This searches the section for a tag that matches the given string. */
122 bool pkgTagSection::Find(const char *Tag
,const char *&Start
,
125 unsigned int Length
= strlen(Tag
);
126 for (unsigned int I
= 0; I
!= TagCount
; I
++)
128 if (strncasecmp(Tag
,Section
+ Indexes
[I
],Length
) != 0)
131 // Make sure the colon is in the right place
132 const char *C
= Section
+ Length
+ Indexes
[I
];
133 for (; isspace(*C
) != 0; C
++);
137 // Strip off the gunk from the start end
139 End
= Section
+ Indexes
[I
+1];
140 for (; (isspace(*Start
) != 0 || *Start
== ':') && Start
< End
; Start
++);
141 for (; isspace(End
[-1]) != 0 && End
> Start
; End
--);
149 #include <pkglib/pkgcachegen.h>
150 #include <pkglib/deblistparser.h>
152 int main(int argc
,char *argv
[])
155 File
F(argv
[1],File::ReadOnly
);
156 File
CacheF("./cache",File::WriteEmpty
);
157 DynamicMMap
Map(CacheF
,MMap::Public
);
158 pkgCacheGenerator
Gen(Map
);
159 Gen
.SelectFile(argv
[1]);
161 debListParser
Parser(F
);
162 Gen
.MergeList(Parser
);
166 File
CacheF("./cache",File::WriteExists
);
167 MMap
Map(CacheF
,MMap::Public
);
169 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
171 cout
<< "Package: " << I
.Name() << endl
;
177 while (Test
.Step(I
) == true)
181 if (I
.Find("Package",Start
,End
) == false)
183 cout
<< "Failed" << endl
;
187 cout
<< "Package: " << string(Start
,End
- Start
) << endl
;
189 /* for (const char *I = Start; I < End; I++)
191 const char *Begin = I;
193 while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End)
195 if (isalpha(*I) != 0)
200 cout << string(Begin,I-Begin) << endl;
201 while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End)
207 _error
->DumpErrors();