unsigned long long Size;
};
+class pkgTagSectionPrivate
+{
+public:
+ pkgTagSectionPrivate()
+ {
+ }
+ struct TagData {
+ unsigned int StartTag;
+ unsigned int EndTag;
+ unsigned int StartValue;
+ unsigned int NextInBucket;
+
+ TagData(unsigned int const StartTag) : StartTag(StartTag), EndTag(0), StartValue(0), NextInBucket(0) {}
+ };
+ std::vector<TagData> Tags;
+};
+
static unsigned long AlphaHash(const char *Text, size_t Length) /*{{{*/
{
/* This very simple hash function for the last 8 letters gives
break;
if (Resize() == false)
- return _error->Error(_("Unable to parse package file %s (1)"),
- d->Fd.Name().c_str());
+ return _error->Error(_("Unable to parse package file %s (%d)"),
+ d->Fd.Name().c_str(), 1);
} while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
}
return false;
if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
- return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str());
+ return _error->Error(_("Unable to parse package file %s (%d)"),d->Fd.Name().c_str(), 2);
return true;
}
// pkgTagSection::pkgTagSection - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
+APT_IGNORE_DEPRECATED_PUSH
pkgTagSection::pkgTagSection()
: Section(0), d(NULL), Stop(0)
{
- memset(&LookupTable, 0, sizeof(LookupTable));
+ d = new pkgTagSectionPrivate();
+#if APT_PKG_ABI < 413
+ TagCount = 0;
+ memset(&Indexes, 0, sizeof(Indexes));
+#endif
+ memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
}
+APT_IGNORE_DEPRECATED_POP
/*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
+#if APT_PKG_ABI < 413
+bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
+{
+ return Scan(Start, MaxLength, true);
+}
+#endif
bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const Restart)
{
Section = Start;
const char *End = Start + MaxLength;
- if (Restart == false && Tags.empty() == false)
+ if (Restart == false && d->Tags.empty() == false)
{
- Stop = Section + Tags.back().StartTag;
+ Stop = Section + d->Tags.back().StartTag;
if (End <= Stop)
return false;
Stop = (const char *)memchr(Stop,'\n',End - Stop);
else
{
Stop = Section;
- if (Tags.empty() == false)
+ if (d->Tags.empty() == false)
{
- memset(&LookupTable, 0, sizeof(LookupTable));
- Tags.clear();
+ memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+ d->Tags.clear();
}
- Tags.reserve(0x100);
+ d->Tags.reserve(0x100);
}
- size_t TagCount = Tags.size();
+#if APT_PKG_ABI >= 413
+ unsigned int TagCount = d->Tags.size();
+#else
+ APT_IGNORE_DEPRECATED(TagCount = d->Tags.size();)
+#endif
if (Stop == 0)
return false;
- TagData lastTagData(0);
+ pkgTagSectionPrivate::TagData lastTagData(0);
lastTagData.EndTag = 0;
unsigned long lastTagHash = 0;
while (Stop < End)
// store the last found tag
if (lastTagData.EndTag != 0)
{
- if (LookupTable[lastTagHash] != 0)
- lastTagData.NextInBucket = LookupTable[lastTagHash];
- LookupTable[lastTagHash] = TagCount;
- Tags.push_back(lastTagData);
+ if (AlphaIndexes[lastTagHash] != 0)
+ lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+ APT_IGNORE_DEPRECATED_PUSH
+ AlphaIndexes[lastTagHash] = TagCount;
+#if APT_PKG_ABI < 413
+ if (d->Tags.size() < sizeof(Indexes)/sizeof(Indexes[0]))
+ Indexes[d->Tags.size()] = lastTagData.StartTag;
+#endif
+ APT_IGNORE_DEPRECATED_POP
+ d->Tags.push_back(lastTagData);
}
- ++TagCount;
- lastTagData = TagData(Stop - Section);
+ APT_IGNORE_DEPRECATED(++TagCount;)
+ lastTagData = pkgTagSectionPrivate::TagData(Stop - Section);
// find the colon separating tag and value
char const * Colon = (char const *) memchr(Stop, ':', End - Stop);
if (Colon == NULL)
{
if (lastTagData.EndTag != 0)
{
- if (LookupTable[lastTagHash] != 0)
- lastTagData.NextInBucket = LookupTable[lastTagHash];
- LookupTable[lastTagHash] = TagCount;
- Tags.push_back(lastTagData);
+ if (AlphaIndexes[lastTagHash] != 0)
+ lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+ APT_IGNORE_DEPRECATED(AlphaIndexes[lastTagHash] = TagCount;)
+#if APT_PKG_ABI < 413
+ APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = lastTagData.StartTag;)
+#endif
+ d->Tags.push_back(lastTagData);
}
- TagData const td(Stop - Section);
- Tags.push_back(td);
+ pkgTagSectionPrivate::TagData const td(Stop - Section);
+#if APT_PKG_ABI < 413
+ APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = td.StartTag;)
+#endif
+ d->Tags.push_back(td);
TrimRecord(false,End);
return true;
}
}
/*}}}*/
// TagSection::Exists - return True if a tag exists /*{{{*/
+#if APT_PKG_ABI >= 413
bool pkgTagSection::Exists(const char* const Tag) const
+#else
+bool pkgTagSection::Exists(const char* const Tag)
+#endif
{
unsigned int tmp;
return Find(Tag, tmp);
bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const
{
size_t const Length = strlen(Tag);
- unsigned int Bucket = LookupTable[AlphaHash(Tag, Length)];
+ unsigned int Bucket = AlphaIndexes[AlphaHash(Tag, Length)];
if (Bucket == 0)
return false;
- for (; Bucket != 0; Bucket = Tags[Bucket - 1].NextInBucket)
+ for (; Bucket != 0; Bucket = d->Tags[Bucket - 1].NextInBucket)
{
- if ((Tags[Bucket - 1].EndTag - Tags[Bucket - 1].StartTag) != Length)
+ if ((d->Tags[Bucket - 1].EndTag - d->Tags[Bucket - 1].StartTag) != Length)
continue;
- char const * const St = Section + Tags[Bucket - 1].StartTag;
+ char const * const St = Section + d->Tags[Bucket - 1].StartTag;
if (strncasecmp(Tag,St,Length) != 0)
continue;
if (Find(Tag, Pos) == false)
return false;
- Start = Section + Tags[Pos].StartValue;
+ Start = Section + d->Tags[Pos].StartValue;
// Strip off the gunk from the end
- End = Section + Tags[Pos + 1].StartTag;
+ End = Section + d->Tags[Pos + 1].StartTag;
if (unlikely(Start > End))
return _error->Error("Internal parsing error");
return true;
}
/*}}}*/
+void pkgTagSection::Get(const char *&Start,const char *&Stop,unsigned int I) const
+{
+ Start = Section + d->Tags[I].StartTag;
+ Stop = Section + d->Tags[I+1].StartTag;
+}
APT_PURE unsigned int pkgTagSection::Count() const { /*{{{*/
- if (Tags.empty() == true)
+ if (d->Tags.empty() == true)
return 0;
// the last element is just marking the end and isn't a real one
- return Tags.size() - 1;
+ return d->Tags.size() - 1;
}
/*}}}*/
+
+#include "tagfile-order.c"
+
// TFRewrite - Rewrite a control record /*{{{*/
// ---------------------------------------------------------------------
/* This writes the control record to stdout rewriting it as necessary. The
override map item specificies the rewriting rules to follow. This also
takes the time to sort the feild list. */
-
-/* The order of this list is taken from dpkg source lib/parse.c the fieldinfos
- array. */
-static const char *iTFRewritePackageOrder[] = {
- "Package",
- "Essential",
- "Status",
- "Priority",
- "Section",
- "Installed-Size",
- "Maintainer",
- "Original-Maintainer",
- "Architecture",
- "Source",
- "Version",
- "Revision", // Obsolete
- "Config-Version", // Obsolete
- "Replaces",
- "Provides",
- "Depends",
- "Pre-Depends",
- "Recommends",
- "Suggests",
- "Conflicts",
- "Breaks",
- "Conffiles",
- "Filename",
- "Size",
- "MD5Sum",
- "SHA1",
- "SHA256",
- "SHA512",
- "MSDOS-Filename", // Obsolete
- "Description",
- 0};
-static const char *iTFRewriteSourceOrder[] = {"Package",
- "Source",
- "Binary",
- "Version",
- "Priority",
- "Section",
- "Maintainer",
- "Original-Maintainer",
- "Build-Depends",
- "Build-Depends-Indep",
- "Build-Conflicts",
- "Build-Conflicts-Indep",
- "Architecture",
- "Standards-Version",
- "Format",
- "Directory",
- "Files",
- 0};
-
-/* Two levels of initialization are used because gcc will set the symbol
- size of an array to the length of the array, causing dynamic relinking
- errors. Doing this makes the symbol size constant */
-const char **TFRewritePackageOrder = iTFRewritePackageOrder;
-const char **TFRewriteSourceOrder = iTFRewriteSourceOrder;
-
bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
TFRewriteData *Rewrite)
{
return true;
}
/*}}}*/
+
+pkgTagSection::~pkgTagSection() { delete d; }