libzypp  13.10.6
ContentFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 
15 #include "zypp/base/LogTools.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/IOStream.h"
20 
23 
24 using std::endl;
25 #undef ZYPP_BASE_LOGGER_LOGGROUP
26 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::susetags"
27 
29 namespace zypp
30 {
31  namespace parser
33  {
34  namespace susetags
36  {
37 
39  //
40  // CLASS NAME : ContentFileReader::Impl
41  //
44  {
45  public:
46  Impl( const ContentFileReader & parent_r )
47  : _parent( parent_r )
48  {}
49 
51  {
52  if ( !_repoindex )
53  _repoindex = new RepoIndex;
54  return *_repoindex;
55  }
56 
57  bool hasRepoIndex() const
58  { return _repoindex != nullptr; }
59 
60  RepoIndex_Ptr handoutRepoIndex()
61  {
62  RepoIndex_Ptr ret;
63  ret.swap( _repoindex );
64  _repoindex = nullptr;
65  return ret;
66  }
67 
68  public:
69  bool setFileCheckSum( std::map<std::string, CheckSum> & map_r, const std::string & value ) const
70  {
71  bool error = false;
72  std::vector<std::string> words;
73  if ( str::split( value, std::back_inserter( words ) ) == 3 )
74  {
75  map_r[words[2]] = CheckSum( words[0], words[1] );
76  }
77  else
78  {
79  error = true;
80  }
81  return error;
82  }
83 
84  public:
85  std::string _inputname;
86 
87  private:
89  RepoIndex_Ptr _repoindex;
90  };
92 
94  //
95  // CLASS NAME : ContentFileReader
96  //
98 
100  //
101  // METHOD NAME : ContentFileReader::ContentFileReader
102  // METHOD TYPE : Ctor
103  //
105  {}
106 
108  //
109  // METHOD NAME : ContentFileReader::~ContentFileReader
110  // METHOD TYPE : Dtor
111  //
113  {}
114 
116  //
117  // METHOD NAME : ContentFileReader::beginParse
118  // METHOD TYPE : void
119  //
121  {
122  _pimpl.reset( new Impl(*this) );
123  // actually mandatory, but in case they were forgotten...
124  _pimpl->repoindex().descrdir = "suse/setup/descr";
125  _pimpl->repoindex().datadir = "suse";
126  }
127 
129  //
130  // METHOD NAME : ContentFileReader::endParse
131  // METHOD TYPE : void
132  //
134  {
135  // consume oldData
136  if ( _pimpl->hasRepoIndex() )
137  {
138  if ( _repoIndexConsumer )
139  _repoIndexConsumer( _pimpl->handoutRepoIndex() );
140  }
141 
142  MIL << "[Content]" << endl;
143  _pimpl.reset();
144  }
145 
147  //
148  // METHOD NAME : ContentFileReader::userRequestedAbort
149  // METHOD TYPE : void
150  //
151  void ContentFileReader::userRequestedAbort( unsigned lineNo_r )
152  {
153  ZYPP_THROW( AbortRequestException( errPrefix( lineNo_r ) ) );
154  }
155 
157  //
158  // METHOD NAME : ContentFileReader::errPrefix
159  // METHOD TYPE : std::string
160  //
161  std::string ContentFileReader::errPrefix( unsigned lineNo_r,
162  const std::string & msg_r,
163  const std::string & line_r ) const
164  {
165  return str::form( "%s:%u:%s | %s",
166  _pimpl->_inputname.c_str(),
167  lineNo_r,
168  line_r.c_str(),
169  msg_r.c_str() );
170  }
171 
173  //
174  // METHOD NAME : ContentFileReader::parse
175  // METHOD TYPE : void
176  //
177  void ContentFileReader::parse( const InputStream & input_r,
178  const ProgressData::ReceiverFnc & fnc_r )
179  {
180  MIL << "Start parsing content repoindex" << input_r << endl;
181  if ( ! input_r.stream() )
182  {
183  std::ostringstream s;
184  s << "Can't read bad stream: " << input_r;
185  ZYPP_THROW( ParseException( s.str() ) );
186  }
187  beginParse();
188  _pimpl->_inputname = input_r.name();
189 
190  ProgressData ticks( makeProgressData( input_r ) );
191  ticks.sendTo( fnc_r );
192  if ( ! ticks.toMin() )
193  userRequestedAbort( 0 );
194 
195  iostr::EachLine line( input_r );
196  for( ; line; line.next() )
197  {
198  // strip 1st word from line to separate tag and value.
199  std::string value( *line );
200  std::string key( str::stripFirstWord( value, /*ltrim_first*/true ) );
201 
202  if ( key.empty() || *key.c_str() == '#' ) // empty or comment line
203  {
204  continue;
205  }
206 
207  // strip modifier if exists
208  std::string modifier;
209  std::string::size_type pos = key.rfind( '.' );
210  if ( pos != std::string::npos )
211  {
212  modifier = key.substr( pos+1 );
213  key.erase( pos );
214  }
215 
216  //
217  // ReppoIndex related data:
218  //
219  else if ( key == "DESCRDIR" )
220  {
221  _pimpl->repoindex().descrdir = value;
222  }
223  else if ( key == "DATADIR" )
224  {
225  _pimpl->repoindex().datadir = value;
226  }
227  else if ( key == "KEY" )
228  {
229  if ( _pimpl->setFileCheckSum( _pimpl->repoindex().signingKeys, value ) )
230  {
231  ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [KEY algorithm checksum filename]", *line ) ) );
232  }
233  }
234  else if ( key == "META" )
235  {
236  if ( _pimpl->setFileCheckSum( _pimpl->repoindex().metaFileChecksums, value ) )
237  {
238  ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
239  }
240  }
241  else if ( key == "HASH" )
242  {
243  if ( _pimpl->setFileCheckSum( _pimpl->repoindex().mediaFileChecksums, value ) )
244  {
245  ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
246  }
247  }
248  else
249  {
250  DBG << errPrefix( line.lineNo(), "ignored", *line ) << endl;
251  }
252 
253 
254  if ( ! ticks.set( input_r.stream().tellg() ) )
255  userRequestedAbort( line.lineNo() );
256  }
257 
258  //
259  // post processing
260  //
261  if ( ! ticks.toMax() )
262  userRequestedAbort( line.lineNo() );
263 
264  endParse();
265  MIL << "Done parsing " << input_r << endl;
266  }
267 
269  } // namespace susetags
272  } // namespace parser
275 } // namespace zypp
#define MIL
Definition: Logger.h:47
Repository content data (from /content file).
Definition: RepoIndex.h:48
ProgressData makeProgressData(const InputStream &input_r)
bool setFileCheckSum(std::map< std::string, CheckSum > &map_r, const std::string &value) const
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: ProgressData.h:231
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:320
bool next()
Advance to next line.
Definition: IOStream.cc:72
unsigned split(const C_Str &line_r, _OutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
Definition: String.h:394
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
bool toMax()
Set counter value to current max value (unless no range).
Definition: ProgressData.h:270
unsigned lineNo() const
Return the current line number.
Definition: IOStream.h:126
Helper to create and pass std::istream.
Definition: InputStream.h:56
DBusError error
Definition: HalContext.cc:86
Simple lineparser: Traverse each line in a file.
Definition: IOStream.h:111
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:144
std::string errPrefix(unsigned lineNo_r, const std::string &msg_r=std::string(), const std::string &line_r="-") const
Prefix exception message with line information.
virtual void userRequestedAbort(unsigned lineNo_r)
Called when user(callback) request to abort.
bool toMin()
Set counter value to current min value.
Definition: ProgressData.h:266
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:237
Parse repoindex part from a content file.
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:135
virtual void beginParse()
Called when start parsing.
SolvableIdType size_type
Definition: PoolMember.h:99
std::istream & stream() const
The std::istream.
Definition: InputStream.h:93
std::string form(const char *format,...)
Printf style construction of std::string.
Definition: String.cc:34
const std::string & name() const
Name of the std::istream.
Definition: InputStream.h:107
virtual void endParse()
Called when the parse is done.
bool set(value_type val_r)
Set new counter value.
Definition: ProgressData.h:251
virtual void parse(const InputStream &imput_r, const ProgressData::ReceiverFnc &fnc_r=ProgressData::ReceiverFnc())
Parse the stream.
Impl(const ContentFileReader &parent_r)
#define DBG
Definition: Logger.h:46