Disk ARchive  2.7.15
Full featured and portable backup and archiving tool
sparse_file.hpp
Go to the documentation of this file.
1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2024 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // to contact the author, see the AUTHOR file
20 /*********************************************************************/
21 
33 
34 #ifndef SPARSE_FILE_HPP
35 #define SPARSE_FILE_HPP
36 
37 #include "../my_config.h"
38 
39 extern "C"
40 {
41 #if HAVE_LIMITS_H
42 #include <limits.h>
43 #endif
44 }
45 
46 #include "generic_file.hpp"
47 #include "escape.hpp"
48 
49 #define SPARSE_FIXED_ZEROED_BLOCK 40960
50 #ifdef SSIZE_MAX
51 #if SSIZE_MAX < MAX_BUFFER_SIZE
52 #undef MAX_BUFFER_SIZE
53 #define SPARSE_FIXED_ZEROED_BLOCK SSIZE_MAX
54 #endif
55 #endif
56 
57 namespace libdar
58 {
59 
62 
63  class sparse_file : public escape
64  {
65  public:
67 
71  sparse_file(generic_file *below, const infinint & hole_size = 15);
72  sparse_file(const sparse_file & ref) = default;
73  sparse_file(sparse_file && ref) noexcept = default;
74  sparse_file & operator = (const sparse_file & ref) = default;
75  sparse_file & operator = (sparse_file && ref) noexcept = default;
76  ~sparse_file() = default;
77 
81  void write_as_escape(bool mode) { escape_write = mode; };
82 
86  void read_as_escape(bool mode) { escape_read = mode; };
87 
91  void copy_to_without_skip(bool mode) { copy_to_no_skip = mode; };
92 
93  bool has_seen_hole() const { return seen_hole; };
94  bool has_escaped_data() const { return data_escaped; };
95 
98 
107  virtual void copy_to(generic_file & ref) override { crc *tmp = nullptr; copy_to(ref, 0, tmp); if(tmp != nullptr) throw SRC_BUG; };
108 
110 
112  virtual void copy_to(generic_file & ref, const infinint & crc_size, crc * & value) override;
113 
114  // indirectly inherited from generic_file
115  virtual bool skippable(skippability direction, const infinint & amount) override { return false; };
116  virtual bool skip(const infinint & pos) override { if(pos != offset) throw Efeature("skip in sparse_file"); else return true; };
117  virtual bool skip_to_eof() override { throw Efeature("skip in sparse_file"); };
118  virtual bool skip_relative(S_I x) override { if(x != 0) throw Efeature("skip in sparse_file"); return true; };
119  virtual infinint get_position() const override;
120 
121  protected:
122 
123  // methods from the escape class we hide from the (public) class interface
124 
125  void add_mark_at_current_position(sequence_type t) { escape::add_mark_at_current_position(t); };
126  bool skip_to_next_mark(sequence_type t, bool jump) { return escape::skip_to_next_mark(t, jump); };
127  bool next_to_read_is_mark(sequence_type t) { return escape::next_to_read_is_mark(t); };
128  void add_unjumpable_mark(sequence_type t) { escape::add_unjumpable_mark(t); };
129 
130  // methods from generic_file redefined as protected
131 
132  virtual U_I inherited_read(char *a, U_I size) override;
133  virtual void inherited_write(const char *a, U_I size) override;
134  virtual void inherited_sync_write() override;
135  // inherited_flush_read() kept as is from the escape class
136  // inherited_terminate() kept as is from the escape class
137 
138  private:
139  static bool initialized;
140  static unsigned char zeroed_field[SPARSE_FIXED_ZEROED_BLOCK];
141 
142  enum { normal, hole } mode;
143  infinint zero_count;
144  infinint offset;
145  infinint min_hole_size;
146  U_I UI_min_hole_size;
147  bool escape_write;
148  bool escape_read;
149  bool copy_to_no_skip;
150  bool seen_hole;
151  bool data_escaped;
152 
155  void dump_pending_zeros();
156 
158  void write_hole(const infinint & length);
159 
163  void reset();
164 
165 
167 
175  static bool look_for_hole(const char *a, U_I size, U_I min_hole_size, U_I & start, U_I & length);
176 
178 
182  static U_I count_initial_zeros(const char *a, U_I size);
183  };
184 
186 
187 } // end of namespace
188 
189 
190 #endif
U_32 copy_to(generic_file &ref, U_32 size)
small copy (up to 4GB) with CRC calculation
class escape definition, used for sequential reading of archives
class generic_file is defined here as well as class fichier
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47