ContentFileReader.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <sstream>
00014
00015 #include "zypp/base/LogTools.h"
00016 #include "zypp/base/String.h"
00017 #include "zypp/base/IOStream.h"
00018 #include "zypp/base/UserRequestException.h"
00019 #include "zypp/parser/ParseException.h"
00020
00021 #include "zypp/parser/susetags/ContentFileReader.h"
00022 #include "zypp/parser/susetags/RepoIndex.h"
00023
00024 using std::endl;
00025 #undef ZYPP_BASE_LOGGER_LOGGROUP
00026 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::susetags"
00027
00029 namespace zypp
00030 {
00031
00032 namespace parser
00033 {
00034
00035 namespace susetags
00036 {
00037
00039
00040
00041
00043 struct ContentFileReader::Impl
00044 {
00045 public:
00046 Impl( const ContentFileReader & parent_r )
00047 : _parent( parent_r )
00048 {}
00049
00050 RepoIndex & repoindex()
00051 {
00052 if ( !_repoindex )
00053 _repoindex = new RepoIndex;
00054 return *_repoindex;
00055 }
00056
00057 bool hasRepoIndex() const
00058 { return _repoindex; }
00059
00060 RepoIndex_Ptr handoutRepoIndex()
00061 {
00062 RepoIndex_Ptr ret;
00063 ret.swap( _repoindex );
00064 _repoindex = 0;
00065 return ret;
00066 }
00067
00068 public:
00069 bool setFileCheckSum( std::map<std::string, CheckSum> & map_r, const std::string & value ) const
00070 {
00071 bool error = false;
00072 std::vector<std::string> words;
00073 if ( str::split( value, std::back_inserter( words ) ) == 3 )
00074 {
00075 map_r[words[2]] = CheckSum( words[0], words[1] );
00076 }
00077 else
00078 {
00079 error = true;
00080 }
00081 return error;
00082 }
00083
00084 public:
00085 std::string _inputname;
00086
00087 private:
00088 const ContentFileReader & _parent;
00089 RepoIndex_Ptr _repoindex;
00090 };
00092
00094
00095
00096
00098
00100
00101
00102
00103
00104 ContentFileReader::ContentFileReader()
00105 {}
00106
00108
00109
00110
00111
00112 ContentFileReader::~ContentFileReader()
00113 {}
00114
00116
00117
00118
00119
00120 void ContentFileReader::beginParse()
00121 {
00122 _pimpl.reset( new Impl(*this) );
00123
00124 _pimpl->repoindex().descrdir = "suse/setup/descr";
00125 _pimpl->repoindex().datadir = "suse";
00126 }
00127
00129
00130
00131
00132
00133 void ContentFileReader::endParse()
00134 {
00135
00136 if ( _pimpl->hasRepoIndex() )
00137 {
00138 if ( _repoIndexConsumer )
00139 _repoIndexConsumer( _pimpl->handoutRepoIndex() );
00140 }
00141
00142 MIL << "[Content]" << endl;
00143 _pimpl.reset();
00144 }
00145
00147
00148
00149
00150
00151 void ContentFileReader::userRequestedAbort( unsigned lineNo_r )
00152 {
00153 ZYPP_THROW( AbortRequestException( errPrefix( lineNo_r ) ) );
00154 }
00155
00157
00158
00159
00160
00161 std::string ContentFileReader::errPrefix( unsigned lineNo_r,
00162 const std::string & msg_r,
00163 const std::string & line_r ) const
00164 {
00165 return str::form( "%s:%u:%s | %s",
00166 _pimpl->_inputname.c_str(),
00167 lineNo_r,
00168 line_r.c_str(),
00169 msg_r.c_str() );
00170 }
00171
00173
00174
00175
00176
00177 void ContentFileReader::parse( const InputStream & input_r,
00178 const ProgressData::ReceiverFnc & fnc_r )
00179 {
00180 MIL << "Start parsing content repoindex" << input_r << endl;
00181 if ( ! input_r.stream() )
00182 {
00183 std::ostringstream s;
00184 s << "Can't read bad stream: " << input_r;
00185 ZYPP_THROW( ParseException( s.str() ) );
00186 }
00187 beginParse();
00188 _pimpl->_inputname = input_r.name();
00189
00190 ProgressData ticks( makeProgressData( input_r ) );
00191 ticks.sendTo( fnc_r );
00192 if ( ! ticks.toMin() )
00193 userRequestedAbort( 0 );
00194
00195 iostr::EachLine line( input_r );
00196 for( ; line; line.next() )
00197 {
00198
00199 std::string value( *line );
00200 std::string key( str::stripFirstWord( value, true ) );
00201
00202 if ( key.empty() || *key.c_str() == '#' )
00203 {
00204 continue;
00205 }
00206
00207
00208 std::string modifier;
00209 std::string::size_type pos = key.rfind( '.' );
00210 if ( pos != std::string::npos )
00211 {
00212 modifier = key.substr( pos+1 );
00213 key.erase( pos );
00214 }
00215
00216
00217
00218
00219 else if ( key == "DESCRDIR" )
00220 {
00221 _pimpl->repoindex().descrdir = value;
00222 }
00223 else if ( key == "DATADIR" )
00224 {
00225 _pimpl->repoindex().datadir = value;
00226 }
00227 else if ( key == "KEY" )
00228 {
00229 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().signingKeys, value ) )
00230 {
00231 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [KEY algorithm checksum filename]", *line ) ) );
00232 }
00233 }
00234 else if ( key == "META" )
00235 {
00236 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().metaFileChecksums, value ) )
00237 {
00238 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
00239 }
00240 }
00241 else if ( key == "HASH" )
00242 {
00243 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().mediaFileChecksums, value ) )
00244 {
00245 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
00246 }
00247 }
00248 else
00249 {
00250 DBG << errPrefix( line.lineNo(), "ignored", *line ) << endl;
00251 }
00252
00253
00254 if ( ! ticks.set( input_r.stream().tellg() ) )
00255 userRequestedAbort( line.lineNo() );
00256 }
00257
00258
00259
00260
00261 if ( ! ticks.toMax() )
00262 userRequestedAbort( line.lineNo() );
00263
00264 endParse();
00265 MIL << "Done parsing " << input_r << endl;
00266 }
00267
00269 }
00272 }
00275 }