X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b7080ced608f012aee2566afc724c3727e75fc1b..0aae6d14390193e25ab6d0fd49295bd7b131954f:/apt-pkg/tagfile.cc?ds=sidebyside diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 4a2f3f7e6..aa0f1eee8 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -11,39 +11,64 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include +#include -#include - #include #include #include + +#include /*}}}*/ using std::string; +class pkgTagFilePrivate +{ +public: + pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Buffer(NULL), + Start(NULL), End(NULL), + Done(false), iOffset(0), + Size(Size) + { + } + FileFd &Fd; + char *Buffer; + char *Start; + char *End; + bool Done; + unsigned long long iOffset; + unsigned long long Size; +}; + // TagFile::pkgTagFile - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : - Fd(*pFd), - Size(Size) +pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size) { - if (Fd.IsOpen() == false) + /* The size is increased by 4 because if we start with the Size of the + filename we need to try to read 1 char more to see an EOF faster, 1 + char the end-pointer can be on and maybe 2 newlines need to be added + to the end of the file -> 4 extra chars */ + Size += 4; + d = new pkgTagFilePrivate(pFd, Size); + + if (d->Fd.IsOpen() == false) { - Buffer = 0; - Start = End = Buffer = 0; - Done = true; - iOffset = 0; + d->Start = d->End = d->Buffer = 0; + d->Done = true; + d->iOffset = 0; return; } - Buffer = new char[Size]; - Start = End = Buffer; - Done = false; - iOffset = 0; + d->Buffer = new char[Size]; + d->Start = d->End = d->Buffer; + d->Done = false; + d->iOffset = 0; Fill(); } /*}}}*/ @@ -52,7 +77,14 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : /* */ pkgTagFile::~pkgTagFile() { - delete [] Buffer; + delete [] d->Buffer; + delete d; +} + /*}}}*/ +// TagFile::Offset - Return the current offset in the buffer /*{{{*/ +unsigned long pkgTagFile::Offset() +{ + return d->iOffset; } /*}}}*/ // TagFile::Resize - Resize the internal buffer /*{{{*/ @@ -62,23 +94,27 @@ pkgTagFile::~pkgTagFile() */ bool pkgTagFile::Resize() { - char *tmp; - unsigned long EndSize = End - Start; - // fail is the buffer grows too big - if(Size > 1024*1024+1) + if(d->Size > 1024*1024+1) return false; + return Resize(d->Size * 2); +} +bool pkgTagFile::Resize(unsigned long long const newSize) +{ + unsigned long long const EndSize = d->End - d->Start; + char *tmp; + // get new buffer and use it - tmp = new char[2*Size]; - memcpy(tmp, Buffer, Size); - Size = Size*2; - delete [] Buffer; - Buffer = tmp; + tmp = new char[newSize]; + memcpy(tmp, d->Buffer, d->Size); + d->Size = newSize; + delete [] d->Buffer; + d->Buffer = tmp; // update the start/end pointers to the new buffer - Start = Buffer; - End = Start + EndSize; + d->Start = d->Buffer; + d->End = d->Start + EndSize; return true; } /*}}}*/ @@ -90,20 +126,20 @@ bool pkgTagFile::Resize() */ bool pkgTagFile::Step(pkgTagSection &Tag) { - while (Tag.Scan(Start,End - Start) == false) + while (Tag.Scan(d->Start,d->End - d->Start) == false) { if (Fill() == false) return false; - if(Tag.Scan(Start,End - Start)) + if(Tag.Scan(d->Start,d->End - d->Start)) break; if (Resize() == false) return _error->Error(_("Unable to parse package file %s (1)"), - Fd.Name().c_str()); + d->Fd.Name().c_str()); } - Start += Tag.size(); - iOffset += Tag.size(); + d->Start += Tag.size(); + d->iOffset += Tag.size(); Tag.Trim(); return true; @@ -115,37 +151,43 @@ bool pkgTagFile::Step(pkgTagSection &Tag) then fills the rest from the file */ bool pkgTagFile::Fill() { - unsigned long EndSize = End - Start; - unsigned long Actual = 0; + unsigned long long EndSize = d->End - d->Start; + unsigned long long Actual = 0; - memmove(Buffer,Start,EndSize); - Start = Buffer; - End = Buffer + EndSize; + memmove(d->Buffer,d->Start,EndSize); + d->Start = d->Buffer; + d->End = d->Buffer + EndSize; - if (Done == false) + if (d->Done == false) { // See if only a bit of the file is left - if (Fd.Read(End,Size - (End - Buffer),&Actual) == false) + unsigned long long const dataSize = d->Size - ((d->End - d->Buffer) + 1); + if (d->Fd.Read(d->End, dataSize, &Actual) == false) return false; - if (Actual != Size - (End - Buffer)) - Done = true; - End += Actual; + if (Actual != dataSize || d->Fd.Eof() == true) + d->Done = true; + d->End += Actual; } - if (Done == true) + if (d->Done == true) { if (EndSize <= 3 && Actual == 0) return false; - if (Size - (End - Buffer) < 4) + if (d->Size - (d->End - d->Buffer) < 4) return true; // Append a double new line if one does not exist unsigned int LineCount = 0; - for (const char *E = End - 1; E - End < 6 && (*E == '\n' || *E == '\r'); E--) + for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--) if (*E == '\n') LineCount++; - for (; LineCount < 2; LineCount++) - *End++ = '\n'; + if (LineCount < 2) + { + if ((unsigned)(d->End - d->Buffer) >= d->Size) + Resize(d->Size + 3); + for (; LineCount < 2; LineCount++) + *d->End++ = '\n'; + } return true; } @@ -157,36 +199,36 @@ bool pkgTagFile::Fill() // --------------------------------------------------------------------- /* This jumps to a pre-recorded file location and reads the record that is there */ -bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset) +bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset) { // We are within a buffer space of the next hit.. - if (Offset >= iOffset && iOffset + (End - Start) > Offset) + if (Offset >= d->iOffset && d->iOffset + (d->End - d->Start) > Offset) { - unsigned long Dist = Offset - iOffset; - Start += Dist; - iOffset += Dist; + unsigned long long Dist = Offset - d->iOffset; + d->Start += Dist; + d->iOffset += Dist; return Step(Tag); } // Reposition and reload.. - iOffset = Offset; - Done = false; - if (Fd.Seek(Offset) == false) + d->iOffset = Offset; + d->Done = false; + if (d->Fd.Seek(Offset) == false) return false; - End = Start = Buffer; + d->End = d->Start = d->Buffer; if (Fill() == false) return false; - if (Tag.Scan(Start,End - Start) == true) + if (Tag.Scan(d->Start, d->End - d->Start) == true) return true; // This appends a double new line (for the real eof handling) if (Fill() == false) return false; - if (Tag.Scan(Start,End - Start) == false) - return _error->Error(_("Unable to parse package file %s (2)"),Fd.Name().c_str()); + if (Tag.Scan(d->Start, d->End - d->Start) == false) + return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str()); return true; } @@ -255,10 +297,17 @@ void pkgTagSection::Trim() for (; Stop > Section + 2 && (Stop[-2] == '\n' || Stop[-2] == '\r'); Stop--); } /*}}}*/ +// TagSection::Exists - return True if a tag exists /*{{{*/ +bool pkgTagSection::Exists(const char* const Tag) +{ + unsigned int tmp; + return Find(Tag, tmp); +} + /*}}}*/ // TagSection::Find - Locate a tag /*{{{*/ // --------------------------------------------------------------------- /* This searches the section for a tag that matches the given string. */ -bool pkgTagSection::Find(const char *Tag,unsigned &Pos) const +bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const { unsigned int Length = strlen(Tag); unsigned int I = AlphaIndexes[AlphaHash(Tag)]; @@ -457,6 +506,7 @@ static const char *iTFRewritePackageOrder[] = { "MD5Sum", "SHA1", "SHA256", + "SHA512", "MSDOS-Filename", // Obsolete "Description", 0};