libept
|
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 // std::cerr << "parsing line: " << line << std::endl; 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 // std::cerr << "type: " << tmp << std::endl; 00174 if (tmp == "deb" || tmp == "deb-src") { 00175 e.setTypeString( tmp ); 00176 } else { 00177 // std::cerr << "comment: '" << line << "'" << std::endl; 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 // vim:set ts=4 sw=4: