Also, remove `Entry#extra=` as it makes no sense (and wasn't even being
tested).
And remove slightly odd test that was assuming an archive would not be
changed if its utime was changed - even if it was being changed back
immediately. This test was merely confirming that we weren't catching
timestamp changes correctly.
Set it to true by default - because a new `Entry` is dirty by
definition, having not been written yet. Then make sure that an `Entry`
that is created by reading from a zip file is set as not dirty.
When passing an `Entry` type to `File#get_output_stream` the entry is
used to create a `StreamableStream`, which preserves all the info in the
entry, such as timestamp, etc. But then in `put_next_entry` all that is
lost due to the test for `kind_of?(Entry)` which a `StreamableStream` is
not. See #503 for details.
This change tests for `StreamableStream`s in `put_next_entry` and uses
them directly. Some set-up within `Entry` needed to be made more robust
to cope with this, but otherwise it's a low impact change, which does
fix the problem.
The reason this case was being missed before is that the tests weren't
testing `get_output_stream` with an `Entry` object, so I have also added
that test too.
Fixes#503.
When loading extra fields from both the central directory and local headers,
unknown fields were not merged correctly. They were being appended, which
means that we end up with the two versions stuck together - in some
cases duplicating the field completely.
This broke all kinds of things (like calculating the size of a local
header) in subtle ways.
This commit fixes this by implementing a new `Unknown` extra field type,
and making sure that when reading local and central extra fields they
are stored and preserved correctly. We cannot assume the unknown fields
use the same data in the local and central headers.
Fixes#505.
We were previously trying to work out where the next entry would be,
even with GP bit 3 set, but the logic was flaky and cannot really be
correct given the data available. It's not expected behaviour, so raise
the error instead.
This means that we get rid of the incorrect `Entry.data_descriptor_size`
which was doing more harm than good.
Having a specific 'does this instance equal another instance' method is
kind of annoying and breaks a number of things. Most obviously it breaks
comparing to `nil`: `nil.dos_equals(other)` will fail where
`nil == other` does not.
So this commit overrides `<=>` in `Zip::DOSTime` and deprecates
`dos_equals`.
Whatever the compression method that is set by the user, if the
compression level is set to 0 (no compression), then the entry should be
STORED. This mimics commandline tool behaviour and matches user
expectations.
Constants for Store and Deflate are already available, so use them. It
might be sensible to remove these local versions, but they do have their
uses as a shortened form.
Remove a load of accessors from the 'public' API by not documenting
them, and remove access to `header_signature` completely.
Also, `Entry#extra` has been created to allow extra fields to be set
correctly after initialization.
This greatly simplifies the creation of `Entry` objects when only a
couple of fields are not set to their defaults, while at the same time
allowing an `Entry` to be fully configured at creation time if
appropriate.
This fundamentally changes the `Entry` API and means that some
convenience methods in `OutputStream` and `File` have needed to be
refactored.
There was some fairly odd stuff going on in `put_next_entry` that
allowed for data within an `Entry` to be overridden and prevented an
`Entry` from being a single point of truth. Fixing this also simplifies
the code within `File` and still passes all tests.
Also, fixing the above means we can stop passing the compression level
around as a parameter and use the value stored in each `Entry` directly.
Let's keep `compression_level` out of the `Entry` public API though as
it only makes sense when writing an `Entry`: there doesn't seem to be an
obvious way to read what level of compression was used when reading an
`Entry` from a zip file.
Allow an Entry to specify a compression level and pass this down to the
underlying OutputStream infrastructure. OutputStream has been able to
specify a compression level for a while but this has, up until now, only
ever been set to the default.
This fundamentally changes the API so will need a major version bump.