summaryrefslogtreecommitdiff
path: root/apt-pkg/tagfile.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2014-11-07 21:52:31 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2014-11-08 14:33:25 +0100
commitbc4ccfeb6096fc6f9a74e2abff3abe31261b5df2 (patch)
tree3ac5a8dc90cdbd8dc284c995a071afd492de4deb /apt-pkg/tagfile.cc
parent0dc0b42d73ffd08bbdbe08b0678fbaae02364622 (diff)
restore ABI of pkgTagSection
We have a d-pointer available here, so go ahead and use it which also helps in hidding some dirty details here. The "hard" part is keeping the abi for the inlined methods so that they don't break – at least not more than before as much of the point beside a speedup is support for more than 256 fields in a single section.
Diffstat (limited to 'apt-pkg/tagfile.cc')
-rw-r--r--apt-pkg/tagfile.cc105
1 files changed, 75 insertions, 30 deletions
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 3ee5c7076..590206f17 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -47,6 +47,23 @@ public:
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
@@ -274,11 +291,18 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
// 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
@@ -292,9 +316,9 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
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);
@@ -305,19 +329,23 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
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)
@@ -335,14 +363,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
// 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)
@@ -377,14 +411,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
{
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;
}
@@ -430,16 +470,16 @@ bool pkgTagSection::Exists(const char* const Tag)
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;
@@ -457,9 +497,9 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
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");
@@ -571,11 +611,16 @@ bool pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag,
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 /*{{{*/
@@ -768,4 +813,4 @@ bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
}
/*}}}*/
-pkgTagSection::~pkgTagSection() {}
+pkgTagSection::~pkgTagSection() { delete d; }