| 1 | // -*- mode: cpp; mode: fold -*- |
| 2 | // Description /*{{{*/ |
| 3 | // $Id: tagfile.h,v 1.20 2003/05/19 17:13:57 doogie Exp $ |
| 4 | /* ###################################################################### |
| 5 | |
| 6 | Fast scanner for RFC-822 type header information |
| 7 | |
| 8 | This parser handles Debian package files (and others). Their form is |
| 9 | RFC-822 type header fields in groups separated by a blank line. |
| 10 | |
| 11 | The parser reads the file and provides methods to step linearly |
| 12 | over it or to jump to a pre-recorded start point and read that record. |
| 13 | |
| 14 | A second class is used to perform pre-parsing of the record. It works |
| 15 | by indexing the start of each header field and providing lookup |
| 16 | functions for header fields. |
| 17 | |
| 18 | ##################################################################### */ |
| 19 | /*}}}*/ |
| 20 | #ifndef PKGLIB_TAGFILE_H |
| 21 | #define PKGLIB_TAGFILE_H |
| 22 | |
| 23 | #include <apt-pkg/macros.h> |
| 24 | |
| 25 | #include <stdio.h> |
| 26 | |
| 27 | #include <string> |
| 28 | |
| 29 | #ifndef APT_8_CLEANER_HEADERS |
| 30 | #include <apt-pkg/fileutl.h> |
| 31 | #endif |
| 32 | |
| 33 | class FileFd; |
| 34 | |
| 35 | class pkgTagSection |
| 36 | { |
| 37 | const char *Section; |
| 38 | // We have a limit of 256 tags per section. |
| 39 | unsigned int Indexes[256]; |
| 40 | unsigned int AlphaIndexes[0x100]; |
| 41 | unsigned int TagCount; |
| 42 | // dpointer placeholder (for later in case we need it) |
| 43 | void *d; |
| 44 | |
| 45 | /* This very simple hash function for the last 8 letters gives |
| 46 | very good performance on the debian package files */ |
| 47 | inline static unsigned long AlphaHash(const char *Text, const char *End = 0) |
| 48 | { |
| 49 | unsigned long Res = 0; |
| 50 | for (; Text != End && *Text != ':' && *Text != 0; Text++) |
| 51 | Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1); |
| 52 | return Res & 0xFF; |
| 53 | } |
| 54 | |
| 55 | protected: |
| 56 | const char *Stop; |
| 57 | |
| 58 | public: |
| 59 | |
| 60 | inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;}; |
| 61 | inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;}; |
| 62 | |
| 63 | bool Find(const char *Tag,const char *&Start, const char *&End) const; |
| 64 | bool Find(const char *Tag,unsigned int &Pos) const; |
| 65 | std::string FindS(const char *Tag) const; |
| 66 | signed int FindI(const char *Tag,signed long Default = 0) const ; |
| 67 | unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const; |
| 68 | bool FindFlag(const char *Tag,unsigned long &Flags, |
| 69 | unsigned long Flag) const; |
| 70 | bool static FindFlag(unsigned long &Flags, unsigned long Flag, |
| 71 | const char* Start, const char* Stop); |
| 72 | bool Scan(const char *Start,unsigned long MaxLength); |
| 73 | inline unsigned long size() const {return Stop - Section;}; |
| 74 | void Trim(); |
| 75 | virtual void TrimRecord(bool BeforeRecord, const char* &End); |
| 76 | |
| 77 | inline unsigned int Count() const {return TagCount;}; |
| 78 | bool Exists(const char* const Tag); |
| 79 | |
| 80 | inline void Get(const char *&Start,const char *&Stop,unsigned int I) const |
| 81 | {Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];} |
| 82 | |
| 83 | inline void GetSection(const char *&Start,const char *&Stop) const |
| 84 | { |
| 85 | Start = Section; |
| 86 | Stop = this->Stop; |
| 87 | }; |
| 88 | |
| 89 | pkgTagSection(); |
| 90 | virtual ~pkgTagSection() {}; |
| 91 | }; |
| 92 | |
| 93 | class pkgTagFilePrivate; |
| 94 | class pkgTagFile |
| 95 | { |
| 96 | pkgTagFilePrivate *d; |
| 97 | |
| 98 | APT_HIDDEN bool Fill(); |
| 99 | APT_HIDDEN bool Resize(); |
| 100 | APT_HIDDEN bool Resize(unsigned long long const newSize); |
| 101 | |
| 102 | public: |
| 103 | |
| 104 | bool Step(pkgTagSection &Section); |
| 105 | unsigned long Offset(); |
| 106 | bool Jump(pkgTagSection &Tag,unsigned long long Offset); |
| 107 | |
| 108 | pkgTagFile(FileFd *F,unsigned long long Size = 32*1024); |
| 109 | virtual ~pkgTagFile(); |
| 110 | }; |
| 111 | |
| 112 | /* This is the list of things to rewrite. The rewriter |
| 113 | goes through and changes or adds each of these headers |
| 114 | to suit. A zero forces the header to be erased, an empty string |
| 115 | causes the old value to be used. (rewrite rule ignored) */ |
| 116 | struct TFRewriteData |
| 117 | { |
| 118 | const char *Tag; |
| 119 | const char *Rewrite; |
| 120 | const char *NewTag; |
| 121 | }; |
| 122 | extern const char **TFRewritePackageOrder; |
| 123 | extern const char **TFRewriteSourceOrder; |
| 124 | |
| 125 | bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[], |
| 126 | TFRewriteData *Rewrite); |
| 127 | |
| 128 | #endif |