Disk ARchive  2.5.2
Full featured and portable backup and archiving tool
pile.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines