apt
1.5
|
00001 // -*- mode: cpp; mode: fold -*- 00002 // Description /*{{{*/ 00003 // $Id: tagfile.h,v 1.20 2003/05/19 17:13:57 doogie Exp $ 00004 /* ###################################################################### 00005 00006 Fast scanner for RFC-822 type header information 00007 00008 This parser handles Debian package files (and others). Their form is 00009 RFC-822 type header fields in groups separated by a blank line. 00010 00011 The parser reads the file and provides methods to step linearly 00012 over it or to jump to a pre-recorded start point and read that record. 00013 00014 A second class is used to perform pre-parsing of the record. It works 00015 by indexing the start of each header field and providing lookup 00016 functions for header fields. 00017 00018 ##################################################################### */ 00019 /*}}}*/ 00020 #ifndef PKGLIB_TAGFILE_H 00021 #define PKGLIB_TAGFILE_H 00022 00023 #include <stdio.h> 00024 00025 #include <string> 00026 00027 #ifndef APT_8_CLEANER_HEADERS 00028 #include <apt-pkg/fileutl.h> 00029 #endif 00030 00031 class FileFd; 00032 00033 class pkgTagSection 00034 { 00035 const char *Section; 00036 // We have a limit of 256 tags per section. 00037 unsigned int Indexes[256]; 00038 unsigned int AlphaIndexes[0x100]; 00039 unsigned int TagCount; 00040 // dpointer placeholder (for later in case we need it) 00041 void *d; 00042 00043 /* This very simple hash function for the last 8 letters gives 00044 very good performance on the debian package files */ 00045 inline static unsigned long AlphaHash(const char *Text, const char *End = 0) 00046 { 00047 unsigned long Res = 0; 00048 for (; Text != End && *Text != ':' && *Text != 0; Text++) 00049 Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1); 00050 return Res & 0xFF; 00051 } 00052 00053 protected: 00054 const char *Stop; 00055 00056 public: 00057 00058 inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;}; 00059 inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;}; 00060 00061 bool Find(const char *Tag,const char *&Start, const char *&End) const; 00062 bool Find(const char *Tag,unsigned &Pos) const; 00063 std::string FindS(const char *Tag) const; 00064 signed int FindI(const char *Tag,signed long Default = 0) const ; 00065 unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const; 00066 bool FindFlag(const char *Tag,unsigned long &Flags, 00067 unsigned long Flag) const; 00068 bool static const FindFlag(unsigned long &Flags, unsigned long Flag, 00069 const char* Start, const char* Stop); 00070 bool Scan(const char *Start,unsigned long MaxLength); 00071 inline unsigned long size() const {return Stop - Section;}; 00072 void Trim(); 00073 virtual void TrimRecord(bool BeforeRecord, const char* &End); 00074 00075 inline unsigned int Count() const {return TagCount;}; 00076 inline bool Exists(const char* const Tag) {return AlphaIndexes[AlphaHash(Tag)] != 0;} 00077 00078 inline void Get(const char *&Start,const char *&Stop,unsigned int I) const 00079 {Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];} 00080 00081 inline void GetSection(const char *&Start,const char *&Stop) const 00082 { 00083 Start = Section; 00084 Stop = this->Stop; 00085 }; 00086 00087 pkgTagSection() : Section(0), TagCount(0), Stop(0) {}; 00088 virtual ~pkgTagSection() {}; 00089 }; 00090 00091 class pkgTagFilePrivate; 00092 class pkgTagFile 00093 { 00094 pkgTagFilePrivate *d; 00095 00096 bool Fill(); 00097 bool Resize(); 00098 00099 public: 00100 00101 bool Step(pkgTagSection &Section); 00102 unsigned long Offset(); 00103 bool Jump(pkgTagSection &Tag,unsigned long long Offset); 00104 00105 pkgTagFile(FileFd *F,unsigned long long Size = 32*1024); 00106 virtual ~pkgTagFile(); 00107 }; 00108 00109 /* This is the list of things to rewrite. The rewriter 00110 goes through and changes or adds each of these headers 00111 to suit. A zero forces the header to be erased, an empty string 00112 causes the old value to be used. (rewrite rule ignored) */ 00113 struct TFRewriteData 00114 { 00115 const char *Tag; 00116 const char *Rewrite; 00117 const char *NewTag; 00118 }; 00119 extern const char **TFRewritePackageOrder; 00120 extern const char **TFRewriteSourceOrder; 00121 00122 bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[], 00123 TFRewriteData *Rewrite); 00124 00125 #endif