00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // SPKFileRep.H -- classes for reading/writing PKFile header records 00020 00021 #ifndef _SPK_FILE_REP_H 00022 #define _SPK_FILE_REP_H 00023 00024 #include <Basics.H> 00025 #include <FS.H> 00026 #include <FP.H> 00027 #include <fstream> 00028 00029 class SPKFileRep { 00030 public: 00031 // Current version number of disk data. This is the version number for 00032 // MultiPKFiles and for the PKFiles within them. All positive versions 00033 // less than the current one are also supported. 00034 // 00035 // Version history: 00036 // 1 -- original version 00037 // 2 -- added magic number to SMultiPKFileRep::Header; no change to 00038 // SMultiPKFile header entry format or PKFile format on disk 00039 // 3 -- added sourceFunc field to PKFiles 00040 enum { 00041 OriginalVersion = 1, 00042 MPKMagicNumVersion = 2, 00043 SourceFuncVersion = 3 00044 }; 00045 enum { 00046 FirstVersion = OriginalVersion, 00047 LastVersion = SourceFuncVersion 00048 }; 00049 00050 // type for ints of various sizes 00051 typedef unsigned short UShort; 00052 typedef unsigned int UInt; 00053 00054 // <CFPHeaderEntry> ------------------------------------------------------- 00055 00056 class HeaderEntry { 00057 public: 00058 // constructors 00059 HeaderEntry() { /*SKIP*/ } 00060 HeaderEntry(std::ifstream &ifs, std::streampos origin) 00061 throw (FS::EndOfFile, FS::Failure) 00062 { Read(ifs, origin); } 00063 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeaderEntry>'' */ 00064 00065 // reading/writing 00066 void Read(std::ifstream &ifs, std::streampos origin) 00067 throw (FS::EndOfFile, FS::Failure); 00068 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeaderEntry>'' */ 00069 00070 void Write(std::ostream &ofs, std::streampos origin) throw (FS::Failure); 00071 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeaderEntry>'' */ 00072 00073 void Debug(std::ostream &os, bool verbose = false) const throw (); 00074 /* Write an ASCII representation of this "HeaderEntry" to "os". By 00075 default, a one-line elided representation is written. If "verbose" 00076 is true, a complete multi-line representation is written. */ 00077 00078 // size 00079 static int Size() throw() { return sizeof(FP::Tag) + sizeof(UInt); } 00080 00081 // disk data 00082 FP::Tag cfp; // common fingerprint 00083 UInt offset; // start of corresponding <PKEntries> (*) 00084 00085 // auxiliary data -- not written to disk 00086 UInt offsetLoc; // location of "offset" on disk (*) 00087 00088 // (*) These offsets are interpreted relative to the start of 00089 // the corresponding <PKFile>. 00090 }; // <CFPHeaderEntry> 00091 00092 // <CFPHeader> ------------------------------------------------------------ 00093 00094 // "Header.type" values 00095 enum HeaderType { HT_List, HT_SortedList, HT_HashTable, 00096 HT_PerfectHashTable, HT_Last }; 00097 00098 class Header { 00099 public: 00100 // constructors 00101 Header() : num(0), type(HT_Last), entry(NULL) { /*SKIP*/ } 00102 Header(std::ifstream &ifs, std::streampos origin, int version, 00103 bool readEntries = true) throw (FS::EndOfFile, FS::Failure) 00104 : entry(NULL) { Read(ifs, origin, version, readEntries); } 00105 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeader>'' */ 00106 00107 // skip 00108 static void Skip(std::ifstream &ifs, std::streampos origin, int version) 00109 throw (FS::EndOfFile, FS::Failure); 00110 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeader>'' */ 00111 /* Move the current position of "ifs" to the end of the <CFPHeader>. */ 00112 00113 // reading/writing 00114 void Read(std::ifstream &ifs, std::streampos origin, int version, 00115 bool readEntries = true) throw (FS::EndOfFile, FS::Failure); 00116 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeader>'' */ 00117 /* Initializes the "Header" from the stream "ifs", computing internal 00118 offsets relative to "origin". "version" is the version number found 00119 in the MultiPKFile <Header>. If "readEntries" is true, this also 00120 allocates the "entry" array and reads the <CFPHeaderEntry> records 00121 into it. Otherwise, it leaves "ifs" positioned at the start of the 00122 <CFPTypedHeader>. */ 00123 00124 void Write(std::ostream &ofs, std::streampos origin) throw (FS::Failure); 00125 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeader>'' */ 00126 /* Write the complete "Header" to "ofs" using "origin" as the origin 00127 position against which offsets in the <CFPHeader> are computed. 00128 This includes writing the <CFPHeaderEntry> records represented 00129 by the "entry" array. This method may have the side-effect of 00130 permuting the "HeaderEntry"'s in the "entry" array. */ 00131 00132 void BackPatch(std::ostream &ofs, std::streampos origin) const 00133 throw (FS::Failure); 00134 /* Back-patch the "offset"s in this PKFile's <HeaderEntry> records 00135 by seeking to their locations relative to "origin" and writing 00136 their values to "ofs". */ 00137 00138 void Debug(std::ostream &os, bool verbose = false) const throw (); 00139 /* Write an ASCII represenation of this "Header" to "os". By default, 00140 a one-line elided representation is written. If "verbose" is true, 00141 a multi-line complete represenation is written. In any event, this 00142 does not write the information in the "entry" array; use the 00143 "HeaderEntry::Debug" method for that. */ 00144 00145 // disk data 00146 UShort num; // number of <CFPHeaderEntry>'s 00147 UShort type; // format in which HeaderEntry's are stored 00148 00149 // auxiliary data 00150 HeaderEntry *entry; // array of corresponding <CFPHeaderEntry>'s 00151 00152 /* The "entry" field is a dynamically allocated list of this 00153 PKFile's <CFPHeaderEntry> records, in order; it has length 00154 "num". */ 00155 00156 private: 00157 static void SkipListV1(std::ifstream &ifs, int num) 00158 throw (FS::EndOfFile, FS::Failure); 00159 /* REQUIRES FS::Posn(ifs) == ``start of <CFPSeqHeader>'' */ 00160 00161 void ReadListV1(std::ifstream &ifs, std::streampos origin) 00162 throw (FS::EndOfFile, FS::Failure); 00163 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeader>'' */ 00164 00165 void WriteList(std::ostream &ofs, std::streampos origin) 00166 throw (FS::Failure); 00167 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeader>'' */ 00168 00169 void WriteSortedList(std::ostream &ofs, std::streampos origin) 00170 throw (FS::Failure); 00171 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeader>'' */ 00172 }; // <CFPHeader> 00173 }; 00174 00175 #endif // _SPK_FILE_REP_H