// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: tagfile.cc,v 1.4 1998/07/05 05:33:58 jgg Exp $
+// $Id: tagfile.cc,v 1.15 1998/11/27 01:14:06 jgg Exp $
/* ######################################################################
Fast scanner for RFC-822 type header information
- This uses a rotating 64K buffer to load the package information into.
+ This uses a rotating buffer to load the package information into.
The scanner runs over it and isolates and indexes a single section.
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
-#include <pkglib/tagfile.h>
-#include <pkglib/error.h>
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/tagfile.h"
+#endif
+
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/error.h>
#include <string>
#include <stdio.h>
// TagFile::pkgTagFile - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-pkgTagFile::pkgTagFile(File &Fd) : Fd(Fd)
+pkgTagFile::pkgTagFile(FileFd &Fd,unsigned long Size) : Fd(Fd), Size(Size)
{
- Buffer = new char[64*1024];
- Start = End = Buffer + 64*1024;
+ Buffer = new char[Size];
+ Start = End = Buffer;
Left = Fd.Size();
iOffset = 0;
Fill();
then fills the rest from the file */
bool pkgTagFile::Fill()
{
- unsigned long Size = End - Start;
+ unsigned long EndSize = End - Start;
if (Left == 0)
{
- if (Size <= 1)
+ if (EndSize <= 1)
return false;
return true;
}
- memmove(Buffer,Start,Size);
+ memmove(Buffer,Start,EndSize);
Start = Buffer;
+ End = Buffer + EndSize;
- // See if only a bit of the file is left or if
- if (Left < End - Buffer - Size)
+ // See if only a bit of the file is left
+ if (Left < Size - (End - Buffer))
{
- if (Fd.Read(Buffer + Size,Left) == false)
+ if (Fd.Read(End,Left) == false)
return false;
- End = Buffer + Size + Left;
+
+ End += Left;
Left = 0;
}
else
{
- if (Fd.Read(Buffer + Size, End - Buffer - Size) == false)
+ if (Fd.Read(End,Size - (End - Buffer)) == false)
return false;
- Left -= End - Buffer - Size;
+
+ Left -= Size - (End - Buffer);
+ End = Buffer + Size;
}
return true;
}
/*}}}*/
+// TagFile::Jump - Jump to a pre-recorded location in the file /*{{{*/
+// ---------------------------------------------------------------------
+/* This jumps to a pre-recorded file location and reads the record
+ that is there */
+bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
+{
+ iOffset = Offset;
+ Left = Fd.Size() - Offset;
+ if (Fd.Seek(Offset) == false)
+ return false;
+ End = Start = Buffer;
+
+ if (Fill() == false)
+ return false;
+
+ if (Tag.Scan(Start,End - Start) == false)
+ return _error->Error("Unable to parse package file");
+ return true;
+}
+ /*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
// ---------------------------------------------------------------------
/* This looks for the first double new line in the data stream. It also
{
if (Stop[-1] != '\n')
continue;
+
+ // Skip line feeds
+ for (; Stop[0] == '\r' && Stop < End; Stop++);
+
if (Stop[0] == '\n')
{
// Extra one at the end to simplify find
Indexes[TagCount] = Stop - Section;
- for (; Stop[0] == '\n' && Stop < End; Stop++);
+ for (; (Stop[0] == '\n' || Stop[0] == '\r') && Stop < End; Stop++);
return true;
- break;
}
if (isspace(Stop[0]) == 0)
End = Section + Indexes[I+1];
for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
for (; isspace(End[-1]) != 0 && End > Start; End--);
+
return true;
}
Start = End = 0;
return false;
}
/*}}}*/
-
-#include <pkglib/pkgcachegen.h>
-#include <pkglib/deblistparser.h>
-
-int main(int argc,char *argv[])
+// pkgTagSection::FindS - Find a string /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string pkgTagSection::FindS(const char *Tag)
{
- {
- File CacheF("./cache",File::WriteEmpty);
- DynamicMMap Map(CacheF,MMap::Public);
- pkgCacheGenerator Gen(Map);
-
- for (int I = 1; I != argc; I++)
- {
- cout << "Merging in " << argv[I] << endl;
- File F(argv[I],File::ReadOnly);
- Gen.SelectFile(argv[I]);
- debListParser Parser(F);
- Gen.MergeList(Parser);
- }
- }
-/*
- {
- File CacheF("./cache",File::WriteExists);
- MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
- pkgCache Cache(Map);
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
- {
- cout << "Package: " << I.Name() << endl;
- for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
- {
- cout << "Version: " << V.VerStr() << endl;
- cout << "Size: " << V->Size << endl;
- cout << "Installed-Size: " << V->InstalledSize << endl;
- cout << "Section: " << V.Section() << endl;
- cout << "Priority: " << Cache.Priority(V->Priority) << endl;
-
- pkgCache::PrvIterator P = V.ProvidesList();
- if (P.end() == false)
- {
- cout << "Provides: ";
- for (; P.end() == false; P++)
- cout << P.Name() << ", ";
- cout << endl;
- }
- }
- cout << endl;
- }
- }
-*/
-#if 0
- pkgTagSection I;
- while (Test.Step(I) == true)
- {
- const char *Start;
- const char *End;
- if (I.Find("Package",Start,End) == false)
- {
- cout << "Failed" << endl;
- continue;
- }
-
- cout << "Package: " << string(Start,End - Start) << endl;
-
-/* for (const char *I = Start; I < End; I++)
- {
- const char *Begin = I;
- bool Number = true;
- while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End)
- {
- if (isalpha(*I) != 0)
- Number = false;
- I++;
- }
- if (Number == false)
- cout << string(Begin,I-Begin) << endl;
- while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End)
- I++;
- I--;
- } */
- }
-#endif
- _error->DumpErrors();
+ const char *Start;
+ const char *End;
+ if (Find(Tag,Start,End) == false)
+ return string();
+ return string(Start,End);
+}
+ /*}}}*/
+// TagSection::FindI - Find an integer /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned int pkgTagSection::FindI(const char *Tag)
+{
+ const char *Start;
+ const char *End;
+ if (Find(Tag,Start,End) == false)
+ return 0;
+
+ return atoi(string(Start,End).c_str());
}
+ /*}}}*/