libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00009 00013 #include <iostream> 00014 00015 #include "zypp/base/InputStream.h" 00016 #include "zypp/base/IOStream.h" 00017 #include "zypp/base/Logger.h" 00018 #include "zypp/parser/ParseException.h" 00019 00020 #include "zypp/parser/HistoryLogReader.h" 00021 00022 using namespace std; 00023 00025 namespace zypp 00026 { 00027 00028 namespace parser 00029 { 00030 00031 00033 // 00034 // CLASS NAME: HistoryLogReader::Impl 00035 // 00037 00038 struct HistoryLogReader::Impl 00039 { 00040 Impl( const Pathname & historyFile, const ProcessItem & callback ); 00041 ~Impl() 00042 {} 00043 00044 HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields); 00045 void parseLine(const string & line, unsigned int lineNr); 00046 00047 void readAll(const ProgressData::ReceiverFnc & progress); 00048 void readFrom(const Date & date, 00049 const ProgressData::ReceiverFnc & progress); 00050 void readFromTo( 00051 const Date & fromDate, const Date & toDate, 00052 const ProgressData::ReceiverFnc & progress); 00053 00054 Pathname _filename; 00055 ProcessItem _callback; 00056 bool _ignoreInvalid; 00057 }; 00058 00059 HistoryLogReader::Impl::Impl( const Pathname & historyFile, 00060 const ProcessItem & callback ) 00061 : _filename(historyFile), _callback(callback), _ignoreInvalid(false) 00062 {} 00063 00064 HistoryItem::Ptr 00065 HistoryLogReader::Impl::createHistoryItem(HistoryItem::FieldVector & fields) 00066 { 00067 HistoryActionID aid(str::trim(fields[1])); 00068 switch (aid.toEnum()) 00069 { 00070 case HistoryActionID::INSTALL_e: 00071 return HistoryItemInstall::Ptr(new HistoryItemInstall(fields)); 00072 break; 00073 00074 case HistoryActionID::REMOVE_e: 00075 return HistoryItemRemove::Ptr(new HistoryItemRemove(fields)); 00076 break; 00077 00078 case HistoryActionID::REPO_ADD_e: 00079 return HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields)); 00080 break; 00081 00082 case HistoryActionID::REPO_REMOVE_e: 00083 return HistoryItemRepoRemove::Ptr(new HistoryItemRepoRemove(fields)); 00084 break; 00085 00086 case HistoryActionID::REPO_CHANGE_ALIAS_e: 00087 return HistoryItemRepoAliasChange::Ptr(new HistoryItemRepoAliasChange(fields)); 00088 break; 00089 00090 case HistoryActionID::REPO_CHANGE_URL_e: 00091 return HistoryItemRepoUrlChange::Ptr(new HistoryItemRepoUrlChange(fields)); 00092 break; 00093 00094 default: 00095 WAR << "Unknown history log action type: " << fields[1] << endl; 00096 } 00097 00098 return HistoryItem::Ptr(); 00099 } 00100 00101 void HistoryLogReader::Impl::parseLine(const string & line, unsigned int lineNr) 00102 { 00103 HistoryItem::FieldVector fields; 00104 HistoryItem::Ptr item_ptr; 00105 00106 // parse into fields 00107 str::splitEscaped(line, back_inserter(fields), "|", true); 00108 00109 if (fields.size() <= 2) 00110 { 00111 ParseException 00112 e(str::form("Error in history log on line #%u.", lineNr)); 00113 e.addHistory( 00114 str::form("Bad number of fields. Got %zd, expected more than %d.", 00115 fields.size(), 2)); 00116 ZYPP_THROW(e); 00117 } 00118 00119 try 00120 { 00121 item_ptr = createHistoryItem(fields); 00122 } 00123 catch (const Exception & e) 00124 { 00125 ZYPP_CAUGHT(e); 00126 ERR << "Invalid history log entry on line #" << lineNr << ":" << endl 00127 << line << endl; 00128 00129 if (!_ignoreInvalid) 00130 { 00131 ParseException newe( 00132 str::form("Error in history log on line #%u.", lineNr ) ); 00133 newe.remember(e); 00134 ZYPP_THROW(newe); 00135 } 00136 } 00137 00138 if (item_ptr) 00139 _callback(item_ptr); 00140 else if (!_ignoreInvalid) 00141 { 00142 ParseException 00143 e(str::form("Error in history log on line #%u.", lineNr)); 00144 e.addHistory("Unknown entry type."); 00145 ZYPP_THROW(e); 00146 } 00147 } 00148 00149 void HistoryLogReader::Impl::readAll(const ProgressData::ReceiverFnc & progress) 00150 { 00151 InputStream is(_filename); 00152 iostr::EachLine line(is); 00153 00154 ProgressData pd; 00155 pd.sendTo( progress ); 00156 pd.toMin(); 00157 00158 for (; line; line.next(), pd.tick() ) 00159 { 00160 // ignore comments 00161 if ((*line)[0] == '#') 00162 continue; 00163 00164 parseLine(*line, line.lineNo()); 00165 } 00166 00167 pd.toMax(); 00168 } 00169 00170 void HistoryLogReader::Impl::readFrom(const Date & date, 00171 const ProgressData::ReceiverFnc & progress) 00172 { 00173 InputStream is(_filename); 00174 iostr::EachLine line(is); 00175 00176 ProgressData pd; 00177 pd.sendTo( progress ); 00178 pd.toMin(); 00179 00180 bool pastDate = false; 00181 for (; line; line.next(), pd.tick()) 00182 { 00183 const string & s = *line; 00184 00185 // ignore comments 00186 if (s[0] == '#') 00187 continue; 00188 00189 if (pastDate) 00190 parseLine(s, line.lineNo()); 00191 else 00192 { 00193 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT); 00194 if (logDate > date) 00195 { 00196 pastDate = true; 00197 parseLine(s, line.lineNo()); 00198 } 00199 } 00200 } 00201 00202 pd.toMax(); 00203 } 00204 00205 void HistoryLogReader::Impl::readFromTo( 00206 const Date & fromDate, const Date & toDate, 00207 const ProgressData::ReceiverFnc & progress) 00208 { 00209 InputStream is(_filename); 00210 iostr::EachLine line(is); 00211 00212 ProgressData pd; 00213 pd.sendTo(progress); 00214 pd.toMin(); 00215 00216 bool pastFromDate = false; 00217 for (; line; line.next(), pd.tick()) 00218 { 00219 const string & s = *line; 00220 00221 // ignore comments 00222 if (s[0] == '#') 00223 continue; 00224 00225 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT); 00226 00227 // past toDate - stop reading 00228 if (logDate >= toDate) 00229 break; 00230 00231 // past fromDate - start reading 00232 if (!pastFromDate && logDate > fromDate) 00233 pastFromDate = true; 00234 00235 if (pastFromDate) 00236 parseLine(s, line.lineNo()); 00237 } 00238 00239 pd.toMax(); 00240 } 00241 00243 // 00244 // CLASS NAME: HistoryLogReader 00245 // 00247 00248 HistoryLogReader::HistoryLogReader( const Pathname & historyFile, 00249 const ProcessItem & callback ) 00250 : _pimpl(new HistoryLogReader::Impl(historyFile, callback)) 00251 {} 00252 00253 HistoryLogReader::~HistoryLogReader() 00254 {} 00255 00256 void HistoryLogReader::setIgnoreInvalidItems(bool ignoreInvalid) 00257 { _pimpl->_ignoreInvalid = ignoreInvalid; } 00258 00259 bool HistoryLogReader::ignoreInvalidItems() const 00260 { return _pimpl->_ignoreInvalid; } 00261 00262 void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress) 00263 { _pimpl->readAll(progress); } 00264 00265 void HistoryLogReader::readFrom(const Date & date, 00266 const ProgressData::ReceiverFnc & progress) 00267 { _pimpl->readFrom(date, progress); } 00268 00269 void HistoryLogReader::readFromTo( 00270 const Date & fromDate, const Date & toDate, 00271 const ProgressData::ReceiverFnc & progress) 00272 { _pimpl->readFromTo(fromDate, toDate, progress); } 00273 00274 00276 } // namespace parser 00279 } // namespace zypp