| Disk ARchive 2.5.10 Full featured and portable backup and archiving tool

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

escape.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
37
38
39 #ifndef ESCAPE_HPP
40 #define ESCAPE_HPP
41
42 #include "../my_config.h"
43
44 extern "C"
45 {
46 #if HAVE_LIMITS_H
47 #include <limits.h>
48 #endif
49 }
50
51 #include <set>
52
53 #include "generic_file.hpp"
54
55 #define ESCAPE_FIXED_SEQUENCE_NORMAL 0xAD
56 #define ESCAPE_FIXED_SEQUENCE_SPARSE_FILE 0xAE
57
58 #define MAX_BUFFER_SIZE 102400
59 #ifdef SSIZE_MAX
60 #if SSIZE_MAX < MAX_BUFFER_SIZE
61 #undef MAX_BUFFER_SIZE
62 #define MAX_BUFFER_SIZE SSIZE_MAX
63 #endif
64 #endif
65
66 namespace libdar
67 {
68
71
72 class escape : public generic_file
73 {
74 public:
75 enum sequence_type
76 {
77 seqt_undefined, //< not enough data to define the type of the escape sequence
78 seqt_not_a_sequence, //< to escape data corresponding to an escape sequence's fixed byte sequence
79 seqt_file, //< placed before inode information, eventually followed by file data
80 seqt_ea, //< placed before EA data
81 seqt_catalogue, //< placed before the archive's internal catalogue
82 seqt_data_name, //< placed before the archive data_name (at the beginning of the archive)
83 seqt_file_crc, //< placed before the CRC of file's data
84 seqt_ea_crc, //< placed before the CRC of file's EA
85 seqt_changed, //< placed before new copy of file's data if file's data changed while reading it for backup
86 seqt_dirty, //< placed after data CRC if file is dirty
87 seqt_failed_backup, //< placed after inode information if the file could not be openned at backup time
88 seqt_fsa, //< placed before FSA data
89 seqt_fsa_crc //< place before the CRC of file's FSA
90 };
91
92 // the archive layout of marks is for each entry:
93 // #seqt_file# <inode> [<file data> [#seqt_changed# <new copy of data> [...] ] #seqt_file_crc# <CRC>[#seqt_dirty#]] [#seqt_ea# <EA> #seqt_ea_crc# <CRC>]
94 // this previous sequence that we will call <SEQ> is repeated for each file, then on the overall archive we have :
95 // #seqt_data_name# <data_name> <SEQ> ... <SEQ> #seqt_catalogue# <catalogue> <terminator>
96
97 // the provided "below" object must exist during the whole live of the escape object,
98 // the escape object does not own this "below" object
99 // it must be destroyed by the caller/creator of the escape object.
100
101
102 // constructors & destructors
103
104 escape(generic_file *below, //< "Below" is the generic file that holds the escaped data
105 const std::set<sequence_type> & x_unjumpable); //< a set of marks that can never been jumped over when skipping for the next mark of a any given type.
106 escape(const escape & ref) : generic_file(ref) { copy_from(ref); };
107 const escape & operator = (const escape & ref);
108 ~escape();
109
110 // escape specific routines
111
112 void add_mark_at_current_position(sequence_type t);
113
115
120 bool skip_to_next_mark(sequence_type t, bool jump);
121 bool next_to_read_is_mark(sequence_type t);
122 bool next_to_read_is_which_mark(sequence_type & t);
123
124 void add_unjumpable_mark(sequence_type t) { if(is_terminated()) throw SRC_BUG; unjumpable.insert(t); };
125 void remove_unjumpable_mark(sequence_type t);
126 bool is_unjumpable_mark(sequence_type t) const { return unjumpable.find(t) != unjumpable.end(); };
127 void clear_all_unjumpable_marks() { unjumpable.clear(); };
128
129
130 // generic_file inherited routines
131 // NOTA: Nothing is done to prevent skip* operation to put the read cursor in the middle of an escape sequence and
132 // thus incorrectly consider it as normal data. Such event should only occure upon archive corruption and will be detected
133 // by checksum mechanisms.
134
135 bool skippable(skippability direction, const infinint & amount);
136 bool skip(const infinint & pos);
137 bool skip_to_eof();
138 bool skip_relative(S_I x);
139 infinint get_position() const;
140
141 protected:
142 void inherited_read_ahead(const infinint & amount);
143 U_I inherited_read(char *a, U_I size);
144 void inherited_write(const char *a, U_I size);
145 void inherited_sync_write() { flush_write(); };
146 void inherited_flush_read() { flush_write(); clean_read(); };
147 void inherited_terminate() { flush_or_clean(); };
148
149 void change_fixed_escape_sequence(unsigned char value) { fixed_sequence[0] = value; };
150 bool has_escaped_data_since_last_skip() const { return escaped_data_count_since_last_skip > 0; };
151
152 private:
153
154 //-- constants
155
157 static const U_I ESCAPE_SEQUENCE_LENGTH = 6;
158 static const U_I WRITE_BUFFER_SIZE = 2*ESCAPE_SEQUENCE_LENGTH;
159 static const U_I READ_BUFFER_SIZE = MAX_BUFFER_SIZE;
160 static const infinint READ_BUFFER_SIZE_INFININT;
161
163
169 static const unsigned char usual_fixed_sequence[ESCAPE_SEQUENCE_LENGTH];
170
171 //-- variables
172
173 generic_file *x_below; //< the generic_file in which we read/write escaped data from/to the object is not owned by "this"
174 U_I write_buffer_size; //< amount of data in write transit not yet written to "below" (may have to be escaped)
175 char write_buffer[WRITE_BUFFER_SIZE]; //< data in write transit, all data is unescaped, up to the first real mark, after it, data is raw (may be escaped)
176 //< the first real mark is pointed to by escape_seq_offset_in_buffer
177 U_I read_buffer_size; //< amount of data in transit, read from below, but possibly not yet unescaped and returned to the upper layer
178 U_I already_read; //< data in buffer that has already been returned to the upper layer
179 bool read_eof; //< whether we reached a escape sequence while reading data
180 U_I escape_seq_offset_in_buffer; //< location of the first escape sequence which is not a data sequence
181 char read_buffer[READ_BUFFER_SIZE]; //< data in read transit
182 std::set<sequence_type> unjumpable; //< list of mark that cannot be jumped over when searching for the next mark
183 unsigned char fixed_sequence[ESCAPE_SEQUENCE_LENGTH]; //< the preambule of an escape sequence to use/search for
184 infinint escaped_data_count_since_last_skip;
185 infinint below_position; //< remember the position of object pointed to by x_below
186
187 //-- routines
188
189 void set_fixed_sequence_for(sequence_type t) { fixed_sequence[ESCAPE_SEQUENCE_LENGTH - 1] = type2char(t); };
190 void check_below() const { if(x_below == nullptr) throw SRC_BUG; };
191 void clean_read(); //< drops all in-transit data
192 void flush_write(); //< write down to "below" all in-transit data
193 void flush_or_clean()
194 {
195 switch(get_mode())
196 {
197 case gf_read_only:
198 clean_read();
199 break;
200 case gf_write_only:
201 case gf_read_write:
202 flush_write();
203 break;
204 default:
205 throw SRC_BUG;
206 }
207 };
208 void copy_from(const escape & ref);
209 bool mini_read_buffer(); //< returns true if it could end having at least ESCAPE_SEQUENCE_LENGTH bytes in read_buffer, false else (EOF reached).
210
211 //-- static routine(s)
212
213 // some convertion routines
214 static char type2char(sequence_type x);
215 static sequence_type char2type(char x);
216
218
220
223 static U_I trouve_amorce(const char *a, U_I size, const unsigned char escape_sequence[ESCAPE_SEQUENCE_LENGTH]);
224
226
233 static U_I remove_data_marks_and_stop_at_first_real_mark(char *a, U_I size, U_I & delta, const unsigned char escape_sequence[ESCAPE_SEQUENCE_LENGTH]);
234 };
235
237
238 } // end of namespace
239
240 #endif
libdar::gf_write_only
write only access
Definition: generic_file.hpp:80
generic_file.hpp
class generic_file is defined here as well as class fichierthe generic_file interface is widely used ...
libdar::generic_file::is_terminated
bool is_terminated() const
Definition: generic_file.hpp:316
libdar::generic_file::generic_file
generic_file(gf_mode m)
main constructor
Definition: generic_file.hpp:104
libdar::generic_file::get_mode
gf_mode get_mode() const
retreive the openning mode for this object
Definition: generic_file.hpp:120
libdar::gf_read_write
read and write access
Definition: generic_file.hpp:81
libdar::gf_read_only
read only access
Definition: generic_file.hpp:79
libdar
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47