Libbarrett
1.2.4
|
00001 00034 #include <stdexcept> 00035 #include <sstream> 00036 #include <fstream> 00037 00038 00039 namespace barrett { 00040 namespace log { 00041 00042 00043 template<typename T, typename Traits> 00044 Reader<T, Traits>::Reader(const char* fileName) : 00045 file(fileName, std::ios_base::binary), recordLength(Traits::serializedLength()), recordCount(0) 00046 { 00047 if (recordLength == 0) { 00048 throw(std::logic_error("(log::Reader::Reader): The record length " 00049 "(Traits::serializedLength()) cannot be zero.")); 00050 } 00051 00052 file.seekg(0, std::ifstream::end); 00053 long size = file.tellg(); 00054 00055 if (size % recordLength != 0) { 00056 std::stringstream ss; 00057 ss << "(log::Reader::Reader): The file '" << fileName 00058 << "' is corrupted or does not contain this type of data. Its " 00059 "size is not evenly divisible by the record length (" 00060 << recordLength << " bytes)."; 00061 throw(std::runtime_error(ss.str())); 00062 } 00063 recordCount = size / recordLength; 00064 file.seekg(0); 00065 00066 buffer = new char[recordLength]; 00067 } 00068 00069 template<typename T, typename Traits> 00070 Reader<T, Traits>::~Reader() 00071 { 00072 if (file.is_open()) { 00073 close(); 00074 } 00075 00076 delete[] buffer; 00077 buffer = NULL; 00078 } 00079 00080 template<typename T, typename Traits> 00081 inline size_t Reader<T, Traits>::numRecords() const 00082 { 00083 return recordCount; 00084 } 00085 00086 template<typename T, typename Traits> 00087 inline T Reader<T, Traits>::getRecord() 00088 { 00089 file.read(buffer, recordLength); 00090 00091 if (file.eof()) { 00092 throw(std::underflow_error("(log::Reader::getRecord()): The end of the file was reached. There are no more records to read.")); 00093 } 00094 00095 return Traits::unserialize(buffer); 00096 } 00097 00098 template<typename T, typename Traits> 00099 inline void Reader<T, Traits>::exportCSV(const char* outputFileName) 00100 { 00101 std::ofstream ofs(outputFileName); 00102 exportCSV(ofs); 00103 ofs.close(); 00104 } 00105 00106 template<typename T, typename Traits> 00107 void Reader<T, Traits>::exportCSV(std::ostream& os) 00108 { 00109 try { 00110 for (size_t i = 0; i < numRecords(); ++i) { 00111 Traits::asCSV(getRecord(), os); 00112 os << std::endl; 00113 } 00114 } catch (std::underflow_error) {} 00115 } 00116 00117 template<typename T, typename Traits> 00118 inline void Reader<T, Traits>::close() 00119 { 00120 file.close(); 00121 } 00122 00123 00124 } 00125 }