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 
32  namespace parser
33  {
34 
35  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 )
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  {
235  {
236  ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
237  }
238  }
239  else if ( key == "HASH" )
240  {
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