summaryrefslogtreecommitdiff
path: root/apt-pkg/tagfile.h
blob: d1a24ba45132580d0d3848afe98323e5fa8512d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// -*- mode: cpp; mode: fold -*-
// Description								/*{{{*/
// $Id: tagfile.h,v 1.20 2003/05/19 17:13:57 doogie Exp $
/* ######################################################################

   Fast scanner for RFC-822 type header information
   
   This parser handles Debian package files (and others). Their form is
   RFC-822 type header fields in groups separated by a blank line.
   
   The parser reads the file and provides methods to step linearly
   over it or to jump to a pre-recorded start point and read that record.
   
   A second class is used to perform pre-parsing of the record. It works
   by indexing the start of each header field and providing lookup 
   functions for header fields.
   
   ##################################################################### */
									/*}}}*/
#ifndef PKGLIB_TAGFILE_H
#define PKGLIB_TAGFILE_H

#include <apt-pkg/macros.h>

#include <stdio.h>

#include <string>

#ifndef APT_8_CLEANER_HEADERS
#include <apt-pkg/fileutl.h>
#endif

class FileFd;

class pkgTagSection
{
   const char *Section;
   // We have a limit of 256 tags per section.
   unsigned int Indexes[256];
   unsigned int AlphaIndexes[0x100];
   unsigned int TagCount;
   // dpointer placeholder (for later in case we need it)
   void *d;

   /* This very simple hash function for the last 8 letters gives
      very good performance on the debian package files */
   inline static unsigned long AlphaHash(const char *Text, const char *End = 0)
   {
      unsigned long Res = 0;
      for (; Text != End && *Text != ':' && *Text != 0; Text++)
	 Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1);
      return Res & 0xFF;
   }

   protected:
   const char *Stop;

   public:
   
   inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
   inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;};
   
   bool Find(const char *Tag,const char *&Start, const char *&End) const;
   bool Find(const char *Tag,unsigned int &Pos) const;
   std::string FindS(const char *Tag) const;
   signed int FindI(const char *Tag,signed long Default = 0) const ;
   unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
   bool FindFlag(const char *Tag,unsigned long &Flags,
		 unsigned long Flag) const;
   bool static FindFlag(unsigned long &Flags, unsigned long Flag,
				const char* Start, const char* Stop);
   bool Scan(const char *Start,unsigned long MaxLength);
   inline unsigned long size() const {return Stop - Section;};
   void Trim();
   virtual void TrimRecord(bool BeforeRecord, const char* &End);
   
   inline unsigned int Count() const {return TagCount;};
   bool Exists(const char* const Tag);
 
   inline void Get(const char *&Start,const char *&Stop,unsigned int I) const
                   {Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];}
	    
   inline void GetSection(const char *&Start,const char *&Stop) const
   {
      Start = Section;
      Stop = this->Stop;
   };
   
   pkgTagSection();
   virtual ~pkgTagSection() {};
};

class pkgTagFilePrivate;
class pkgTagFile
{
   pkgTagFilePrivate *d;

   APT_HIDDEN bool Fill();
   APT_HIDDEN bool Resize();
   APT_HIDDEN bool Resize(unsigned long long const newSize);

   public:

   bool Step(pkgTagSection &Section);
   unsigned long Offset();
   bool Jump(pkgTagSection &Tag,unsigned long long Offset);

   void Init(FileFd *F,unsigned long long Size = 32*1024);

   pkgTagFile(FileFd *F,unsigned long long Size = 32*1024);
   virtual ~pkgTagFile();
};

/* This is the list of things to rewrite. The rewriter
   goes through and changes or adds each of these headers
   to suit. A zero forces the header to be erased, an empty string
   causes the old value to be used. (rewrite rule ignored) */
struct TFRewriteData
{
   const char *Tag;
   const char *Rewrite;
   const char *NewTag;
};
extern const char **TFRewritePackageOrder;
extern const char **TFRewriteSourceOrder;

bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
	       TFRewriteData *Rewrite);

#endif