00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027
00028 #ifndef STORAGE_HPP
00029 #define STORAGE_HPP
00030
00031 #include "../my_config.h"
00032 #include "erreurs.hpp"
00033 #include "integers.hpp"
00034
00035 #ifndef LIBDAR_MODE
00036 namespace libdar
00037 {
00038 class infinint;
00039 }
00040 #else
00041 #include "infinint.hpp"
00042 #endif
00043
00044
00045 namespace libdar
00046 {
00047 class generic_file;
00048
00050
00053
00054 class storage
00055 {
00056 private:
00057 struct cellule
00058 {
00059 cellule() : next(NULL), prev(NULL), data(NULL), size(0) {};
00060 struct cellule *next, *prev;
00061 unsigned char *data;
00062 U_32 size;
00063 };
00064
00065 public:
00066 storage(U_32 size)
00067 { E_BEGIN; make_alloc(size, first, last); E_END("storage::storage","U_32"); };
00068 storage(const infinint & size);
00069 storage(const storage & ref)
00070 { E_BEGIN; copy_from(ref); E_END("storage::storage", "storage &"); };
00071 storage(generic_file & f, const infinint &size);
00072 ~storage()
00073 { E_BEGIN; detruit(first); E_END("storage::~storage", ""); };
00074
00075 storage & operator = (const storage & val)
00076 { E_BEGIN; detruit(first); copy_from(val); return *this; E_END("storage::operator=",""); };
00077
00078 bool operator < (const storage & ref) const
00079 { E_BEGIN; return difference(ref) < 0; E_END("storage::operator <",""); };
00080 bool operator == (const storage & ref) const
00081 { E_BEGIN; return difference(ref) == 0; E_END("storage::operator ==",""); };
00082 bool operator > (const storage & ref) const
00083 { E_BEGIN; return difference(ref) > 0; E_END("storage::operator >", ""); };
00084 bool operator <= (const storage & ref) const
00085 { E_BEGIN; return difference(ref) <= 0; E_END("storage::operator <=", ""); };
00086 bool operator >= (const storage & ref) const
00087 { E_BEGIN; return difference(ref) >= 0; E_END("storage::operator >=", ""); };
00088 bool operator != (const storage & ref) const
00089 { E_BEGIN; return difference(ref) != 0; E_END("storage::operator !=", ""); };
00090 unsigned char & operator [](infinint position);
00091 unsigned char operator [](const infinint & position) const;
00092 infinint size() const;
00093 void clear(unsigned char val = 0);
00094 void dump(generic_file & f) const;
00095
00096 class iterator
00097 {
00098 public :
00099 iterator() : ref(NULL), cell(NULL), offset(0) {};
00100
00101
00102
00103
00104 iterator operator ++ (S_I x)
00105 { E_BEGIN; iterator ret = *this; skip_plus_one(); return ret; E_END("storage::iterator::operator++", "(S_I)"); };
00106 iterator operator -- (S_I x)
00107 { E_BEGIN; iterator ret = *this; skip_less_one(); return ret; E_END("storage::iterator::operator--", "(S_I)");};
00108 iterator & operator ++ ()
00109 { E_BEGIN; skip_plus_one(); return *this; E_END("storage::iterator::operator++", "()"); };
00110 iterator & operator -- ()
00111 { E_BEGIN; skip_less_one(); return *this; E_END("storage::iterator::operator--", "()"); };
00112 iterator operator + (U_32 s) const
00113 { E_BEGIN; iterator ret = *this; ret += s; return ret; E_END("storage::iterator::operator +", ""); };
00114 iterator operator - (U_32 s) const
00115 { E_BEGIN; iterator ret = *this; ret -= s; return ret; E_END("storage::iterator::operator -", ""); };
00116 iterator & operator += (U_32 s);
00117 iterator & operator -= (U_32 s);
00118 unsigned char &operator *() const;
00119
00120 void skip_to(const storage & st, infinint val);
00121 infinint get_position() const;
00122
00123 bool operator == (const iterator & cmp) const
00124 { E_BEGIN; return ref == cmp.ref && cell == cmp.cell && offset == cmp.offset; E_END("storage::iterator::operator ==", ""); };
00125 bool operator != (const iterator & cmp) const
00126 { E_BEGIN; return ! (*this == cmp); E_END("storage::iterator::operator !=", ""); };
00127
00128 private:
00129 static const U_32 OFF_BEGIN = 1;
00130 static const U_32 OFF_END = 2;
00131
00132 const storage *ref;
00133 struct cellule *cell;
00134 U_32 offset;
00135
00136 void relative_skip_to(S_32 val);
00137 bool points_on_data() const
00138 { E_BEGIN; return ref != NULL && cell != NULL && offset < cell->size; E_END("storage::iterator::point_on_data", "");};
00139
00140 inline void skip_plus_one();
00141 inline void skip_less_one();
00142
00143 friend class storage;
00144 };
00145
00146
00147
00148 iterator begin() const
00149 { E_BEGIN; iterator ret; ret.cell = first; ret.offset = 0; ret.ref = this; return ret; E_END("storage::begin", ""); };
00150 iterator end() const
00151 { E_BEGIN; iterator ret; ret.cell = NULL; ret.offset = iterator::OFF_END; ret.ref = this; return ret; E_END("storage::end", ""); };
00152
00153
00154
00155
00156
00157 iterator rbegin() const
00158 { E_BEGIN; iterator ret; ret.cell = last; ret.offset = last != NULL ? last->size-1 : 0; ret.ref = this; return ret; E_END("storage::rbegin", ""); };
00159 iterator rend() const
00160 { E_BEGIN; iterator ret; ret.cell = NULL, ret.offset = iterator::OFF_BEGIN; ret.ref = this; return ret; E_END("storage::rend", ""); };
00161
00163
00167 U_I write(iterator & it, unsigned char *a, U_I size);
00168 U_I read(iterator & it, unsigned char *a, U_I size) const;
00169 bool write(iterator & it, unsigned char a)
00170 { E_BEGIN; return write(it, &a, 1) == 1; E_END("storage::write", "unsigned char"); };
00171 bool read(iterator & it, unsigned char &a) const
00172 { E_BEGIN; return read(it, &a, 1) == 1; E_END("storage::read", "unsigned char"); };
00173
00174
00175 void insert_null_bytes_at_iterator(iterator it, U_I size);
00176 void insert_const_bytes_at_iterator(iterator it, unsigned char a, U_I size);
00177 void insert_bytes_at_iterator(iterator it, unsigned char *a, U_I size);
00178 void insert_as_much_as_necessary_const_byte_to_be_as_wider_as(const storage & ref, const iterator & it, unsigned char value);
00179 void remove_bytes_at_iterator(iterator it, U_I number);
00180 void remove_bytes_at_iterator(iterator it, infinint number);
00181
00182
00183 private:
00184 struct cellule *first, *last;
00185
00186 void copy_from(const storage & ref);
00187 S_32 difference(const storage & ref) const;
00188 void reduce();
00189 void insert_bytes_at_iterator_cmn(iterator it, bool constant, unsigned char *a, U_I size);
00190 void fusionne(struct cellule *a_first, struct cellule *a_last, struct cellule *b_first, struct cellule *b_last,
00191 struct cellule *&res_first, struct cellule * & res_last);
00192
00194
00195
00196
00197 static void detruit(struct cellule *c);
00198 static void make_alloc(U_32 size, struct cellule * & begin, struct cellule * & end);
00199 static void make_alloc(infinint size, cellule * & begin, struct cellule * & end);
00200
00201 friend class storage::iterator;
00202 };
00203
00204 inline void storage::iterator::skip_plus_one()
00205 {
00206 E_BEGIN;
00207 if(cell != NULL)
00208 if(++offset >= cell->size)
00209 {
00210 cell = cell->next;
00211 if(cell != NULL)
00212 offset = 0;
00213 else
00214 offset = OFF_END;
00215 }
00216 E_END("storage::iterator::slik_plus_one", "");
00217 }
00218
00219 inline void storage::iterator::skip_less_one()
00220 {
00221 E_BEGIN;
00222 if(cell != NULL)
00223 {
00224 if(offset > 0)
00225 --offset;
00226 else
00227 {
00228 cell = cell->prev;
00229 if(cell != NULL)
00230 offset = cell->size - 1;
00231 else
00232 offset = OFF_BEGIN;
00233 }
00234 }
00235 E_END("storage::iterator::slik_plus_one", "");
00236 }
00237
00238 }
00239
00240 #endif