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
// 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;
}
/*}}}*/
// TFRewrite - Rewrite a control record /*{{{*/
"Conffiles",
"Filename",
"Size",
- "MD5Sum",
+ "MD5sum",
"SHA1",
"SHA256",
"SHA512",
return true;
}
/*}}}*/
+
+pkgTagSection::~pkgTagSection() { delete d; }