libzypp  13.10.6
ProductFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/Exception.h"
15 #include "zypp/base/Functional.h"
16 
17 #include "zypp/PathInfo.h"
18 
22 #include "zypp/parser/xml/Reader.h"
23 
24 using std::endl;
25 
27 namespace zypp
28 {
29  namespace parser
31  {
32 
34  //
35  // class ProductFileData::Upgrade
36  //
38 
40  {
41  std::string _name;
42  std::string _summary;
43  std::string _repository;
44  std::string _product;
46  std::string _status;
47  };
48 
50  : _pimpl( allocated_r ? allocated_r : new Impl )
51  {}
52 
53  std::string ProductFileData::Upgrade::name() const { return _pimpl->_name; }
54  std::string ProductFileData::Upgrade::summary() const { return _pimpl->_summary; }
55  std::string ProductFileData::Upgrade::repository() const { return _pimpl->_repository; }
56  std::string ProductFileData::Upgrade::product() const { return _pimpl->_product; }
57  bool ProductFileData::Upgrade::notify() const { return _pimpl->_notify; }
58  std::string ProductFileData::Upgrade::status() const { return _pimpl->_status; }
59 
61  //
62  // class ProductFileData
63  //
65 
67  {
72 
73  std::string _shortName;
74  std::string _summary;
75 
76  std::string _productline;
77  std::string _registerTarget;
78  std::string _registerRelease;
79 
80  std::string _updaterepokey;
81 
83  };
84 
86  : _pimpl( allocated_r ? allocated_r : new Impl )
87  {}
88 
89  IdString ProductFileData::vendor() const { return _pimpl->_vendor; }
90  IdString ProductFileData::name() const { return _pimpl->_name; }
91  Edition ProductFileData::edition() const { return _pimpl->_edition; }
92  Arch ProductFileData::arch() const { return _pimpl->_arch; }
93 
94  std::string ProductFileData::shortName() const { return _pimpl->_shortName; }
95  std::string ProductFileData::summary() const { return _pimpl->_summary; }
96 
97  std::string ProductFileData::productline() const { return _pimpl->_productline; }
98  std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; }
99  std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; }
100 
101  std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
102 
103  const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; }
104 
105  std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
106  {
107  str << str::form( "|product|%s|%s|%s|%s|",
108  obj.name().c_str(),
109  obj.edition().c_str(),
110  obj.arch().c_str(),
111  obj.vendor().c_str() );
112  if ( ! obj.upgrades().empty() )
113  {
114  for_( it, obj.upgrades().begin(), obj.upgrades().end() )
115  str << endl << " " << *it;
116  }
117  return str;
118  }
119 
120  std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
121  {
122  str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
123  obj.name().c_str(),
124  obj.repository().c_str(),
125  obj.product().c_str(),
126  obj.status().c_str(),
127  (obj.notify() ? "notify" : "noNotify") );
128  return str;
129  }
131  //
132  // class ProductFileReader
133  //
135 
136  struct ProductNode : public xml::ParseDef
137  {
139  : ParseDef( "product", MANDTAORY )
140  , _pdata( pdata_r )
141  {
142  (*this)
143  ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) )
144  ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) )
145  ("version", MANDTAORY, xml::parseDefAssign( _version ) )
146  ("release", MANDTAORY, xml::parseDefAssign( _release ) )
147  ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) )
148  ("shortsummary", OPTIONAL, xml::parseDefAssign( _pdata._shortName ) )
149  ("summary", MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale )
150  >>bind( &ProductNode::doneLocalizedDefault, this, _1, boost::ref(_pdata._summary) ))
151  ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) )
152  ("register", OPTIONAL)
153  ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) )
154  ("upgrades", OPTIONAL)
155  ;
156 
157  (*this)["register"]
158  ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) )
159  ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) )
160  ;
161 
162  (*this)["upgrades"]
163  ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign()
164  >> bind( &ProductNode::doneUpgrade, this, _1 ))
165  ;
166 
167  (*this)["upgrades"]["upgrade"]
168  ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) )
169  ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) )
170  ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) )
171  ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) )
172  ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) )
173  ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) )
174  ;
175 
176  // </product> callback to build edition.
177  setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
178  // xml::ParseDef::_debug = true;
179  }
180 
182  void doneUpgrade( const xml::Node & _node )
183  {
185  _pdata._upgrades.push_back( cdata );
187  }
189  void doneLocalizedDefault( const xml::Node & _node, std::string & store_r )
190  {
191  // take 1st or default
192  if ( store_r.empty() || _tlocale.empty() )
193  store_r = _ttext;
194  }
195 
197  void done( const xml::Node & _node )
198  {
200  }
201 
202  private:
204 
205  std::string _version;
206  std::string _release;
207 
208  std::string _ttext;
209  std::string _tlocale;
210 
212  };
213 
214  bool ProductFileReader::parse( const InputStream & input_r ) const
215  {
216  MIL << "+++" << input_r << endl;
217  bool ret = true;
218 
219  ProductFileData::Impl * pdataImpl = 0;
220  ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
221 
222  try
223  {
224  xml::Reader reader( input_r );
225  ProductNode rootNode( *pdataImpl );
226  rootNode.take( reader );
227 
228  }
229  catch ( const Exception & err )
230  {
231  // parse error
232  ERR << err << endl;
233  ERR << "---" << ret << " - " << input_r << endl;
234  return ret;
235  }
236 
237  if ( _consumer )
238  {
239  ret = _consumer( pdata );
240  }
241 
242  MIL << "---" << ret << " - " << input_r << endl;
243  return ret;
244  }
245 
247 
248  bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
249  {
250  std::list<Pathname> retlist;
251  int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
252  if ( res != 0 )
253  {
254  WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
255  return true;
256  }
257 
258  ProductFileReader reader( consumer_r );
259  for_( it, retlist.begin(), retlist.end() )
260  {
261  if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
262  {
263  return false; // consumer_r request to stop parsing.
264  }
265  }
266  return true;
267  }
268 
269  ProductFileData ProductFileReader::scanFile( const Pathname & file_r )
270  {
271  if ( ! PathInfo( file_r ).isFile() )
272  {
273  WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
274  return ProductFileData();
275  }
276 
277  ProductFileData ret;
278  ProductFileReader reader( functor::getFirst( ret ), file_r );
279  return ret;
280  }
281 
283  } // namespace parser
286 } // namespace zypp
ProductFileData::Impl & _pdata
std::string shortName() const
#define MIL
Definition: Logger.h:47
ParseDef(const std::string &name_r, Mode mode_r)
Definition: ParseDef.cc:369
Define a xml node structure to parse.
Definition: ParseDef.h:128
Architecture.
Definition: Arch.h:36
static ProductFileData scanFile(const Pathname &file_r)
Parse one file (or symlink) and return the ProductFileData parsed.
GetFirst< _Tp > getFirst(_Tp &result_r)
Convenience function for creating GetFirst.
Definition: Functional.h:384
Access to the sat-pools string space.
Definition: IdString.h:39
std::ostream & operator<<(std::ostream &str, const IniDict &obj)
Definition: IniDict.cc:143
Helper to create and pass std::istream.
Definition: InputStream.h:56
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
Edition represents [epoch:]version[-release]
Definition: Edition.h:60
#define ERR
Definition: Logger.h:49
RWCOW_pointer< Impl > _pimpl
const Upgrades & upgrades() const
void done(const xml::Node &_node)
finaly
xmlTextReader based interface to Reader&#39;s current node.
Definition: Node.h:35
ProductNode(ProductFileData::Impl &pdata_r)
void take(Reader &reader_r)
Parse the node.
Definition: ParseDef.cc:439
#define WAR
Definition: Logger.h:48
std::string registerTarget() const
void doneUpgrade(const xml::Node &_node)
collect _upgrade
bool parse(const InputStream &input_r=InputStream()) const
Parse the input stream and call _consumer for each parsed section.
const char * c_str() const
Conversion to const char *
Definition: IdString.cc:42
void doneLocalizedDefault(const xml::Node &_node, std::string &store_r)
collect localized data
const char * c_str() const
Definition: Arch.h:59
std::string form(const char *format,...)
Printf style construction of std::string.
Definition: String.cc:34
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:599
const char * c_str() const
Definition: IdStringType.h:105
ProductFileData::Upgrade::Impl _upgrade
Base class for Exception.
Definition: Exception.h:143
Data returned by ProductFileReader.
Upgrade(Impl *allocated_r=0)
Ctor takes ownership of allocated_r.
void setConsumer(const shared_ptr< ParseDefConsume > &target_r)
Set data consumer.
Definition: ParseDef.cc:423
std::string productline() const
ProductFileData(Impl *allocated_r=0)
Ctor takes ownership of allocated_r.
std::vector< Upgrade > Upgrades
std::string registerRelease() const
Parser for /etc/products.d enries (just relevant entires).
std::string updaterepokey() const
static bool scanDir(const Consumer &consumer_r, const Pathname &dir_r)
Parse all files (no symlinks) in dir_r and call consumer_r for each ProductFileData parsed...
function< bool(const ProductFileData &)> Consumer
Callback being invoked for each ProductFileData parsed.
xmlTextReader based interface to iterate xml streams.
Definition: Reader.h:95