Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00037
00038
00039 #ifndef ESCAPE_HPP
00040 #define ESCAPE_HPP
00041
00042 #include "../my_config.h"
00043
00044 extern "C"
00045 {
00046 #if HAVE_LIMITS_H
00047 #include <limits.h>
00048 #endif
00049 }
00050
00051 #include <set>
00052
00053 #include "generic_file.hpp"
00054
00055 #define ESCAPE_FIXED_SEQUENCE_NORMAL 0xAD
00056 #define ESCAPE_FIXED_SEQUENCE_SPARSE_FILE 0xAE
00057
00058 #define MAX_BUFFER_SIZE 204800
00059 #ifdef SSIZE_MAX
00060 #if SSIZE_MAX < MAX_BUFFER_SIZE
00061 #undef MAX_BUFFER_SIZE
00062 #define MAX_BUFFER_SIZE SSIZE_MAX
00063 #endif
00064 #endif
00065
00066 namespace libdar
00067 {
00068
00071
00072 class escape : public generic_file
00073 {
00074 public:
00075 enum sequence_type
00076 {
00077 seqt_undefined,
00078 seqt_not_a_sequence,
00079 seqt_file,
00080 seqt_ea,
00081 seqt_catalogue,
00082 seqt_data_name,
00083 seqt_file_crc,
00084 seqt_ea_crc,
00085 seqt_changed,
00086 seqt_dirty,
00087 seqt_failed_backup
00088 };
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 escape(generic_file *below,
00102 const std::set<sequence_type> & x_unjumpable);
00103 escape(const escape & ref) : generic_file(ref) { copy_from(ref); };
00104 const escape & operator = (const escape & ref);
00105 ~escape();
00106
00107
00108
00109 void add_mark_at_current_position(sequence_type t);
00110
00112
00117 bool skip_to_next_mark(sequence_type t, bool jump);
00118 bool next_to_read_is_mark(sequence_type t);
00119 bool next_to_read_is_which_mark(sequence_type & t);
00120
00121 void add_unjumpable_mark(sequence_type t) { if(is_terminated()) throw SRC_BUG; unjumpable.insert(t); };
00122 void remove_unjumpable_mark(sequence_type t);
00123 bool is_unjumpable_mark(sequence_type t) const { return unjumpable.find(t) != unjumpable.end(); };
00124 void clear_all_unjumpable_marks() { unjumpable.clear(); };
00125
00126
00127
00128
00129
00130
00131 bool skip(const infinint & pos);
00132 bool skip_to_eof();
00133 bool skip_relative(S_I x);
00134 infinint get_position();
00135
00136 generic_file *get_below() const { return x_below; };
00137
00138 protected:
00139 U_I inherited_read(char *a, U_I size);
00140 void inherited_write(const char *a, U_I size);
00141 void inherited_sync_write() { flush_write(); };
00142 void inherited_terminate() { flush_or_clean(); };
00143
00144 void change_fixed_escape_sequence(unsigned char value) { fixed_sequence[0] = value; };
00145 bool has_escaped_data_since_last_skip() const { return escaped_data_count_since_last_skip > 0; };
00146
00147 private:
00148
00149
00150
00152 static const U_I ESCAPE_SEQUENCE_LENGTH = 6;
00153 static const U_I WRITE_BUFFER_SIZE = 2*ESCAPE_SEQUENCE_LENGTH;
00154 static const U_I READ_BUFFER_SIZE = MAX_BUFFER_SIZE;
00155
00157
00163 static const unsigned char usual_fixed_sequence[ESCAPE_SEQUENCE_LENGTH];
00164
00165
00166
00167 generic_file *x_below;
00168 U_I write_buffer_size;
00169 char write_buffer[WRITE_BUFFER_SIZE];
00170
00171 U_I read_buffer_size;
00172 U_I already_read;
00173 bool read_eof;
00174 U_I escape_seq_offset_in_buffer;
00175 char read_buffer[READ_BUFFER_SIZE];
00176 std::set<sequence_type> unjumpable;
00177 unsigned char fixed_sequence[ESCAPE_SEQUENCE_LENGTH];
00178 infinint escaped_data_count_since_last_skip;
00179
00180
00181
00182 void set_fixed_sequence_for(sequence_type t) { fixed_sequence[ESCAPE_SEQUENCE_LENGTH - 1] = type2char(t); };
00183 void check_below() { if(x_below == NULL) throw SRC_BUG; };
00184 void clean_data() { read_buffer_size = already_read = escape_seq_offset_in_buffer = 0; };
00185 void flush_write();
00186 void flush_or_clean()
00187 {
00188 switch(get_mode())
00189 {
00190 case gf_read_only:
00191 clean_data();
00192 break;
00193 case gf_write_only:
00194 flush_write();
00195 break;
00196 default:
00197 throw SRC_BUG;
00198 }
00199 };
00200 void copy_from(const escape & ref);
00201 bool mini_read_buffer();
00202
00203
00204
00205
00206 static char type2char(sequence_type x);
00207 static sequence_type char2type(char x);
00208
00210
00212
00215 static U_I trouve_amorce(const char *a, U_I size, const unsigned char escape_sequence[ESCAPE_SEQUENCE_LENGTH]);
00216
00218
00225 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]);
00226 };
00227
00229
00230 }
00231
00232 #endif