|
Disk ARchive
2.4.12
|
00001 /*********************************************************************/ 00002 // dar - disk archive - a backup/restoration program 00003 // Copyright (C) 2002-2052 Denis Corbin 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 // to contact the author : http://dar.linux.free.fr/email.html 00020 /*********************************************************************/ 00021 00025 00026 00027 #ifndef PILE_HPP 00028 #define PILE_HPP 00029 00030 #include "../my_config.h" 00031 00032 #include <vector> 00033 #include <list> 00034 #include "generic_file.hpp" 00035 00036 namespace libdar 00037 { 00038 00041 00042 class pile : public generic_file 00043 { 00044 public: 00049 00050 pile() : generic_file(gf_read_only) { stack.clear(); }; 00051 pile(const pile & ref) : generic_file(ref) { copy_from(ref); }; 00052 const pile & operator = (const pile & ref) { detruit(); copy_from(ref); return *this; }; 00053 ~pile() { detruit(); }; 00054 00064 void push(generic_file *f, const std::string & label = ""); 00065 00070 generic_file *pop(); 00071 00075 template <class T> bool pop_and_close_if_type_is(T *ptr); 00076 00078 generic_file *top() { if(stack.empty()) return NULL; else return stack.back().ptr; }; 00079 00081 generic_file *bottom() { if(stack.empty()) return NULL; else return stack[0].ptr; }; 00082 00084 U_I size() const { return stack.size(); }; 00085 00087 bool is_empty() const { return stack.empty(); }; 00088 00090 void clear() { detruit(); }; 00091 00095 template<class T> void find_first_from_top(T * & ref); 00096 00098 template<class T> void find_first_from_bottom(T * & ref); 00099 00100 00102 generic_file *get_below(const generic_file *ref); 00103 00105 generic_file *get_above(const generic_file *ref); 00106 00107 00112 generic_file *get_by_label(const std::string & label); 00113 00114 00115 00120 void clear_label(const std::string & label); 00121 00122 00128 void add_label(const std::string & label); 00129 00130 00131 00132 // inherited methods from generic_file 00133 // they all apply to the top generic_file object, they fail by Erange() exception if the stack is empty 00134 00135 bool skip(const infinint & pos); 00136 bool skip_to_eof(); 00137 bool skip_relative(S_I x); 00138 infinint get_position(); 00139 void copy_to(generic_file & ref); 00140 void copy_to(generic_file & ref, const infinint & crc_size, crc * & value); 00141 00142 protected: 00143 U_I inherited_read(char *a, U_I size); 00144 void inherited_write(const char *a, U_I size); 00145 void inherited_sync_write(); 00146 void inherited_terminate(); 00147 00148 private: 00149 struct face 00150 { 00151 generic_file * ptr; 00152 std::list<std::string> labels; 00153 }; 00154 00155 std::vector<face> stack; 00156 00157 void copy_from(const pile & ref) 00158 { 00159 throw SRC_BUG; // it is not possible to copy an object to its another of the exact same type when only a pure virtual pointer pointing on it is available, or when no virtual "clone'-like method is available from the root pure virtual class (generic_file here). 00160 }; 00161 void detruit(); 00162 std::vector<face>::iterator look_for_label(const std::string & label); 00163 }; 00164 00165 00166 template <class T> bool pile::pop_and_close_if_type_is(T *ptr) 00167 { 00168 generic_file *top = NULL; 00169 00170 if(!stack.empty()) 00171 { 00172 top = stack.back().ptr; 00173 ptr = dynamic_cast<T *>(top); 00174 if(ptr != NULL) 00175 { 00176 stack.pop_back(); 00177 delete top; 00178 return true; 00179 } 00180 else 00181 return false; 00182 } 00183 else 00184 return false; 00185 } 00186 00187 template <class T> void pile::find_first_from_top(T * & ref) 00188 { 00189 ref = NULL; 00190 for(std::vector<face>::reverse_iterator it = stack.rbegin(); it != stack.rend() && ref == NULL; ++it) 00191 ref = dynamic_cast<T *>(it->ptr); 00192 } 00193 00194 00195 template <class T> void pile::find_first_from_bottom(T * & ref) 00196 { 00197 ref = NULL; 00198 for(std::vector<face>::iterator it = stack.begin(); it != stack.end() && ref == NULL; ++it) 00199 ref = dynamic_cast<T *>(it->ptr); 00200 } 00201 00203 00204 } // end of namespace 00205 00206 #endif
1.7.6.1