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

IntVecFile.cc

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal 00006 // 00007 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 00038 00039 /* ******************************************************* 00040 * $Id: IntVecFile.cc,v 1.6 2004/07/21 16:30:51 chrish42 Exp $ 00041 * AUTHORS: Pascal Vincent 00042 * This file is part of the PLearn library. 00043 ******************************************************* */ 00044 00045 #include "IntVecFile.h" 00046 //#include "fileutils.h" 00047 #include <plearn/base/byte_order.h> 00048 00049 namespace PLearn { 00050 using namespace std; 00051 00052 const char IntVecFile::signature[] = { 00053 0xDE, 0xAD, 0xBE, 0xEF, 0x00 00054 }; 00055 00056 const int IntVecFile::header_size[] = { 00057 0, 00058 2 00059 }; 00060 00061 00062 IntVecFile::IntVecFile(const IntVecFile& other) 00063 : filename(other.filename), f(0), length_(other.length_), 00064 version_number_(other.version_number_), endianness_(other.endianness_) 00065 { 00066 open(filename, false /* readonly */); 00067 } 00068 00069 void IntVecFile::open(const string& the_filename, bool readwrite) 00070 { 00071 if(f) 00072 close(); 00073 00074 filename = the_filename; 00075 bool file_exists = isfile(filename); 00076 if(readwrite) 00077 { 00078 f = fopen(filename.c_str(),"a+"); 00079 if(!f) 00080 PLERROR("Couldn't open file %s for read/write",filename.c_str()); 00081 } 00082 else 00083 { 00084 f = fopen(filename.c_str(),"r"); 00085 if(!f) 00086 PLERROR("Couldn't open file %s for reading",filename.c_str()); 00087 } 00088 if (file_exists) 00089 getVersionAndSize(); 00090 else 00091 writeFileSignature(); 00092 } 00093 00094 int IntVecFile::get(int i) const 00095 { 00096 #ifdef BOUNDCHECK 00097 if(i<0 || i>=length()) 00098 PLERROR("Out Of Bounds in IntVecFile::get"); 00099 #endif 00100 seek_to_index(i); 00101 return fread_int(f, endianness_ == BIG_ENDIAN_ORDER); 00102 } 00103 00104 void IntVecFile::put(int i, int value) 00105 { 00106 seek_to_index(i); 00107 fwrite_int(f, value, endianness_ == BIG_ENDIAN_ORDER); 00108 if(i>=length_) 00109 length_ = i+1; 00110 } 00111 00112 void IntVecFile::close() 00113 { 00114 if(f) 00115 fclose(f); 00116 f=0; 00117 } 00118 00119 IntVecFile::~IntVecFile() 00120 { 00121 close(); 00122 } 00123 00124 TVec<int> IntVecFile::getVec() const 00125 { 00126 int tt; 00127 TVec<int> res(length()); 00128 seek_to_index(0); 00129 if((tt=fread(res.data(), sizeof(int), length(), f)) != length()) 00130 PLERROR("fread error in IntVecFile::getVec()"); 00131 00132 // Switch byte order if necessary 00133 if (byte_order() != endianness_) 00134 endianswap(res.data(), length()); 00135 00136 return res; 00137 } 00138 void IntVecFile::append(const TVec<int>& vec) 00139 { 00140 seek_to_index(length()); 00141 00142 if (byte_order() != endianness_) { 00143 TVec<int> new_vec(vec.length()); 00144 new_vec << vec; 00145 endianswap(new_vec.data(), new_vec.length()); 00146 fwrite(new_vec.data(), sizeof(int), new_vec.length(), f); 00147 } 00148 else { 00149 fwrite(vec.data(), sizeof(int), vec.length(), f); 00150 } 00151 00152 length_ += vec.length(); 00153 } 00154 00155 void IntVecFile::writeFileSignature() 00156 { 00157 // This is for a new file. Assume length 0, version number 1, 00158 // file endianness is current-platform endianness 00159 length_ = 0; 00160 version_number_ = 1; 00161 endianness_ = byte_order(); 00162 00163 fseek(f, 0, SEEK_SET); 00164 fputs(signature, f); 00165 fputc(endianness_, f); 00166 fputc(0x00, f); 00167 fputc(0x00, f); 00168 fputc(char(version_number_), f); 00169 } 00170 00171 void IntVecFile::getVersionAndSize() 00172 { 00173 if (sizeof(int) != 4) 00174 PLERROR("IntVecFile::getVersionAndSize: " 00175 "IntVecFile not yet designed to handle sizeof(int) != 4"); 00176 00177 long the_filesize = filesize(filename); 00178 if (the_filesize < long(2*sizeof(int)) /* assume 4 */) 00179 goto version0; // unbelievable but true! 00180 00181 fseek(f, 0, SEEK_SET); 00182 for (int i=0; i<4; ++i) 00183 if (char(fgetc(f)) != signature[i]) 00184 goto version0; 00185 00186 // Assume new-world file format 00187 endianness_ = char(fgetc(f)); 00188 if (endianness_ != LITTLE_ENDIAN_ORDER && 00189 endianness_ != BIG_ENDIAN_ORDER) 00190 PLERROR("IntVecFile::getVersionAndSize: " 00191 "File format error in file %s Only supported endianness is 'L' or 'B'\n" 00192 "Read %c", filename.c_str(),endianness_); 00193 00194 if(fgetc(f) != 0x00 || fgetc(f) != 0x00) 00195 PLERROR("IntVecFile::getVersionAndSize: " 00196 "File format error in file %s", filename.c_str()); 00197 00198 version_number_ = (unsigned char)fgetc(f); 00199 00200 if (version_number_ > 1) 00201 PLERROR("IntVecFile::getVersionAndSize: " 00202 "File version (%d) is not supported", version_number_); 00203 00204 length_ = the_filesize / sizeof(int) - header_size[version_number_]; 00205 return; 00206 00207 version0: 00208 length_ = the_filesize / sizeof(int); 00209 version_number_ = 0; 00210 endianness_ = 'L'; 00211 } 00212 00213 void IntVecFile::seek_to_index(int i) const 00214 { 00215 fseek(f, (i+header_size[version_number_]) * sizeof(int), SEEK_SET); 00216 } 00217 00218 } // end of namespace PLearn

Generated on Tue Aug 17 15:55:40 2004 for PLearn by doxygen 1.3.7