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