Disk ARchive
2.4.5
|
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 // $Id$ 00022 // 00023 /*********************************************************************/ 00024 00028 00029 00030 #ifndef PILE_HPP 00031 #define PILE_HPP 00032 00033 #include "../my_config.h" 00034 00035 #include <vector> 00036 #include <list> 00037 #include "generic_file.hpp" 00038 00039 namespace libdar 00040 { 00041 00044 00045 class pile : public generic_file 00046 { 00047 public: 00052 00053 pile() : generic_file(gf_read_only) { stack.clear(); }; 00054 pile(const pile & ref) : generic_file(ref) { copy_from(ref); }; 00055 const pile & operator = (const pile & ref) { detruit(); copy_from(ref); return *this; }; 00056 ~pile() { detruit(); }; 00057 00067 void push(generic_file *f, const std::string & label = ""); 00068 00073 generic_file *pop(); 00074 00078 template <class T> bool pop_and_close_if_type_is(T *ptr); 00079 00081 generic_file *top() { if(stack.empty()) return NULL; else return stack.back().ptr; }; 00082 00084 generic_file *bottom() { if(stack.empty()) return NULL; else return stack[0].ptr; }; 00085 00087 U_I size() const { return stack.size(); }; 00088 00090 bool is_empty() const { return stack.empty(); }; 00091 00093 void clear() { detruit(); }; 00094 00098 template<class T> void find_first_from_top(T * & ref); 00099 00101 template<class T> void find_first_from_bottom(T * & ref); 00102 00103 00105 generic_file *get_below(const generic_file *ref); 00106 00108 generic_file *get_above(const generic_file *ref); 00109 00110 00115 generic_file *get_by_label(const std::string & label); 00116 00117 00118 00123 void clear_label(const std::string & label); 00124 00125 00131 void add_label(const std::string & label); 00132 00133 00134 00135 // inherited methods from generic_file 00136 // they all apply to the top generic_file object, they fail by Erange() exception if the stack is empty 00137 00138 bool skip(const infinint & pos); 00139 bool skip_to_eof(); 00140 bool skip_relative(S_I x); 00141 infinint get_position(); 00142 void copy_to(generic_file & ref); 00143 void copy_to(generic_file & ref, const infinint & crc_size, crc * & value); 00144 00145 protected: 00146 U_I inherited_read(char *a, U_I size); 00147 void inherited_write(const char *a, U_I size); 00148 void inherited_sync_write(); 00149 void inherited_terminate(); 00150 00151 private: 00152 struct face 00153 { 00154 generic_file * ptr; 00155 std::list<std::string> labels; 00156 }; 00157 00158 std::vector<face> stack; 00159 00160 void copy_from(const pile & ref) 00161 { 00162 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). 00163 }; 00164 void detruit(); 00165 std::vector<face>::iterator look_for_label(const std::string & label); 00166 }; 00167 00168 00169 template <class T> bool pile::pop_and_close_if_type_is(T *ptr) 00170 { 00171 generic_file *top = NULL; 00172 00173 if(!stack.empty()) 00174 { 00175 top = stack.back().ptr; 00176 ptr = dynamic_cast<T *>(top); 00177 if(ptr != NULL) 00178 { 00179 stack.pop_back(); 00180 delete top; 00181 return true; 00182 } 00183 else 00184 return false; 00185 } 00186 else 00187 return false; 00188 } 00189 00190 template <class T> void pile::find_first_from_top(T * & ref) 00191 { 00192 ref = NULL; 00193 for(std::vector<face>::reverse_iterator it = stack.rbegin(); it != stack.rend() && ref == NULL; ++it) 00194 ref = dynamic_cast<T *>(it->ptr); 00195 } 00196 00197 00198 template <class T> void pile::find_first_from_bottom(T * & ref) 00199 { 00200 ref = NULL; 00201 for(std::vector<face>::iterator it = stack.begin(); it != stack.end() && ref == NULL; ++it) 00202 ref = dynamic_cast<T *>(it->ptr); 00203 } 00204 00206 00207 } // end of namespace 00208 00209 #endif