diff options
author | João Matos <joao@tritao.eu> | 2016-06-30 15:58:27 +0300 |
---|---|---|
committer | João Matos <joao@tritao.eu> | 2016-06-30 16:15:52 +0300 |
commit | 4fc860ec217b121bda019de9b182a48ad9642f8d (patch) | |
tree | 246d6b829e38f89de8587aa757ee0b8cc054164c /mcs/class/System.IO.Compression | |
parent | c167f3abe391923656db51f7d5db4c6d0eaef951 (diff) |
[System.IO.Compression] Fixed Zip entry stream length/position getters in Update mode.
This does away with the lazy writeable entry scheme in Update mode and converts the stream to be writeable when its opened in Update mode.
From local testing, .NET does the same in this case.
Fixes another issue reported by @Numpsy in https://github.com/OfficeDev/Open-XML-SDK/issues/64.
Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=42274.
Diffstat (limited to 'mcs/class/System.IO.Compression')
-rw-r--r-- | mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs | 31 | ||||
-rw-r--r-- | mcs/class/System.IO.Compression/ZipArchiveEntry.cs | 24 |
2 files changed, 38 insertions, 17 deletions
diff --git a/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs b/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs index 99692163002..b9bb8101185 100644 --- a/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs +++ b/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs @@ -275,11 +275,10 @@ namespace MonoTests.System.IO.Compression } } - [Test] - public void ZipGetArchiveEntryStreamLengthPositionReadMode() + public void ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode mode) { - using (var archive = new ZipArchive(File.Open("test.nupkg", FileMode.Open), - ZipArchiveMode.Read)) + File.Copy("test.nupkg", "test2.nupkg", overwrite: true); + using (var archive = new ZipArchive(File.Open("test2.nupkg", FileMode.Open), mode)) { var entry = archive.GetEntry("_rels/.rels"); using (var stream = entry.Open()) @@ -287,10 +286,34 @@ namespace MonoTests.System.IO.Compression Assert.AreEqual(0, stream.Position); Assert.AreEqual(425, stream.Length); } + + // .NET does not support these in Read mode but we do. + var entry2 = archive.GetEntry("modernhttpclient.nuspec"); + using (var stream = entry2.Open()) + { + Assert.AreEqual(857, stream.Length); + if (mode == ZipArchiveMode.Update) + { + Assert.AreEqual(0, stream.Position); + } + } } + File.Delete ("test2.nupkg"); } [Test] + public void ZipGetArchiveEntryStreamLengthPositionReadMode() + { + ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode.Read); + } + + [Test] + public void ZipGetArchiveEntryStreamLengthPositionUpdateMode() + { + ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode.Update); + } + + [Test] public void ZipEnumerateEntriesReadMode() { File.Copy("archive.zip", "test.zip", overwrite: true); diff --git a/mcs/class/System.IO.Compression/ZipArchiveEntry.cs b/mcs/class/System.IO.Compression/ZipArchiveEntry.cs index 002b6f14ceb..9b415fbe6fd 100644 --- a/mcs/class/System.IO.Compression/ZipArchiveEntry.cs +++ b/mcs/class/System.IO.Compression/ZipArchiveEntry.cs @@ -54,7 +54,7 @@ namespace System.IO.Compression public override long Length { get { - return stream.Length; + return stream.CanWrite ? stream.Length : entry.Length; } } @@ -95,15 +95,16 @@ namespace System.IO.Compression public override void Write (byte[] buffer, int offset, int count) { - if (entry.Archive.Mode == ZipArchiveMode.Update && !entry.wasWritten) + stream.Write(buffer, offset, count); + } + + internal void EnsureWriteable() + { + if (entry.Archive.Mode == ZipArchiveMode.Update && !stream.CanWrite) { // Replace the read-only stream with a writeable memory stream. - if (!stream.CanWrite) - SetWriteable(); - entry.wasWritten = true; + SetWriteable(); } - - stream.Write(buffer, offset, count); } internal void SetWriteable() @@ -115,15 +116,11 @@ namespace System.IO.Compression var newStream = newEntry.OpenEntryStream(); var openStream = stream; - var position = openStream.Position; - - entry.openStream = null; - entry.Open(); - openStream.CopyTo(newStream); - newStream.Position = position; openStream.Dispose(); + newStream.Position = 0; + archive.zipFile.RemoveEntry(internalEntry); entry.entry = newEntry; stream = newStream; @@ -232,6 +229,7 @@ namespace System.IO.Compression var entryStream = entry.OpenEntryStream(); openStream = new ZipArchiveEntryStream(this, entryStream); + openStream.EnsureWriteable(); return openStream; } |