Disk ARchive 2.4.2
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 // $Id: pile.hpp,v 1.14 2011/04/17 13:12:29 edrusb Rel $
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, 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines