]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/tagfile.cc
always run 'dpkg --configure -a' at the end of our dpkg callings
[apt.git] / apt-pkg / tagfile.cc
index e667c495fd0fc68caade79dbb5ac957790fab914..590206f1720b771e678c0b09f8923056a26dbe05 100644 (file)
@@ -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,21 +291,34 @@ 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
+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);
@@ -299,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)
@@ -329,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)
@@ -371,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;
       }
@@ -424,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;
 
@@ -451,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");
 
@@ -565,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                                        /*{{{*/
@@ -762,4 +813,4 @@ bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
 }
                                                                        /*}}}*/
 
-pkgTagSection::~pkgTagSection() {}
+pkgTagSection::~pkgTagSection() { delete d; }