Disk ARchive  2.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
pile.hpp
Go to the documentation of this file.
1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 // $Id: pile.hpp,v 1.14 2011/04/17 13:12:29 edrusb Rel $
22 //
23 /*********************************************************************/
24 
28 
29 
30 #ifndef PILE_HPP
31 #define PILE_HPP
32 
33 #include "../my_config.h"
34 
35 #include <vector>
36 #include <list>
37 #include "generic_file.hpp"
38 
39 namespace libdar
40 {
41 
44 
45  class pile : public generic_file
46  {
47  public:
52 
53  pile() : generic_file(gf_read_only) { stack.clear(); };
54  pile(const pile & ref) : generic_file(ref) { copy_from(ref); };
55  const pile & operator = (const pile & ref) { detruit(); copy_from(ref); return *this; };
56  ~pile() { detruit(); };
57 
67  void push(generic_file *f, const std::string & label = "");
68 
73  generic_file *pop();
74 
78  template <class T> bool pop_and_close_if_type_is(T *ptr);
79 
81  generic_file *top() { if(stack.empty()) return NULL; else return stack.back().ptr; };
82 
84  generic_file *bottom() { if(stack.empty()) return NULL; else return stack[0].ptr; };
85 
87  U_I size() const { return stack.size(); };
88 
90  bool is_empty() const { return stack.empty(); };
91 
93  void clear() { detruit(); };
94 
98  template<class T> void find_first_from_top(T * & ref);
99 
101  template<class T> void find_first_from_bottom(T * & ref);
102 
103 
105  generic_file *get_below(const generic_file *ref);
106 
108  generic_file *get_above(const generic_file *ref);
109 
110 
115  generic_file *get_by_label(const std::string & label);
116 
117 
118 
123  void clear_label(const std::string & label);
124 
125 
131  void add_label(const std::string & label);
132 
133 
134 
135  // inherited methods from generic_file
136  // they all apply to the top generic_file object, they fail by Erange() exception if the stack is empty
137 
138  bool skip(const infinint & pos);
139  bool skip_to_eof();
140  bool skip_relative(S_I x);
141  infinint get_position();
142  void copy_to(generic_file & ref);
143  void copy_to(generic_file & ref, crc & value);
144 
145  protected:
146  U_I inherited_read(char *a, U_I size);
147  void inherited_write(const char *a, U_I size);
148  void inherited_sync_write();
149  void inherited_terminate();
150 
151  private:
152  struct face
153  {
154  generic_file * ptr;
155  std::list<std::string> labels;
156  };
157 
158  std::vector<face> stack;
159 
160  void copy_from(const pile & ref)
161  {
162  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).
163  };
164  void detruit();
165  std::vector<face>::iterator look_for_label(const std::string & label);
166  };
167 
168 
169  template <class T> bool pile::pop_and_close_if_type_is(T *ptr)
170  {
171  generic_file *top = NULL;
172 
173  if(!stack.empty())
174  {
175  top = stack.back().ptr;
176  ptr = dynamic_cast<T *>(top);
177  if(ptr != NULL)
178  {
179  stack.pop_back();
180  delete top;
181  return true;
182  }
183  else
184  return false;
185  }
186  else
187  return false;
188  }
189 
190  template <class T> void pile::find_first_from_top(T * & ref)
191  {
192  ref = NULL;
193  for(std::vector<face>::reverse_iterator it = stack.rbegin(); it != stack.rend() && ref == NULL; ++it)
194  ref = dynamic_cast<T *>(it->ptr);
195  }
196 
197 
198  template <class T> void pile::find_first_from_bottom(T * & ref)
199  {
200  ref = NULL;
201  for(std::vector<face>::iterator it = stack.begin(); it != stack.end() && ref == NULL; ++it)
202  ref = dynamic_cast<T *>(it->ptr);
203  }
204 
206 
207 } // end of namespace
208 
209 #endif