From: Jon Turney <jon.turney@dronecode.org.uk>
To: cygwin-apps@cygwin.com
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: [PATCH setup 04/11] Add seek() method to archive and compress file classes
Date: Tue, 10 Aug 2021 18:02:21 +0100 [thread overview]
Message-ID: <20210810170228.1690-5-jon.turney@dronecode.org.uk> (raw)
In-Reply-To: <20210810170228.1690-1-jon.turney@dronecode.org.uk>
Add seek() method to archive and compressed file isostream classes
(which can only rewind to the start).
Also clean up some cruft in archive class.
This still needs testing on a .gz archive (slightly involved as there
aren't any currently!)
---
archive.cc | 52 --------------------------------------
archive.h | 14 +++--------
archive_tar.cc | 14 +++++++----
compress_bz.cc | 12 +++++++++
compress_bz.h | 1 +
compress_gz.cc | 65 +++++++++++++++++++++++++++++-------------------
compress_gz.h | 3 ++-
compress_xz.cc | 34 ++++++++++++++++++-------
compress_xz.h | 3 ++-
compress_zstd.cc | 19 +++++++++++---
compress_zstd.h | 3 ++-
11 files changed, 111 insertions(+), 109 deletions(-)
diff --git a/archive.cc b/archive.cc
index 1ceb355..448ea0e 100644
--- a/archive.cc
+++ b/archive.cc
@@ -45,7 +45,6 @@
* offset 257 string ustar\040\040\0
*/
-
#define longest_magic 265
archive *
@@ -65,15 +64,6 @@ archive::extract (io_stream * original)
return rv;
return NULL;
}
-#if 0
- else if (memcmp (magic, "BZh", 3) == 0)
- {
- archive_bz *rv = new archive_bz (original);
- if (!rv->error ())
- return rv;
- return NULL;
- }
-#endif
}
return NULL;
}
@@ -194,45 +184,3 @@ out:
}
archive::~archive () {};
-
-#if 0
-ssize_t archive::read (void *buffer, size_t len)
-{
- Log (LOG_TIMESTAMP, "archive::read called");
- return 0;
-}
-
-ssize_t archive::write (void *buffer, size_t len)
-{
- Log (LOG_TIMESTAMP, "archive::write called");
- return 0;
-}
-
-ssize_t archive::peek (void *buffer, size_t len)
-{
- Log (LOG_TIMESTAMP, "archive::peek called");
- return 0;
-}
-
-long
-archive::tell ()
-{
- Log (LOG_TIMESTAMP, "bz::tell called");
- return 0;
-}
-
-int
-archive::error ()
-{
- Log (LOG_TIMESTAMP, "archive::error called");
- return 0;
-}
-
-const char *
-archive::next_file_name ()
-{
- Log (LOG_TIMESTAMP, "archive::next_file_name called");
- return NULL;
-}
-
-#endif
diff --git a/archive.h b/archive.h
index d3c795a..adab9f0 100644
--- a/archive.h
+++ b/archive.h
@@ -69,14 +69,9 @@ public:
/* read data - not valid for archives (duh!)
* Could be made valid via the read-child-directly model
*/
-// virtual ssize_t read(void *buffer, size_t len) {return -1;};
- /* provide data to (double duh!) */
-// virtual ssize_t write(void *buffer, size_t len) { return -1;};
- /* read data without removing it from the class's internal buffer */
-// virtual ssize_t peek(void *buffer, size_t len);
-// virtual long tell ();
- /* try guessing this one */
-// virtual int error ();
+
+ virtual int seek (long offset, io_stream_seek_t whence) = 0;
+
/* Find out the next stream name -
* ie for foo.tar.gz, at offset 0, next_file_name = foo.tar
* for foobar that is an compress, next_file_name is the next
@@ -88,14 +83,11 @@ public:
virtual archive_file_t next_file_type () = 0;
virtual const std::string linktarget () = 0;
virtual int skip_file () = 0;
- /* if you are still needing these hints... give up now! */
virtual ~archive() = 0;
protected:
void operator= (const archive &);
archive () {};
archive (const archive &);
-private:
-// archive () {};
};
#endif /* SETUP_ARCHIVE_H */
diff --git a/archive_tar.cc b/archive_tar.cc
index c359238..5b2a771 100644
--- a/archive_tar.cc
+++ b/archive_tar.cc
@@ -100,11 +100,15 @@ archive_tar::tell ()
int
archive_tar::seek (long where, io_stream_seek_t whence)
{
- /* seeking in the parent archive doesn't make sense. although we could
- map to files ?
- Also, seeking might make sense for rewing..??
- */
- return -1;
+ /* Because the parent stream is compressed, we can only easily support
+ seek()-ing to rewind to the start */
+ if ((whence == IO_SEEK_SET) && (where == 0))
+ {
+ state.header_read = 0;
+ return state.parent->seek(where, whence);
+ }
+
+ return -1;
}
int
diff --git a/compress_bz.cc b/compress_bz.cc
index 18773d4..e4792d6 100644
--- a/compress_bz.cc
+++ b/compress_bz.cc
@@ -35,7 +35,12 @@ compress_bz::compress_bz (io_stream * parent) : peeklen (0), position (0)
}
original = parent;
owns_original = true;
+ init_state();
+}
+void
+compress_bz::init_state(void)
+{
initialisedOk = 0;
endReached = 0;
writing = 0;
@@ -194,6 +199,13 @@ compress_bz::tell ()
int
compress_bz::seek (long where, io_stream_seek_t whence)
{
+ if ((whence == IO_SEEK_SET) && (where == 0))
+ {
+ int result = original->seek(where, whence);
+ init_state();
+ return result;
+ }
+
throw new std::logic_error ("compress_bz::seek is not implemented");
}
diff --git a/compress_bz.h b/compress_bz.h
index 39a0d5b..a7e865a 100644
--- a/compress_bz.h
+++ b/compress_bz.h
@@ -67,6 +67,7 @@ private:
char buf[4096];
int writing;
size_t position;
+ void init_state(void);
};
#endif /* SETUP_COMPRESS_BZ_H */
diff --git a/compress_gz.cc b/compress_gz.cc
index 55a015e..e73ccd3 100644
--- a/compress_gz.cc
+++ b/compress_gz.cc
@@ -41,19 +41,23 @@ static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
*/
compress_gz::compress_gz (io_stream * parent)
{
- construct (parent, "r");
+ original = parent;
+ owns_original = true;
+ openmode = "r";
+ construct ();
}
-compress_gz::compress_gz (io_stream * parent, const char *openmode)
+compress_gz::compress_gz (io_stream * parent, const char *_openmode)
{
- construct (parent, openmode);
+ original = parent;
+ owns_original = true;
+ openmode = _openmode;
+ construct ();
}
void
-compress_gz::construct (io_stream * parent, const char *openmode)
+compress_gz::construct ()
{
- original = parent;
- owns_original = true;
peeklen = 0;
int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */
@@ -76,7 +80,7 @@ compress_gz::construct (io_stream * parent, const char *openmode)
mode = '\0';
- if (!parent)
+ if (!original)
{
z_err = Z_STREAM_ERROR;
return;
@@ -413,6 +417,14 @@ compress_gz::tell ()
int
compress_gz::seek (long where, io_stream_seek_t whence)
{
+ if ((whence == IO_SEEK_SET) && (where == 0))
+ {
+ int result = original->seek(where, whence);
+ destroy();
+ construct();
+ return result;
+ }
+
throw new std::logic_error("compress_gz::seek is not implemented");
}
@@ -458,7 +470,11 @@ void
compress_gz::destroy ()
{
if (msg)
- free (msg);
+ {
+ free (msg);
+ msg = NULL;
+ }
+
if (stream.state != NULL)
{
if (mode == 'w')
@@ -472,12 +488,15 @@ compress_gz::destroy ()
}
if (inbuf)
-
- free (inbuf);
+ {
+ free (inbuf);
+ inbuf = NULL;
+ }
if (outbuf)
- free (outbuf);
- if (original && owns_original)
- delete original;
+ {
+ free (outbuf);
+ outbuf = NULL;
+ }
}
compress_gz::~compress_gz ()
@@ -485,16 +504,15 @@ compress_gz::~compress_gz ()
if (mode == 'w')
{
z_err = do_flush (Z_FINISH);
- if (z_err != Z_OK)
- {
- destroy ();
- return;
- }
-
- putLong (crc);
- putLong (stream.total_in);
+ if (z_err == Z_OK)
+ {
+ putLong (crc);
+ putLong (stream.total_in);
+ }
}
destroy ();
+ if (original && owns_original)
+ delete original;
}
int
@@ -534,11 +552,6 @@ compress_gz::do_flush (int flush)
return z_err == Z_STREAM_END ? Z_OK : z_err;
}
-
-#if 0
-
-gzclose (lst);
-#endif
/* ===========================================================================
* Read a byte from a gz_stream; update next_in and avail_in. Return EOF
* for end of file.
diff --git a/compress_gz.h b/compress_gz.h
index 50b6e66..90073e5 100644
--- a/compress_gz.h
+++ b/compress_gz.h
@@ -60,7 +60,7 @@ private:
};
char peekbuf[512];
size_t peeklen;
- void construct (io_stream *, const char *);
+ void construct ();
void check_header ();
int get_byte ();
unsigned long getLong ();
@@ -69,6 +69,7 @@ private:
int do_flush (int);
io_stream *original;
bool owns_original;
+ const char *openmode;
/* from zlib */
z_stream stream;
int z_err; /* error code for last stream operation */
diff --git a/compress_xz.cc b/compress_xz.cc
index a5167d6..bb64595 100644
--- a/compress_xz.cc
+++ b/compress_xz.cc
@@ -51,9 +51,6 @@ compress_xz::compress_xz (io_stream * parent)
lasterr(0),
compression_type (COMPRESSION_UNKNOWN)
{
- unsigned char * out_block = NULL;
- unsigned char * in_block = NULL;
-
/* read only */
if (!parent || parent->error())
{
@@ -62,6 +59,16 @@ compress_xz::compress_xz (io_stream * parent)
}
original = parent;
+ create ();
+ init_decoder ();
+}
+
+void
+compress_xz::create ()
+{
+ unsigned char * out_block = NULL;
+ unsigned char * in_block = NULL;
+
state = (struct private_data *)calloc(sizeof(*state), 1);
out_block = (unsigned char *)malloc(out_block_size);
in_block = (unsigned char *)malloc(in_block_size);
@@ -79,12 +86,10 @@ compress_xz::compress_xz (io_stream * parent)
state->out_block = out_block;
state->in_block_size = in_block_size;
state->in_block = in_block;
- state->out_p = out_block;
+ state->out_p = state->out_block;
state->stream.avail_in = 0;
state->stream.next_out = state->out_block;
state->stream.avail_out = state->out_block_size;
-
- init_decoder ();
}
ssize_t
@@ -267,6 +272,17 @@ compress_xz::tell ()
int
compress_xz::seek (long where, io_stream_seek_t whence)
{
+ if ((whence == IO_SEEK_SET) && (where == 0))
+ {
+ int result = original->seek(where, whence);
+ destroy ();
+ peeklen = 0;
+ lasterr = 0;
+ create ();
+ init_decoder ();
+ return result;
+ }
+
throw new std::logic_error("compress_xz::seek is not implemented");
}
@@ -334,14 +350,14 @@ compress_xz::destroy ()
compression_type = COMPRESSION_UNKNOWN;
}
-
- if (original && owns_original)
- delete original;
}
compress_xz::~compress_xz ()
{
destroy ();
+
+ if (original && owns_original)
+ delete original;
}
/* ===========================================================================
diff --git a/compress_xz.h b/compress_xz.h
index 24cbb09..31d499c 100644
--- a/compress_xz.h
+++ b/compress_xz.h
@@ -27,7 +27,7 @@ public:
virtual ssize_t write (const void *buffer, size_t len); /* not implemented */
virtual ssize_t peek (void *buffer, size_t len);
virtual long tell (); /* not implemented */
- virtual int seek (long where, io_stream_seek_t whence); /* not implemented */
+ virtual int seek (long where, io_stream_seek_t whence);
virtual int error ();
virtual const char *next_file_name () { return NULL; };
virtual int set_mtime (time_t);
@@ -49,6 +49,7 @@ private:
char peekbuf[512];
size_t peeklen;
int lasterr;
+ void create ();
void destroy ();
struct private_data {
diff --git a/compress_zstd.cc b/compress_zstd.cc
index 3588dbd..bb17785 100644
--- a/compress_zstd.cc
+++ b/compress_zstd.cc
@@ -35,7 +35,12 @@ compress_zstd::compress_zstd (io_stream * parent)
return;
}
original = parent;
+ create();
+}
+void
+compress_zstd::create (void)
+{
state = (struct private_data *)calloc(sizeof(*state), 1);
if (state == NULL)
{
@@ -179,6 +184,14 @@ compress_zstd::tell ()
int
compress_zstd::seek (long where, io_stream_seek_t whence)
{
+ if ((whence == IO_SEEK_SET) && (where == 0))
+ {
+ int result = original->seek(where, whence);
+ destroy();
+ create();
+ return result;
+ }
+
throw new std::logic_error("compress_zstd::seek is not implemented");
}
@@ -240,14 +253,14 @@ compress_zstd::destroy ()
free(state);
state = NULL;
}
-
- if (original && owns_original)
- delete original;
}
compress_zstd::~compress_zstd ()
{
destroy ();
+
+ if (original && owns_original)
+ delete original;
}
bool
diff --git a/compress_zstd.h b/compress_zstd.h
index be5712c..3303daa 100644
--- a/compress_zstd.h
+++ b/compress_zstd.h
@@ -25,7 +25,7 @@ public:
virtual ssize_t write (const void *buffer, size_t len); /* not implemented */
virtual ssize_t peek (void *buffer, size_t len);
virtual long tell (); /* not implemented */
- virtual int seek (long where, io_stream_seek_t whence); /* not implemented */
+ virtual int seek (long where, io_stream_seek_t whence);
virtual int error ();
virtual const char *next_file_name () { return NULL; };
virtual int set_mtime (time_t);
@@ -42,6 +42,7 @@ private:
io_stream *original;
bool owns_original;
int lasterr;
+ void create ();
void destroy ();
struct private_data {
--
2.32.0
next prev parent reply other threads:[~2021-08-10 17:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-10 17:02 [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney
2021-08-10 17:02 ` [PATCH setup 01/11] Add support for creating WSL symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 02/11] Add support for creating native symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 03/11] Factor out the iteration over archive files to install Jon Turney
2021-08-10 17:02 ` Jon Turney [this message]
2021-08-10 17:02 ` [PATCH setup 05/11] Add separate symlink-creation phase when extracting archive Jon Turney
2021-08-10 17:02 ` [PATCH setup 06/11] Enable SeCreateSymbolicLink privilege Jon Turney
2021-08-11 8:46 ` Corinna Vinschen
2021-09-14 11:53 ` Jon Turney
2021-08-10 17:02 ` [PATCH setup 07/11] Add symlink capabilities to user-agent telemetry Jon Turney
2021-08-10 17:02 ` [PATCH setup 08/11] Factor out StringChoiceOption Jon Turney
2021-08-10 17:02 ` [PATCH setup 09/11] Add a command line option to choose symlink type used Jon Turney
2021-08-10 17:02 ` [PATCH setup 10/11] Propagate --symlink-type setting to post-install scripts Jon Turney
2021-08-10 17:02 ` [PATCH setup 11/11] Default symlink mode from CYGWIN env var Jon Turney
2021-09-14 11:53 ` [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210810170228.1690-5-jon.turney@dronecode.org.uk \
--to=jon.turney@dronecode.org.uk \
--cc=cygwin-apps@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).