libept
sources.h
Go to the documentation of this file.
1 
6 #include <iterator>
7 #include <iostream>
8 #include <sstream>
9 #include <string>
10 
11 #include <wibble/range.h>
12 #include <wibble/mixin.h>
13 
14 #ifndef EPT_SOURCES_H
15 #define EPT_SOURCES_H
16 
17 namespace ept {
18 
19 struct Sources {
20  struct Entry : wibble::mixin::Comparable< Entry > {
21  typedef wibble::Range< std::string > StringRange;
22  typedef wibble::Consumer< std::string > StringConsumer;
23  typedef std::vector< std::string > StringVector;
24  struct Word { std::string s; };
25  enum Type { Binary, Source, Comment };
26  Entry( bool e = false, Type t = Comment,
27  std::string u = "", std::string d = "",
28  StringRange c = wibble::range( *new StringVector ) )
29  : m_enabled( e ), m_type( t ), m_url( u ), m_dist( d )
30  {
31  c.output( wibble::consumer( m_components ) );
32  }
33 
34  Entry( const Entry &e )
35  : m_enabled( e.m_enabled ), m_type( e.m_type ), m_url( e.m_url ),
36  m_dist( e.m_dist ), m_comment( e.m_comment )
37  {
38  wibble::range( e.m_components ).output( wibble::consumer( m_components ) );
39  }
40 
41  bool operator< ( const Entry &o ) const {
42  if (type() < o.type())
43  return true;
44  if (enabled() < o.enabled())
45  return true;
46  if (url() < o.url())
47  return true;
48  if (distribution() < o.distribution())
49  return true;
50  if (components() < o.components())
51  return true;
52  if (comment() < o.comment())
53  return true;
54  return false;
55  }
56 
57  bool operator== ( const Entry &e ) const {
58  return not ( ( *this < e ) || ( e < *this ) );
59  }
60 
61  std::string components() const {
62  std::ostringstream s;
63  std::copy( m_components.begin(), m_components.end(),
64  std::ostream_iterator< std::string >( s, " " ) );
65  return s.str();
66  }
67 
68  void setComponents( const std::string &s ) {
69  std::istringstream i( s );
70  m_components.clear();
71  std::copy( std::istream_iterator< std::string >( i ),
72  std::istream_iterator< std::string >(),
73  wibble::consumer( m_components ) );
74  }
75 
76  std::string typeString() const {
77  switch (type())
78  {
79  case Binary: return "deb";
80  case Source: return "deb-src";
81  case Comment: return "comment";
82  }
83  }
84 
85  void setTypeString( const std::string &s ) {
86  if (s == "deb") setType( Binary );
87  if (s == "deb-src") setType( Source );
88  if (s == "comment") setType( Comment );
89  }
90 
91  std::string distribution() const { return m_dist; }
92  void setDistribution( const std::string &s ) { m_dist = s; }
93 
94  std::string url() const { return m_url; }
95  void setUrl( const std::string &s ) { m_url = s; }
96 
97  bool enabled() const { return m_enabled; }
98  void setEnabled( bool e ) { m_enabled = e; }
99 
100  std::string comment() const { return m_comment; }
101  void setComment( const std::string &s ) { m_comment = s; }
102 
103  Type type() const { return m_type; }
104  void setType( Type t ) {
105  m_type = t;
106  if (t == Comment) setEnabled( false );
107  }
108 
109  friend std::istream &operator >>( std::istream &i, Entry &s );
110 
111  protected:
112 
113  bool m_enabled;
115  std::string m_url;
116  std::string m_dist;
118  std::string m_comment;
119  };
120  void add( const Entry &e ) {
121  wibble::consumer( m_entries ).consume( e );
122  }
123  void clear() { m_entries.clear(); }
124  void disable( const Entry & );
125  void enable( const Entry & );
126  wibble::Range< Entry > entries() const {
127  return wibble::range( m_entries );
128  }
129  friend std::istream &operator >>( std::istream &i, Sources &s );
130 protected:
131  std::vector< Entry > m_entries;
132 };
133 
134 inline std::istream &operator >>( std::istream &i, Sources::Entry::Word &w )
135 {
136  bool bracket = false, quote = false, started = false;
137  char c;
138  w.s = "";
139  while (!i.eof()) {
140  c = i.get();
141  if (started && !quote && !bracket && isspace( c ))
142  break;
143  if (!isspace( c ))
144  started = true;
145  if (started)
146  w.s += c;
147  if (bracket && c == ']')
148  bracket = false;
149  if (quote && c == '"')
150  quote = false;
151  if (!quote && c == '[')
152  bracket = true;
153  if (!bracket && c == '"')
154  quote = true;
155  }
156  return i;
157 }
158 
159 inline std::istream &operator >>( std::istream &i, Sources::Entry &e ) {
160  std::string line, tmp;
161  std::getline( i, line );
162  std::istringstream l( line );
163  // std::cerr << "parsing line: " << line << std::endl;
164  l >> tmp;
165  e.setEnabled( true );
166  if (tmp[0] == '#') {
167  if (tmp.size() > 1)
168  tmp = tmp.substr(1);
169  else
170  l >> tmp;
171  e.setEnabled( false );
172  }
173  // std::cerr << "type: " << tmp << std::endl;
174  if (tmp == "deb" || tmp == "deb-src") {
175  e.setTypeString( tmp );
176  } else {
177  // std::cerr << "comment: '" << line << "'" << std::endl;
179  e.setEnabled( false );
180  e.setComment( line );
181  return i;
182  }
184  l >> w; e.m_url = w.s;
185  l >> w; e.m_dist = w.s;
186  e.m_components.clear();
187  std::copy( std::istream_iterator< std::string >( l ),
188  std::istream_iterator< std::string >(),
189  wibble::consumer( e.m_components ) );
190  return i;
191 }
192 
193 inline std::ostream &operator <<( std::ostream &o, const Sources::Entry &e )
194 {
195  if (e.type() == Sources::Entry::Comment)
196  return o << e.comment();
197  if (! e.enabled())
198  o << "# ";
199  o << e.typeString();
200  o << " " << e.url() << " " << e.distribution() << " " << e.components();
201  return o;
202 }
203 
204 inline std::istream &operator >>( std::istream &i, Sources &s ) {
205  std::copy( std::istream_iterator< Sources::Entry >( i ),
206  std::istream_iterator< Sources::Entry >(),
207  wibble::consumer( s.m_entries ) );
208  return i;
209 }
210 
211 inline std::ostream &operator <<( std::ostream &o, const Sources &s ) {
212  std::copy( s.entries().begin(), s.entries().end(),
213  std::ostream_iterator< Sources::Entry >( o, "\n" ) );
214  return o;
215 }
216 
217 }
218 
219 #endif
220 // vim:set ts=4 sw=4: