Disk ARchive  2.4.15
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
storage.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 
25 
26 #include "../my_config.h"
27 #include "erreurs.hpp"
28 #include "integers.hpp"
29 #include "special_alloc.hpp"
30 
31 #ifdef LIBDAR_MODE
32 #include "infinint.hpp"
33 #endif
34 
35  // it is necessary to not protect the previous inclusion inside
36  // the STORAGE_HPP protection to avoid cyclic dependancies.
37 
38 #ifndef STORAGE_HPP
39 #define STORAGE_HPP
40 
41 #ifndef LIBDAR_MODE
42 namespace libdar
43 {
44  class infinint;
45 }
46 #endif
47 
48 namespace libdar
49 {
50  class generic_file;
51 
53 
56 
57  class storage
58  {
59  private:
60  struct cellule
61  {
62  cellule() : next(NULL), prev(NULL), data(NULL), size(0) {};
63  struct cellule *next, *prev;
64  unsigned char *data;
65  U_32 size;
66  };
67 
68  public:
69  storage(U_32 size)
70  { make_alloc(size, first, last); };
71  storage(const infinint & size);
72  storage(const storage & ref)
73  { copy_from(ref); };
74  storage(generic_file & f, const infinint &size);
75  ~storage()
76  { detruit(first); };
77 
78  const storage & operator = (const storage & val)
79  { detruit(first); copy_from(val); return *this; };
80 
81  bool operator < (const storage & ref) const
82  { return difference(ref) < 0; }; // true if arg uses more space than this
83  bool operator == (const storage & ref) const
84  { return difference(ref) == 0; }; //true if arg have same space than this
85  bool operator > (const storage & ref) const
86  { return difference(ref) > 0; };
87  bool operator <= (const storage & ref) const
88  { return difference(ref) <= 0; };
89  bool operator >= (const storage & ref) const
90  { return difference(ref) >= 0; };
91  bool operator != (const storage & ref) const
92  { return difference(ref) != 0; };
93  unsigned char & operator [](infinint position);
94  unsigned char operator [](const infinint & position) const;
95  infinint size() const;
96  void clear(unsigned char val = 0);
97  void dump(generic_file & f) const;
98 
99  class iterator
100  {
101  public :
102  iterator() : ref(NULL), cell(NULL), offset(0) {};
103  // default constructor by reference is OK
104  // default destructor is OK
105  // default operator = is OK
106 
107  iterator operator ++ (S_I x)
108  { iterator ret = *this; skip_plus_one(); return ret; };
109  iterator operator -- (S_I x)
110  { iterator ret = *this; skip_less_one(); return ret; };
111  iterator & operator ++ ()
112  { skip_plus_one(); return *this; };
113  iterator & operator -- ()
114  { skip_less_one(); return *this; };
115  iterator operator + (U_32 s) const
116  { iterator ret = *this; ret += s; return ret; };
117  iterator operator - (U_32 s) const
118  { iterator ret = *this; ret -= s; return ret; };
119  iterator & operator += (U_32 s);
120  iterator & operator -= (U_32 s);
121  unsigned char &operator *() const;
122 
123  void skip_to(const storage & st, infinint val); // absolute position in st
124  infinint get_position() const;
125 
126  bool operator == (const iterator & cmp) const
127  { return ref == cmp.ref && cell == cmp.cell && offset == cmp.offset; };
128  bool operator != (const iterator & cmp) const
129  { return ! (*this == cmp); };
130 
131  private:
132  static const U_32 OFF_BEGIN = 1;
133  static const U_32 OFF_END = 2;
134 
135  const storage *ref;
136  struct cellule *cell;
137  U_32 offset;
138 
139  void relative_skip_to(S_32 val);
140  bool points_on_data() const
141  { return ref != NULL && cell != NULL && offset < cell->size; };
142 
143  inline void skip_plus_one();
144  inline void skip_less_one();
145 
146  friend class storage;
147  };
148 
149  // public storage methode using iterator
150 
151  iterator begin() const
152  { iterator ret; ret.cell = first; if(ret.cell != NULL) ret.offset = 0; else ret.offset = iterator::OFF_END; ret.ref = this; return ret; };
153  iterator end() const
154  { iterator ret; ret.cell = NULL; ret.offset = iterator::OFF_END; ret.ref = this; return ret; };
155 
156  // WARNING for the two following methods :
157  // there is no "reverse_iterator" type, unlike the standart lib,
158  // thus when going from rbegin() to rend(), you must use the -- operator
159  // unlike the stdlib, that uses the ++ operator. this is the only difference in use with stdlib.
160  iterator rbegin() const
161  { iterator ret; ret.cell = last; ret.offset = last != NULL ? last->size-1 : 0; ret.ref = this; return ret; };
162  iterator rend() const
163  { iterator ret; ret.cell = NULL, ret.offset = iterator::OFF_BEGIN; ret.ref = this; return ret; };
164 
166 
170  U_I write(iterator & it, unsigned char *a, U_I size);
171  U_I read(iterator & it, unsigned char *a, U_I size) const;
172  bool write(iterator & it, unsigned char a)
173  { return write(it, &a, 1) == 1; };
174  bool read(iterator & it, unsigned char &a) const
175  { return read(it, &a, 1) == 1; };
176 
177  // after one of these 3 calls, the iterator given in argument are undefined (they may point nowhere)
178  void insert_null_bytes_at_iterator(iterator it, U_I size);
179  void insert_const_bytes_at_iterator(iterator it, unsigned char a, U_I size);
180  void insert_bytes_at_iterator(iterator it, unsigned char *a, U_I size);
181  void insert_as_much_as_necessary_const_byte_to_be_as_wider_as(const storage & ref, const iterator & it, unsigned char value);
182  void remove_bytes_at_iterator(iterator it, U_I number);
183  void remove_bytes_at_iterator(iterator it, infinint number);
184 
185 #ifdef LIBDAR_SPECIAL_ALLOC
186  USE_SPECIAL_ALLOC(storage);
187 #endif
188  private:
189  struct cellule *first, *last;
190 
191  void copy_from(const storage & ref);
192  S_32 difference(const storage & ref) const;
193  void reduce(); // heuristic that tries to free some memory;
194  void insert_bytes_at_iterator_cmn(iterator it, bool constant, unsigned char *a, U_I size);
195  void fusionne(struct cellule *a_first, struct cellule *a_last, struct cellule *b_first, struct cellule *b_last,
196  struct cellule *&res_first, struct cellule * & res_last);
197 
199  // STATIC statments :
200  //
201 
202  static void detruit(struct cellule *c);
203  static void make_alloc(U_32 size, struct cellule * & begin, struct cellule * & end);
204  static void make_alloc(infinint size, cellule * & begin, struct cellule * & end);
205 
206  friend class storage::iterator;
207  };
208 
209  inline void storage::iterator::skip_plus_one()
210  {
211  if(cell != NULL)
212  if(++offset >= cell->size)
213  {
214  cell = cell->next;
215  if(cell != NULL)
216  offset = 0;
217  else
218  offset = OFF_END;
219  }
220  }
221 
222  inline void storage::iterator::skip_less_one()
223  {
224  if(cell != NULL)
225  {
226  if(offset > 0)
227  --offset;
228  else
229  {
230  cell = cell->prev;
231  if(cell != NULL)
232  offset = cell->size - 1;
233  else
234  offset = OFF_BEGIN;
235  }
236  }
237  }
238 
239 } // end of namespace
240 
241 #endif
are defined here basic integer types that tend to be portable
the deleted file entry
Definition: catalogue.hpp:906
std::vector< T > operator+=(std::vector< T > &a, const std::vector< T > &b)
template function to add two vectors
Definition: tools.hpp:344
U_I write(iterator &it, unsigned char *a, U_I size)
write data to the storage at the location pointed to by it
re-definition of new and delete class operatorthis is a set of macro that makes the new and delete op...
arbitrary large storage structure
Definition: storage.hpp:57
contains all the excetion class thrown by libdar
switch module to limitint (32 ou 64 bits integers) or infinint
this is the interface class from which all other data transfer classes inherit
the arbitrary large positive integer class
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:43