Go to the documentation of this file.00001
00006 #include <iterator>
00007 #include <iostream>
00008 #include <sstream>
00009 #include <string>
00010
00011 #include <wibble/range.h>
00012 #include <wibble/mixin.h>
00013
00014 #ifndef EPT_SOURCES_H
00015 #define EPT_SOURCES_H
00016
00017 namespace ept {
00018
00019 struct Sources {
00020 struct Entry : wibble::mixin::Comparable< Entry > {
00021 typedef wibble::Range< std::string > StringRange;
00022 typedef wibble::Consumer< std::string > StringConsumer;
00023 typedef std::vector< std::string > StringVector;
00024 struct Word { std::string s; };
00025 enum Type { Binary, Source, Comment };
00026 Entry( bool e = false, Type t = Comment,
00027 std::string u = "", std::string d = "",
00028 StringRange c = wibble::range( *new StringVector ) )
00029 : m_enabled( e ), m_type( t ), m_url( u ), m_dist( d )
00030 {
00031 c.output( wibble::consumer( m_components ) );
00032 }
00033
00034 Entry( const Entry &e )
00035 : m_enabled( e.m_enabled ), m_type( e.m_type ), m_url( e.m_url ),
00036 m_dist( e.m_dist ), m_comment( e.m_comment )
00037 {
00038 wibble::range( e.m_components ).output( wibble::consumer( m_components ) );
00039 }
00040
00041 bool operator< ( const Entry &o ) const {
00042 if (type() < o.type())
00043 return true;
00044 if (enabled() < o.enabled())
00045 return true;
00046 if (url() < o.url())
00047 return true;
00048 if (distribution() < o.distribution())
00049 return true;
00050 if (components() < o.components())
00051 return true;
00052 if (comment() < o.comment())
00053 return true;
00054 return false;
00055 }
00056
00057 bool operator== ( const Entry &e ) const {
00058 return not ( ( *this < e ) || ( e < *this ) );
00059 }
00060
00061 std::string components() const {
00062 std::ostringstream s;
00063 std::copy( m_components.begin(), m_components.end(),
00064 std::ostream_iterator< std::string >( s, " " ) );
00065 return s.str();
00066 }
00067
00068 void setComponents( const std::string &s ) {
00069 std::istringstream i( s );
00070 m_components.clear();
00071 std::copy( std::istream_iterator< std::string >( i ),
00072 std::istream_iterator< std::string >(),
00073 wibble::consumer( m_components ) );
00074 }
00075
00076 std::string typeString() const {
00077 switch (type())
00078 {
00079 case Binary: return "deb";
00080 case Source: return "deb-src";
00081 case Comment: return "comment";
00082 }
00083 }
00084
00085 void setTypeString( const std::string &s ) {
00086 if (s == "deb") setType( Binary );
00087 if (s == "deb-src") setType( Source );
00088 if (s == "comment") setType( Comment );
00089 }
00090
00091 std::string distribution() const { return m_dist; }
00092 void setDistribution( const std::string &s ) { m_dist = s; }
00093
00094 std::string url() const { return m_url; }
00095 void setUrl( const std::string &s ) { m_url = s; }
00096
00097 bool enabled() const { return m_enabled; }
00098 void setEnabled( bool e ) { m_enabled = e; }
00099
00100 std::string comment() const { return m_comment; }
00101 void setComment( const std::string &s ) { m_comment = s; }
00102
00103 Type type() const { return m_type; }
00104 void setType( Type t ) {
00105 m_type = t;
00106 if (t == Comment) setEnabled( false );
00107 }
00108
00109 friend std::istream &operator >>( std::istream &i, Entry &s );
00110
00111 protected:
00112
00113 bool m_enabled;
00114 Type m_type;
00115 std::string m_url;
00116 std::string m_dist;
00117 StringVector m_components;
00118 std::string m_comment;
00119 };
00120 void add( const Entry &e ) {
00121 wibble::consumer( m_entries ).consume( e );
00122 }
00123 void clear() { m_entries.clear(); }
00124 void disable( const Entry & );
00125 void enable( const Entry & );
00126 wibble::Range< Entry > entries() const {
00127 return wibble::range( m_entries );
00128 }
00129 friend std::istream &operator >>( std::istream &i, Sources &s );
00130 protected:
00131 std::vector< Entry > m_entries;
00132 };
00133
00134 inline std::istream &operator >>( std::istream &i, Sources::Entry::Word &w )
00135 {
00136 bool bracket = false, quote = false, started = false;
00137 char c;
00138 w.s = "";
00139 while (!i.eof()) {
00140 c = i.get();
00141 if (started && !quote && !bracket && isspace( c ))
00142 break;
00143 if (!isspace( c ))
00144 started = true;
00145 if (started)
00146 w.s += c;
00147 if (bracket && c == ']')
00148 bracket = false;
00149 if (quote && c == '"')
00150 quote = false;
00151 if (!quote && c == '[')
00152 bracket = true;
00153 if (!bracket && c == '"')
00154 quote = true;
00155 }
00156 return i;
00157 }
00158
00159 inline std::istream &operator >>( std::istream &i, Sources::Entry &e ) {
00160 std::string line, tmp;
00161 std::getline( i, line );
00162 std::istringstream l( line );
00163
00164 l >> tmp;
00165 e.setEnabled( true );
00166 if (tmp[0] == '#') {
00167 if (tmp.size() > 1)
00168 tmp = tmp.substr(1);
00169 else
00170 l >> tmp;
00171 e.setEnabled( false );
00172 }
00173
00174 if (tmp == "deb" || tmp == "deb-src") {
00175 e.setTypeString( tmp );
00176 } else {
00177
00178 e.setType( Sources::Entry::Comment );
00179 e.setEnabled( false );
00180 e.setComment( line );
00181 return i;
00182 }
00183 Sources::Entry::Word w;
00184 l >> w; e.m_url = w.s;
00185 l >> w; e.m_dist = w.s;
00186 e.m_components.clear();
00187 std::copy( std::istream_iterator< std::string >( l ),
00188 std::istream_iterator< std::string >(),
00189 wibble::consumer( e.m_components ) );
00190 return i;
00191 }
00192
00193 inline std::ostream &operator <<( std::ostream &o, const Sources::Entry &e )
00194 {
00195 if (e.type() == Sources::Entry::Comment)
00196 return o << e.comment();
00197 if (! e.enabled())
00198 o << "# ";
00199 o << e.typeString();
00200 o << " " << e.url() << " " << e.distribution() << " " << e.components();
00201 return o;
00202 }
00203
00204 inline std::istream &operator >>( std::istream &i, Sources &s ) {
00205 std::copy( std::istream_iterator< Sources::Entry >( i ),
00206 std::istream_iterator< Sources::Entry >(),
00207 wibble::consumer( s.m_entries ) );
00208 return i;
00209 }
00210
00211 inline std::ostream &operator <<( std::ostream &o, const Sources &s ) {
00212 std::copy( s.entries().begin(), s.entries().end(),
00213 std::ostream_iterator< Sources::Entry >( o, "\n" ) );
00214 return o;
00215 }
00216
00217 }
00218
00219 #endif
00220