|
yast2-storage
|
00001 /* 00002 * Copyright (c) [2004-2009] Novell, Inc. 00003 * 00004 * All Rights Reserved. 00005 * 00006 * This program is free software; you can redistribute it and/or modify it 00007 * under the terms of version 2 of the GNU General Public License as published 00008 * by the Free Software Foundation. 00009 * 00010 * This program is distributed in the hope that it will be useful, but WITHOUT 00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00013 * more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, contact Novell, Inc. 00017 * 00018 * To contact Novell about this file by physical or electronic mail, you may 00019 * find current contact information at www.novell.com. 00020 */ 00021 00022 00023 #ifndef STORAGE_TMPL_H 00024 #define STORAGE_TMPL_H 00025 00026 #include <functional> 00027 #include <ostream> 00028 #include <fstream> 00029 #include <sstream> 00030 #include <list> 00031 #include <map> 00032 #include <deque> 00033 #include <iostream> 00034 00035 #include "storage/IterPair.h" 00036 #include "storage/FilterIterator.h" 00037 #include "storage/DerefIterator.h" 00038 #include "storage/AppUtil.h" 00039 00040 namespace storage 00041 { 00042 00043 template< class Value > 00044 class CheckFnc 00045 { 00046 public: 00047 CheckFnc( bool (* ChkFnc)( Value& )=NULL ) : m_check(ChkFnc) {} 00048 bool operator()(Value& d) const 00049 { return(m_check==NULL || (*m_check)(d)); } 00050 private: 00051 bool (* m_check)( Value& d ); 00052 }; 00053 00054 template< class Pred, class Iter > 00055 class ContainerIter : public FilterIterator< Pred, Iter > 00056 { 00057 typedef FilterIterator< Pred, Iter > _bclass; 00058 public: 00059 ContainerIter() : _bclass() {} 00060 ContainerIter( const Iter& b, const Iter& e, const Pred& p, 00061 bool atend=false ) : 00062 _bclass(b, e, p, atend ) {} 00063 ContainerIter( const IterPair<Iter>& pair, const Pred& p, 00064 bool atend=false ) : 00065 _bclass(pair, p, atend ) {} 00066 template< class It > 00067 ContainerIter( const It& i) : _bclass( i.begin(), i.end(), i.pred() ) 00068 { this->m_cur=i.cur(); } 00069 }; 00070 00071 template< class Pred, class Iter, class Value > 00072 class ContainerDerIter : public DerefIterator<Iter,Value> 00073 { 00074 typedef DerefIterator<Iter,Value> _bclass; 00075 public: 00076 ContainerDerIter() : _bclass() {} 00077 ContainerDerIter( const _bclass& i ) : _bclass(i) {} 00078 template< class It > 00079 ContainerDerIter( const It& i) : _bclass( i ) 00080 { this->m_cur=i.cur(); } 00081 }; 00082 00083 template< class Iter, class CastResult > 00084 class CastIterator : public Iter 00085 { 00086 public: 00087 typedef CastResult value_type; 00088 typedef CastResult& reference; 00089 typedef CastResult* pointer; 00090 00091 CastIterator() : Iter() {} 00092 CastIterator( const Iter& i ) : Iter( i ) {} 00093 template< class It > 00094 CastIterator( const It& i ) : Iter( i ) {} 00095 CastResult operator*() const 00096 { 00097 return( static_cast<CastResult>(Iter::operator*()) ); 00098 } 00099 CastResult* operator->() const 00100 { 00101 return( static_cast<CastResult*>(Iter::operator->()) ); 00102 } 00103 CastIterator& operator++() 00104 { 00105 Iter::operator++(); return(*this); 00106 } 00107 CastIterator operator++(int) 00108 { 00109 y2war( "Expensive ++ CastIterator" ); 00110 CastIterator tmp(*this); 00111 Iter::operator++(); 00112 return(tmp); 00113 } 00114 CastIterator& operator--() 00115 { 00116 Iter::operator--(); return(*this); 00117 } 00118 CastIterator operator--(int) 00119 { 00120 y2war( "Expensive -- CastIterator" ); 00121 CastIterator tmp(*this); 00122 Iter::operator--(); 00123 return(tmp); 00124 } 00125 }; 00126 00127 template < class Checker, class ContIter, class Iter, class Value > 00128 class CheckerIterator : public ContIter 00129 { 00130 public: 00131 CheckerIterator() {}; 00132 CheckerIterator( const Iter& b, const Iter& e, 00133 bool (* CheckFnc)( const Value& )=NULL, 00134 bool atend=false ) : 00135 ContIter( b, e, Checker( CheckFnc ), atend ) {} 00136 CheckerIterator( const IterPair<Iter>& p, 00137 bool (* CheckFnc)( const Value& )=NULL, 00138 bool atend=false ) : 00139 ContIter( p, Checker( CheckFnc ), atend ) {} 00140 template<class It> 00141 CheckerIterator( const It& i ) : 00142 ContIter( i.begin(), i.end(), Checker(i.pred()), false ) 00143 { this->m_cur=i.cur(); } 00144 }; 00145 00146 00147 template<class Num> string decString(Num number) 00148 { 00149 static_assert(std::is_integral<Num>::value, "not integral"); 00150 00151 std::ostringstream num_str; 00152 classic(num_str); 00153 num_str << number; 00154 return num_str.str(); 00155 } 00156 00157 template<class Num> string hexString(Num number) 00158 { 00159 static_assert(std::is_integral<Num>::value, "not integral"); 00160 00161 std::ostringstream num_str; 00162 classic(num_str); 00163 num_str << std::hex << number; 00164 return num_str.str(); 00165 } 00166 00167 template<class Value> void operator>>(const string& d, Value& v) 00168 { 00169 std::istringstream Data(d); 00170 classic(Data); 00171 Data >> v; 00172 } 00173 00174 template<class Value> std::ostream& operator<<( std::ostream& s, const std::list<Value>& l ) 00175 { 00176 s << "<"; 00177 for( typename std::list<Value>::const_iterator i=l.begin(); i!=l.end(); i++ ) 00178 { 00179 if( i!=l.begin() ) 00180 s << " "; 00181 s << *i; 00182 } 00183 s << ">"; 00184 return( s ); 00185 } 00186 00187 template<class Value> std::ostream& operator<<( std::ostream& s, const std::deque<Value>& l ) 00188 { 00189 s << "<"; 00190 for( typename std::deque<Value>::const_iterator i=l.begin(); i!=l.end(); i++ ) 00191 { 00192 if( i!=l.begin() ) 00193 s << " "; 00194 s << *i; 00195 } 00196 s << ">"; 00197 return( s ); 00198 } 00199 00200 template<class F, class S> std::ostream& operator<<( std::ostream& s, const std::pair<F,S>& p ) 00201 { 00202 s << "[" << p.first << ":" << p.second << "]"; 00203 return( s ); 00204 } 00205 00206 template<class Key, class Value> std::ostream& operator<<( std::ostream& s, const std::map<Key,Value>& m ) 00207 { 00208 s << "<"; 00209 for( typename std::map<Key,Value>::const_iterator i=m.begin(); i!=m.end(); i++ ) 00210 { 00211 if( i!=m.begin() ) 00212 s << " "; 00213 s << i->first << ":" << i->second; 00214 } 00215 s << ">"; 00216 return( s ); 00217 } 00218 00219 00220 template <typename Type> 00221 void logDiff(std::ostream& log, const char* text, const Type& lhs, const Type& rhs) 00222 { 00223 static_assert(!std::is_enum<Type>::value, "is enum"); 00224 00225 if (lhs != rhs) 00226 log << " " << text << ":" << lhs << "-->" << rhs; 00227 } 00228 00229 template <typename Type> 00230 void logDiffHex(std::ostream& log, const char* text, const Type& lhs, const Type& rhs) 00231 { 00232 static_assert(std::is_integral<Type>::value, "not integral"); 00233 00234 if (lhs != rhs) 00235 log << " " << text << ":" << std::hex << lhs << "-->" << rhs << std::dec; 00236 } 00237 00238 template <typename Type> 00239 void logDiffEnum(std::ostream& log, const char* text, const Type& lhs, const Type& rhs) 00240 { 00241 static_assert(std::is_enum<Type>::value, "not enum"); 00242 00243 if (lhs != rhs) 00244 log << " " << text << ":" << toString(lhs) << "-->" << toString(rhs); 00245 } 00246 00247 inline 00248 void logDiff(std::ostream& log, const char* text, bool lhs, bool rhs) 00249 { 00250 if (lhs != rhs) 00251 { 00252 if (rhs) 00253 log << " -->" << text; 00254 else 00255 log << " " << text << "-->"; 00256 } 00257 } 00258 00259 00260 template<class Type> 00261 bool 00262 read_sysfs_property(const string& path, Type& value, bool log_error = true) 00263 { 00264 std::ifstream file(path.c_str()); 00265 classic(file); 00266 file >> value; 00267 file.close(); 00268 00269 if (file.fail()) 00270 { 00271 if (log_error) 00272 y2err("reading " << path << " failed"); 00273 return false; 00274 } 00275 00276 return true; 00277 } 00278 00279 00280 template<class Type> 00281 struct deref_less : public std::binary_function<const Type*, const Type*, bool> 00282 { 00283 bool operator()(const Type* x, const Type* y) const { return *x < *y; } 00284 }; 00285 00286 00287 template<class Type> 00288 struct deref_equal_to : public std::binary_function<const Type*, const Type*, bool> 00289 { 00290 bool operator()(const Type* x, const Type* y) const { return *x == *y; } 00291 }; 00292 00293 00294 template <class Type> 00295 void pointerIntoSortedList(list<Type*>& l, Type* e) 00296 { 00297 l.insert(lower_bound(l.begin(), l.end(), e, deref_less<Type>()), e); 00298 } 00299 00300 00301 template <class Type> 00302 void clearPointerList(list<Type*>& l) 00303 { 00304 for (typename list<Type*>::iterator i = l.begin(); i != l.end(); ++i) 00305 delete *i; 00306 l.clear(); 00307 } 00308 00309 00310 template <typename ListType, typename Type> 00311 bool contains(const ListType& l, const Type& value) 00312 { 00313 return find(l.begin(), l.end(), value) != l.end(); 00314 } 00315 00316 00317 template <typename ListType, typename Predicate> 00318 bool contains_if(const ListType& l, Predicate pred) 00319 { 00320 return find_if(l.begin(), l.end(), pred) != l.end(); 00321 } 00322 00323 00324 template<typename Map, typename Key, typename Value> 00325 typename Map::iterator mapInsertOrReplace(Map& m, const Key& k, const Value& v) 00326 { 00327 typename Map::iterator pos = m.lower_bound(k); 00328 if (pos != m.end() && !typename Map::key_compare()(k, pos->first)) 00329 pos->second = v; 00330 else 00331 pos = m.insert(pos, typename Map::value_type(k, v)); 00332 return pos; 00333 } 00334 00335 template<typename List, typename Value> 00336 typename List::const_iterator addIfNotThere(List& l, const Value& v) 00337 { 00338 typename List::const_iterator pos = find( l.begin(), l.end(), v ); 00339 if (pos == l.end() ) 00340 pos = l.insert(l.end(), v); 00341 return pos; 00342 } 00343 00344 00345 template <class InputIterator1, class InputIterator2> 00346 bool equalContent(InputIterator1 first1, InputIterator1 last1, 00347 InputIterator2 first2, InputIterator2 last2) 00348 { 00349 while (first1 != last1 && first2 != last2) 00350 { 00351 if (!first1->equalContent(*first2)) 00352 return false; 00353 ++first1; 00354 ++first2; 00355 } 00356 return first1 == last1 && first2 == last2; 00357 } 00358 00359 00360 template <class InputIterator1, class InputIterator2> 00361 void logVolumesDifference(std::ostream& log, InputIterator1 first1, InputIterator1 last1, 00362 InputIterator2 first2, InputIterator2 last2) 00363 { 00364 for (InputIterator1 i = first1; i != last1; ++i) 00365 { 00366 InputIterator2 j = first2; 00367 while (j != last2 && (i->device() != j->device() || i->created() != j->created())) 00368 ++j; 00369 if (j != last2) 00370 { 00371 if (!i->equalContent(*j)) 00372 { 00373 i->logDifference(log, *j); 00374 log << std::endl; 00375 } 00376 } 00377 else 00378 { 00379 log << " -->" << *i << std::endl; 00380 } 00381 } 00382 00383 for (InputIterator2 i = first2; i != last2; ++i) 00384 { 00385 InputIterator1 j = first1; 00386 while (j != last1 && (i->device() != j->device() || i->created() != j->created())) 00387 ++j; 00388 if (j == last1) 00389 { 00390 log << " <--" << *i << std::endl; 00391 } 00392 } 00393 } 00394 00395 00396 template <class T, unsigned int sz> 00397 inline unsigned int lengthof (T (&)[sz]) { return sz; } 00398 00399 template <class Type> 00400 void printtype(Type type) 00401 { 00402 std::cout << __PRETTY_FUNCTION__ << std::endl; 00403 } 00404 00405 } 00406 00407 #endif
1.7.3