00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <Basics.H>
00020 #include <FS.H>
00021
00022 #include "SPKFileRep.H"
00023
00024 using std::ios;
00025 using std::ostream;
00026 using std::streampos;
00027 using std::ifstream;
00028 using std::endl;
00029
00030
00031
00032 void SPKFileRep::HeaderEntry::Read(ifstream &ifs, streampos origin)
00033 throw (FS::EndOfFile, FS::Failure)
00034
00035 {
00036 FS::Read(ifs, (char *)(&(this->cfp)), sizeof(this->cfp));
00037 this->offsetLoc = FS::Posn(ifs) - origin;
00038 FS::Read(ifs, (char *)(&(this->offset)), sizeof(this->offset));
00039 }
00040
00041 void SPKFileRep::HeaderEntry::Write(ostream &ofs, streampos origin)
00042 throw (FS::Failure)
00043
00044 {
00045 FS::Write(ofs, (char *)(&(this->cfp)), sizeof(this->cfp));
00046 this->offsetLoc = FS::Posn(ofs) - origin;
00047 FS::Write(ofs, (char *)(&(this->offset)), sizeof(this->offset));
00048 }
00049
00050 void SPKFileRep::HeaderEntry::Debug(ostream &os, bool verbose) const throw ()
00051 {
00052 if (verbose) {
00053 os << endl << "// <CFPHeaderEntry>" << endl;
00054 os << "cfp = " << this->cfp << endl;
00055 os << "offset = " << this->offset << endl;
00056 os << "offsetLoc = " << this->offsetLoc << endl;
00057 } else {
00058 os << "cfp = " << this->cfp
00059 << ", offset = " << this->offset << endl;
00060 }
00061 }
00062
00063
00064
00065 void SPKFileRep::Header::Skip(ifstream &ifs, streampos origin, int version)
00066 throw (FS::EndOfFile, FS::Failure)
00067
00068 {
00069 SPKFileRep::Header hdr(ifs, origin, version, false);
00070 switch (hdr.type) {
00071 case HT_List:
00072 case HT_SortedList:
00073 if (version <= SPKFileRep::SourceFuncVersion) {
00074 SkipListV1(ifs, hdr.num);
00075 } else {
00076
00077 assert(false);
00078 }
00079 break;
00080 case HT_HashTable:
00081 case HT_PerfectHashTable:
00082
00083 assert(false);
00084 default:
00085
00086 assert(false);
00087 }
00088 }
00089
00090 void SPKFileRep::Header::SkipListV1(ifstream &ifs, int num)
00091 throw (FS::EndOfFile, FS::Failure)
00092
00093 {
00094 FS::Seek(ifs, num * HeaderEntry::Size(), ios::cur);
00095 }
00096
00097 void SPKFileRep::Header::Read(ifstream &ifs, streampos origin, int version,
00098 bool readEntries) throw (FS::EndOfFile, FS::Failure)
00099
00100 {
00101
00102 FS::Read(ifs, (char *)(&(this->num)), sizeof(this->num));
00103 FS::Read(ifs, (char *)(&(this->type)), sizeof(this->type));
00104
00105 if (readEntries) {
00106
00107 this->entry = NEW_ARRAY(HeaderEntry, this->num);
00108 switch (this->type) {
00109 case HT_List:
00110 case HT_SortedList:
00111 if (version <= SPKFileRep::SourceFuncVersion) {
00112 ReadListV1(ifs, origin);
00113 } else {
00114
00115 assert(false);
00116 }
00117 break;
00118 case HT_HashTable:
00119 case HT_PerfectHashTable:
00120
00121 assert(false);
00122 default:
00123 assert(false);
00124 }
00125 }
00126 }
00127
00128 void SPKFileRep::Header::Write(ostream &ofs, streampos origin)
00129 throw (FS::Failure)
00130
00131 {
00132
00133 if (this->num < 8) {
00134 this->type = HT_List;
00135 } else {
00136 this->type = HT_SortedList;
00137 }
00138
00139
00140 FS::Write(ofs, (char *)(&(this->num)), sizeof(this->num));
00141 FS::Write(ofs, (char *)(&(this->type)), sizeof(this->type));
00142
00143
00144 switch (this->type) {
00145 case HT_List:
00146 WriteList(ofs, origin);
00147 break;
00148 case HT_SortedList:
00149 WriteSortedList(ofs, origin);
00150 break;
00151 case HT_HashTable:
00152 case HT_PerfectHashTable:
00153
00154 assert(false);
00155 default:
00156 assert(false);
00157 }
00158 }
00159
00160 void SPKFileRep::Header::ReadListV1(ifstream &ifs, streampos origin)
00161 throw (FS::EndOfFile, FS::Failure)
00162 {
00163
00164 for (int i = 0; i < this->num; i++) {
00165 this->entry[i].Read(ifs, origin);
00166 }
00167 }
00168
00169 void SPKFileRep::Header::WriteList(ostream &ofs, streampos origin)
00170 throw (FS::Failure)
00171
00172 {
00173
00174 for (int i = 0; i < this->num; i++) {
00175 this->entry[i].Write(ofs, origin);
00176 }
00177 }
00178
00179 extern "C"
00180 {
00181 static int SPKFileRep_HECompare(const void *p1, const void *p2) throw ()
00182 {
00183 const SPKFileRep::HeaderEntry *he1 = (SPKFileRep::HeaderEntry *)p1;
00184 const SPKFileRep::HeaderEntry *he2 = (SPKFileRep::HeaderEntry *)p2;
00185 return Compare(he1->cfp, he2->cfp);
00186 }
00187 }
00188
00189 void SPKFileRep::Header::WriteSortedList(ostream &ofs, streampos origin)
00190 throw (FS::Failure)
00191 {
00192
00193 qsort((void *)(this->entry), (size_t)(this->num),
00194 (size_t)sizeof(*(this->entry)), SPKFileRep_HECompare);
00195
00196
00197 WriteList(ofs, origin);
00198 }
00199
00200 void SPKFileRep::Header::BackPatch(ostream &ofs, streampos origin) const
00201 throw (FS::Failure)
00202 {
00203 for (int i = 0; i < this->num; i++) {
00204 FS::Seek(ofs, origin + (streampos) this->entry[i].offsetLoc);
00205 FS::Write(ofs, (char *)(&(this->entry[i].offset)),
00206 sizeof(this->entry[i].offset));
00207 }
00208 }
00209
00210 const char *HeaderTypeName[] = {
00211 "List", "SortedList", "HashTable", "PerfectHashTable" };
00212
00213 void SPKFileRep::Header::Debug(ostream &os, bool verbose) const throw ()
00214 {
00215 if (verbose) {
00216 os << endl << "// <CFPHeader>" << endl;
00217 os << "num = " << this->num << endl;
00218 assert( this->type < HT_Last);
00219 os << "type = " << HeaderTypeName[this->type] << endl;
00220 } else {
00221 os << "num = " << this->num << endl;
00222 }
00223 }