Disk ARchive 2.8.3
Full featured and portable backup and archiving tool
Loading...
Searching...
No Matches
sparse_file.hpp
Go to the documentation of this file.
1/*********************************************************************/
2// dar - disk archive - a backup/restoration program
3// Copyright (C) 2002-2026 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
virtual void inherited_sync_write()=0
write down any pending data
virtual infinint get_position() const =0
get the current read/write position
virtual bool skip_to_eof()=0
skip to the end of file
class escape definition, used for sequential reading of archives
include macro defined by the configure script and some specific additional ones
libdar namespace encapsulate all libdar symbols
class generic_file is defined here as well as class fichier