Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

SPKFileRep.C

Go to the documentation of this file.
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 #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 // <CFPHeaderEntry> routines --------------------------------------------------
00031 
00032 void SPKFileRep::HeaderEntry::Read(ifstream &ifs, streampos origin)
00033   throw (FS::EndOfFile, FS::Failure)
00034 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeaderEntry>'' */
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 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeaderEntry>'' */
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 // <CFPHeader> routines -------------------------------------------------------
00064 
00065 void SPKFileRep::Header::Skip(ifstream &ifs, streampos origin, int version)
00066   throw (FS::EndOfFile, FS::Failure)
00067 /* REQUIRES FS::Posn(ifs) == ``start of <PKFile>'' */
00068 {
00069     SPKFileRep::Header hdr(ifs, origin, version, /*readEntries=*/ 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             // unsupported version
00077             assert(false);
00078         }
00079         break;
00080       case HT_HashTable:
00081       case HT_PerfectHashTable:
00082         /*** NYI ***/
00083         assert(false);
00084       default:
00085         // unrecognized type
00086         assert(false);
00087     }
00088 }
00089 
00090 void SPKFileRep::Header::SkipListV1(ifstream &ifs, int num)
00091   throw (FS::EndOfFile, FS::Failure)
00092 /* REQUIRES FS::Posn(ifs) == ``start of <CFPSeqHeader>'' */
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 /* REQUIRES FS::Posn(ifs) == ``start of <CFPHeader>'' */
00100 {
00101     // read immediate disk data
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       // fill in "entry" based on "type"
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           // unsupported version
00115           assert(false);
00116         }
00117         break;
00118       case HT_HashTable:
00119       case HT_PerfectHashTable:
00120         /*** NYI ***/
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 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeader>'' */
00131 {
00132     // determine format type
00133     if (this->num < 8) {
00134         this->type = HT_List;
00135     } else {
00136         this->type = HT_SortedList;
00137     }
00138 
00139     // write immediate disk data
00140     FS::Write(ofs, (char *)(&(this->num)), sizeof(this->num));
00141     FS::Write(ofs, (char *)(&(this->type)), sizeof(this->type));
00142 
00143     // write "entry" data
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         /*** NYI ***/
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     // read <CFPHeaderEntry> records
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 /* REQUIRES FS::Posn(ofs) == ``start of <CFPHeader>'' */
00172 {
00173     // write <CFPHeaderEntry> records
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     // sort the entries using qsort(3)
00193     qsort((void *)(this->entry), (size_t)(this->num),
00194       (size_t)sizeof(*(this->entry)), SPKFileRep_HECompare);
00195 
00196     // write them as a simple list
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(/*HT_List <= this->type &&*/ this->type < HT_Last);
00219         os << "type      = " << HeaderTypeName[this->type] << endl;
00220     } else {
00221         os << "num = " << this->num << endl;
00222     }
00223 }

Generated on Mon May 8 00:48:36 2006 for Vesta by  doxygen 1.4.2