aboutsummaryrefslogtreecommitdiff
path: root/src/xz/file_io.h
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2009-11-25 11:19:20 +0200
committerLasse Collin <lasse.collin@tukaani.org>2009-11-25 11:19:20 +0200
commit465d1b0d6518c5d980f2db4c2d769f9905bdd902 (patch)
treea4268eaa071e4cc52da9d56cb5c76168c604ff75 /src/xz/file_io.h
parentUpdated THANKS. (diff)
downloadxz-465d1b0d6518c5d980f2db4c2d769f9905bdd902.tar.xz
Create sparse files by default when decompressing into
a regular file. Sparse file creation can be disabled with --no-sparse. I don't promise yet that the name of this option won't change before 5.0.0. It's possible that the code, that checks when it is safe to use sparse output on stdout, is not good enough, and a more flexible command line option is needed to configure sparse file handling.
Diffstat (limited to '')
-rw-r--r--src/xz/file_io.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/xz/file_io.h b/src/xz/file_io.h
index b0bbe11a..58bf7b5e 100644
--- a/src/xz/file_io.h
+++ b/src/xz/file_io.h
@@ -11,13 +11,22 @@
///////////////////////////////////////////////////////////////////////////////
// Some systems have suboptimal BUFSIZ. Use a bit bigger value on them.
+// We also need that IO_BUFFER_SIZE is a multiple of 8 (sizeof(uint64_t))
#if BUFSIZ <= 1024
# define IO_BUFFER_SIZE 8192
#else
-# define IO_BUFFER_SIZE BUFSIZ
+# define IO_BUFFER_SIZE (BUFSIZ & ~7U)
#endif
+/// is_sparse() accesses the buffer as uint64_t for maximum speed.
+/// Use an union to make sure that the buffer is properly aligned.
+typedef union {
+ uint8_t u8[IO_BUFFER_SIZE];
+ uint64_t u64[IO_BUFFER_SIZE / sizeof(uint64_t)];
+} io_buf;
+
+
typedef struct {
/// Name of the source filename (as given on the command line) or
/// pointer to static "(stdin)" when reading from standard input.
@@ -33,15 +42,24 @@ typedef struct {
/// File descriptor of the target file
int dest_fd;
+ /// True once end of the source file has been detected.
+ bool src_eof;
+
+ /// If true, we look for long chunks of zeros and try to create
+ /// a sparse file.
+ bool dest_try_sparse;
+
+ /// This is used only if dest_try_sparse is true. This holds the
+ /// number of zero bytes we haven't written out, because we plan
+ /// to make that byte range a sparse chunk.
+ off_t dest_pending_sparse;
+
/// Stat of the source file.
struct stat src_st;
/// Stat of the destination file.
struct stat dest_st;
- /// True once end of the source file has been detected.
- bool src_eof;
-
} file_pair;
@@ -49,6 +67,10 @@ typedef struct {
extern void io_init(void);
+/// \brief Disable creation of sparse files when decompressing
+extern void io_no_sparse(void);
+
+
/// \brief Opens a file pair
extern file_pair *io_open(const char *src_name);
@@ -72,7 +94,7 @@ extern void io_close(file_pair *pair, bool success);
/// \return On success, number of bytes read is returned. On end of
/// file zero is returned and pair->src_eof set to true.
/// On error, SIZE_MAX is returned and error message printed.
-extern size_t io_read(file_pair *pair, uint8_t *buf, size_t size);
+extern size_t io_read(file_pair *pair, io_buf *buf, size_t size);
/// \brief Writes a buffer to the destination file
@@ -83,4 +105,4 @@ extern size_t io_read(file_pair *pair, uint8_t *buf, size_t size);
///
/// \return On success, zero is returned. On error, -1 is returned
/// and error message printed.
-extern bool io_write(const file_pair *pair, const uint8_t *buf, size_t size);
+extern bool io_write(file_pair *pair, const io_buf *buf, size_t size);