Disk ARchive 2.7.16
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
39extern "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
57namespace 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