![]() |
Disk ARchive
2.5.2
Full featured and portable backup and archiving tool
|
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 00065 void push(generic_file *f, const std::string & label = "", bool extend_mode = false); 00066 00071 generic_file *pop(); 00072 00076 template <class T> bool pop_and_close_if_type_is(T *ptr); 00077 00079 generic_file *top() { if(stack.empty()) return nullptr; else return stack.back().ptr; }; 00080 00082 generic_file *bottom() { if(stack.empty()) return nullptr; else return stack[0].ptr; }; 00083 00085 U_I size() const { return stack.size(); }; 00086 00088 bool is_empty() const { return stack.empty(); }; 00089 00091 void clear() { detruit(); }; 00092 00096 template<class T> void find_first_from_top(T * & ref); 00097 00099 template<class T> void find_first_from_bottom(T * & ref); 00100 00101 00103 generic_file *get_below(const generic_file *ref); 00104 00106 generic_file *get_above(const generic_file *ref); 00107 00108 00113 generic_file *get_by_label(const std::string & label); 00114 00115 00116 00121 void clear_label(const std::string & label); 00122 00123 00129 void add_label(const std::string & label); 00130 00131 00133 void sync_write_above(generic_file *ptr); 00134 00136 void flush_read_above(generic_file *ptr); 00137 00138 // inherited methods from generic_file 00139 // they all apply to the top generic_file object, they fail by Erange() exception if the stack is empty 00140 00141 bool skippable(skippability direction, const infinint & amount); 00142 bool skip(const infinint & pos); 00143 bool skip_to_eof(); 00144 bool skip_relative(S_I x); 00145 infinint get_position() const; 00146 00147 void copy_to(generic_file & ref); 00148 void copy_to(generic_file & ref, const infinint & crc_size, crc * & value); 00149 00150 protected: 00151 void inherited_read_ahead(const infinint & amount); 00152 U_I inherited_read(char *a, U_I size); 00153 void inherited_write(const char *a, U_I size); 00154 void inherited_sync_write(); 00155 void inherited_flush_read(); 00156 void inherited_terminate(); 00157 00158 private: 00159 struct face 00160 { 00161 generic_file * ptr; 00162 std::list<std::string> labels; 00163 }; // ok, had not much idea to find a name for that struct, "face" was the first idea found to be associated with "pile", which means stack 00164 // in French but also is the name of the face of a coin where its value is written. The opposite face of a coin is called "face" in French 00165 // because often a face is design there and the expression "tirer `a pile ou face" (meaning "to toss up") is very common. 00166 00167 std::vector<face> stack; 00168 00169 void copy_from(const pile & ref) 00170 { 00171 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). 00172 }; 00173 void detruit(); 00174 std::vector<face>::iterator look_for_label(const std::string & label); 00175 }; 00176 00177 00178 template <class T> bool pile::pop_and_close_if_type_is(T *ptr) 00179 { 00180 generic_file *top = nullptr; 00181 00182 if(!stack.empty()) 00183 { 00184 top = stack.back().ptr; 00185 ptr = dynamic_cast<T *>(top); 00186 if(ptr != nullptr) 00187 { 00188 stack.pop_back(); 00189 delete top; 00190 return true; 00191 } 00192 else 00193 return false; 00194 } 00195 else 00196 return false; 00197 } 00198 00199 template <class T> void pile::find_first_from_top(T * & ref) 00200 { 00201 ref = nullptr; 00202 for(std::vector<face>::reverse_iterator it = stack.rbegin(); it != stack.rend() && ref == nullptr; ++it) 00203 ref = dynamic_cast<T *>(it->ptr); 00204 } 00205 00206 00207 template <class T> void pile::find_first_from_bottom(T * & ref) 00208 { 00209 ref = nullptr; 00210 for(std::vector<face>::iterator it = stack.begin(); it != stack.end() && ref == nullptr; ++it) 00211 ref = dynamic_cast<T *>(it->ptr); 00212 } 00213 00215 00216 } // end of namespace 00217 00218 #endif