public void UpdateZip_ChangeMetadata_AES()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_ChangeMetadata_AES.zip");
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int numFilesToCreate = _rnd.Next(13) + 24;
            //int numFilesToCreate = 2;
            string filename = null;
            for (int j = 0; j < numFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000);
                //TestUtilities.CreateAndFillFileText(filename, 500);
            }

            string password = Path.GetRandomFileName() + Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            using (var zip = new ZipFile())
            {
                zip.Password = password;
                zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip.AddFiles(Directory.GetFiles(subdir), "");
                zip.Save(zipFileToCreate);
            }

            // Verify the correct number of files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), numFilesToCreate,
                                 "Fie! The updated Zip file has the wrong number of entries.");

            // test extract (and implicitly check CRCs, passwords, etc)
            VerifyZip(zipFileToCreate, password);

            byte[] buffer = new byte[_rnd.Next(10000) + 10000];
            _rnd.NextBytes(buffer);
            using (var zip = ZipFile.Read(zipFileToCreate))
            {
                // modify the metadata for an entry
                zip[0].LastModified = DateTime.Now - new TimeSpan(7 * 31, 0, 0);
                zip.Password = password;
                zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip.AddEntry(Path.GetRandomFileName(), buffer);
                zip.Save();
            }

            // Verify the correct number of files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), numFilesToCreate + 1,
                                 "Fie! The updated Zip file has the wrong number of entries.");

            // test extract (and implicitly check CRCs, passwords, etc)
            VerifyZip(zipFileToCreate, password);
        }
        public void Create_EmitTimestampOptions()
        {
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            for (int j = 0; j < 3; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Create_EmitTimestampOptions-{0}-{1}.zip", j, k));
                    using (var zip = new ZipFile())
                    {
                        if (j == 1) zip.EmitTimesInUnixFormatWhenSaving = false;
                        else if (j == 2) zip.EmitTimesInUnixFormatWhenSaving = true;

                        if (k == 1) zip.EmitTimesInWindowsFormatWhenSaving = false;
                        else if (k == 2) zip.EmitTimesInWindowsFormatWhenSaving = true;

                        zip.AddFiles(files, "files");
                        zip.Save(zipFileToCreate);
                    }

                    Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate), "The Zip file has the wrong number of entries.");

                    using (var zip = ZipFile.Read(zipFileToCreate))
                    {
                        for (int i = 0; i < zip.Entries.Count; i++)
                        {
                            if (j == 2)
                                Assert.AreEqual<ZipEntryTimestamp>(ZipEntryTimestamp.Unix, zip[i].Timestamp & ZipEntryTimestamp.Unix,
                                    "Missing Unix timestamp (cycle {0},{1}) (entry {2}).", j, k, i);
                            else
                                Assert.AreEqual<ZipEntryTimestamp>(ZipEntryTimestamp.None, zip[i].Timestamp & ZipEntryTimestamp.Unix,
                                    "Unix timestamp is present when none is expected (cycle {0},{1}) (entry {2}).", j, k, i);

                            if (k == 1)
                                Assert.AreEqual<ZipEntryTimestamp>(ZipEntryTimestamp.None, zip[i].Timestamp & ZipEntryTimestamp.Windows,
                                    "Windows timestamp is present when none is expected (cycle {0},{1}) (entry {2}).", j, k, i);
                            else
                                Assert.AreEqual<ZipEntryTimestamp>(ZipEntryTimestamp.Windows, zip[i].Timestamp & ZipEntryTimestamp.Windows,
                                    "Missing Windows timestamp (cycle {0},{1}) (entry {2}).", j, k, i);

                            Assert.AreEqual<ZipEntryTimestamp>(ZipEntryTimestamp.DOS, zip[i].Timestamp & ZipEntryTimestamp.DOS,
                                "Missing DOS timestamp (entry (cycle {0},{1}) (entry {2}).", j, k, i);
                        }
                    }
                }
            }
        }
        public void UpdateZip_AddFile_NewEntriesWithPassword()
        {
            string password = "******";
            string filename = null;
            int entriesAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_AddFile_NewEntriesWithPassword.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create a bunch of files
            int numFilesToCreate = _rnd.Next(10) + 8;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                    Path.GetFileName(filename));
                TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // Create the zip archive
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                zip.AddFiles(filenames, "");
                zip.Comment = "UpdateTests::UpdateZip_AddFile_NewEntriesWithPassword(): This archive will be updated.";
                zip.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                "The Zip file has the wrong number of entries.");

            // Create a bunch of new files...
            var addedFiles = new List<string>();
            int numToUpdate = _rnd.Next(numFilesToCreate - 4);
            for (j = 0; j < numToUpdate; j++)
            {
                // select a new, uniquely named file to create
                filename = String.Format("newfile{0:D3}.txt", j);
                // create a new file, and fill that new file with text data
                repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                    filename, System.DateTime.Now.ToString("yyyy-MM-dd"));
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                addedFiles.Add(filename);
            }

            // add each one of those new files in the zip archive using a password
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                zip2.Password = password;
                foreach (string s in addedFiles)
                    zip2.AddFile(Path.Combine(subdir, s), "");
                zip2.Comment = "UpdateTests::UpdateZip_AddFile_OldEntriesWithPassword(): This archive has been updated.";
                zip2.Save();
            }


            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded + addedFiles.Count,
                "The Zip file has the wrong number of entries.");


            // now extract the newly-added files and verify their contents
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s in addedFiles)
                {
                    repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                        s, System.DateTime.Now.ToString("yyyy-MM-dd"));
                    zip3[s].ExtractWithPassword("extract", password);

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(repeatedLine, sLine,
                            String.Format("The content of the Updated file ({0}) in the zip archive is incorrect.", s));
                }
            }


            // extract all the other files and verify their contents
            using (ZipFile zip4 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s1 in zip4.EntryFileNames)
                {
                    bool addedLater = false;
                    foreach (string s2 in addedFiles)
                    {
                        if (s2 == s1) addedLater = true;
                    }
                    if (!addedLater)
                    {
                        zip4[s1].Extract("extract");
                        repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                            s1);

                        // verify the content of the updated file.
                        var sr = new StreamReader(Path.Combine("extract", s1));
                        string sLine = sr.ReadLine();
                        sr.Close();

                        Assert.AreEqual<string>(repeatedLine, sLine,
                                String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));
                    }
                }
            }
        }
        public void _Internal_CreateZip_ZeroLengthFiles(string password, EncryptionAlgorithm algorithm)
        {
            if (!WinZipIsPresent)
                throw new Exception("no winzip! [_Internal_CreateZip_ZeroLengthFiles]");

            string zipFileToCreate = "WZA_CreateZip_ZeroLengthFiles.zip";
            Assert.IsFalse(File.Exists(zipFileToCreate));

            TestContext.WriteLine("Creating file {0}", zipFileToCreate);
            TestContext.WriteLine("  Password:   {0}", password);

            // create a bunch of zero-length files
            int entries = _rnd.Next(21) + 5;
            int i;
            string[] filesToZip = new string[entries];
            for (i = 0; i < entries; i++)
                filesToZip[i] = TestUtilities.CreateUniqueFile("zerolength", TopLevelDir);

            using (ZipFile zip = new ZipFile())
            {
                zip.Encryption = algorithm;
                zip.Password = password;
                zip.AddFiles(filesToZip);
                zip.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate, password);

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                 filesToZip.Length);
        }
        public void DoubleSave_wi10735()
        {
            string zipFileToCreate1 = "DoubleSave.1.zip";
            string zipFileToCreate2 = "DoubleSave.2.zip";
            string dirToZip = "dirToZip";
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            using (var zip = new ZipFile())
            {
                zip.AddFiles(files);
                zip.Save(zipFileToCreate1);
                zip.Save(zipFileToCreate2);
            }
        }
        public void Progress_AddFiles()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string  zipFileToCreate = Path.Combine(TopLevelDir, "Progress_AddFiles.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            var sw = new StringWriter();
            using (ZipFile zip = new ZipFile(zipFileToCreate, sw))
            {
                zip.AddProgress += AddProgress1;
                zip.AddFiles(files);
                zip.Save();
            }
            TestContext.WriteLine(sw.ToString());

            int count = TestUtilities.CountEntries(zipFileToCreate);
            Assert.AreEqual<Int32>(count, files.Length);
        }
        public void Password_CheckZipPassword_wi13664()
        {
            string[] passwords = { null,
                                   "Password!",
                                   TestUtilities.GenerateRandomPassword(),
                                   "_" };

            string dirToZip = Path.Combine(TopLevelDir, "zipthis");
            int subdirCount;
            int entries = TestUtilities.GenerateFilesOneLevelDeep
                (TestContext, "wi13664", dirToZip, null, out subdirCount);
            string[] filesToZip = Directory.GetFiles("zipthis", "*.*", SearchOption.AllDirectories);

            Assert.AreEqual<int>(filesToZip.Length, entries,
                                 "Incorrect number of entries in the directory.");

            for (int j = 0; j < passwords.Length; j++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Password_CheckZipPassword_wi13664-{0}.zip", j));

                // Create the zip archive
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.Password = passwords[j];
                    zip1.AddFiles(filesToZip, true, "");
                    zip1.Save(zipFileToCreate);
                }

                var r = ZipFile.CheckZipPassword(zipFileToCreate, passwords[j]);
                Assert.IsTrue(r, "Bad password in round {0}", j);
            }
        }
        public void Create_ZipErrorAction_RetryAndEventuallySucceed()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Create_ZipErrorAction_RetryAndEventuallySucceed.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip);
            int n = _rnd.Next(files.Length);

            TestContext.WriteLine("Locking file {0}...", files[n]);

            // This will lock the file for 3 seconds, then release it.
            // The goal is to test whether the retry actually succeeds.
            System.Threading.ThreadPool.QueueUserWorkItem(lockFile, new Object[] { files[n], 3000 });
            System.Threading.Thread.Sleep(200);

            _retryCount = 0;
            using (var zip = new ZipFile())
            {
                zip.ZipErrorAction = ZipErrorAction.Retry;
                zip.AddFiles(files, "fodder");
                zip.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate);

            Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                 "The zip file created has the wrong number of entries.");
        }
        public void ParallelDeflateStream_Create()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "ParallelDeflateStream_Create.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip, _rnd.Next(5) + 5, 128 * 1024 + _rnd.Next(20000));

            using (var zip = new ZipFile())
            {
                zip.ParallelDeflateThreshold = 65536;
                zip.AddFiles(files, "fodder");
                zip.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate);

            Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                 "The zip file created has the wrong number of entries.");
        }
        public void Create_ZipErrorAction_Skip()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            // m is the number of files to lock
            for (int m = 1; m < 4; m++)
            {
                // k is the type of locking.  0 == whole file, 1 == range lock
                for (int k = 0; k < 2; k++)
                {
                    TestContext.WriteLine("Trial {0}.{1}...", m, k);
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Create_ZipErrorAction_Skip-{0}-{1}.zip", m, k));
                    var locked = new Dictionary<String, FileStream>();
                    try
                    {
                        for (int i = 0; i < m; i++)
                        {
                            int n = 0;
                            do
                            {
                                n = _rnd.Next(files.Length);
                            } while (locked.ContainsKey(files[n]));

                            TestContext.WriteLine("  Locking file {0}...", files[n]);

                            FileStream lockStream = null;
                            if (k == 0)
                            {
                                lockStream = new FileStream(files[n], FileMode.Open, FileAccess.Read, FileShare.None);
                            }
                            else
                            {
                                lockStream = new FileStream(files[n], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                                int r = _rnd.Next((int)(lockStream.Length / 2));
                                int s = _rnd.Next((int)(lockStream.Length / 2));
                                lockStream.Lock(s, r);
                            }

                            locked.Add(files[n], lockStream);
                        }

                        using (var zip = new ZipFile())
                        {
                            zip.ZipErrorAction = ZipErrorAction.Skip;
                            zip.AddFiles(files, "fodder");
                            zip.Save(zipFileToCreate);
                        }

                        using (var zip = new ZipFile(zipFileToCreate))
                        {
                            // Writing the info as a single block puts everything on the
                            // same line, makes it unreadable.  So we split the strings on
                            // newline boundaries and write them individually.
                            foreach (string s in zip.Info.Split('\r', '\n'))
                            {
                                Console.WriteLine("{0}", s);
                            }
                        }

                        BasicVerifyZip(zipFileToCreate);

                        Assert.AreEqual<int>(files.Length - m, TestUtilities.CountEntries(zipFileToCreate),
                                             "The zip file created has the wrong number of entries.");
                    }
                    finally
                    {
                        foreach (String s in locked.Keys)
                        {
                            locked[s].Close();
                        }
                    }

                    TestContext.WriteLine("  ...");
                    System.Threading.Thread.Sleep(320);
                }
            }
        }
        public void Create_ZipErrorAction_RetryAndEventuallyThrow()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Create_ZipErrorAction_RetryAndEventuallyThrow.zip");
            Directory.SetCurrentDirectory(TopLevelDir);
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip);
            int n = _rnd.Next(files.Length);

            TestContext.WriteLine("Locking file {0}...", files[n]);
            using (Stream lockStream = new FileStream(files[n], FileMode.Open, FileAccess.Read, FileShare.None))
            {
                _retryCount = 0;
                using (var zip = new ZipFile())
                {
                    zip.ZipErrorAction = ZipErrorAction.InvokeErrorEvent;
                    zip.ZipError += ErrorHandler_RetryAndEventuallyThrow;
                    zip.AddFiles(files, "fodder");
                    zip.Save(zipFileToCreate);
                }
            }
        }
        public void _Internal_DuplicateNames_DifferentFolders_wi8982(bool flat)
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            TestUtilities.GenerateFilesFlat(dirToZip, 3);
            string subdir = Path.Combine(dirToZip, "subdir1");
            TestUtilities.GenerateFilesFlat(subdir, 2);

            for (int i = 0; i < 2; i++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Create_DuplicateNames_DifferentFolders.{0}.zip", i));

                using (var zip = new ZipFile())
                {
                    zip.ZipErrorAction = ZipErrorAction.Throw;
                    if (i == 0)
                        zip.AddDirectory(dirToZip, "fodder");
                    else
                    {
                        var files = Directory.GetFiles(dirToZip, "*.*", SearchOption.AllDirectories);
                        if (flat)
                            zip.AddFiles(files, "fodder");
                        else
                            zip.AddFiles(files, true, "fodder");

                    }

                    zip.Save(zipFileToCreate);
                }

                BasicVerifyZip(zipFileToCreate);

                Assert.AreEqual<int>(5, TestUtilities.CountEntries(zipFileToCreate),
                                     "Trial {0}: The zip file created has the wrong number of entries.", i);
            }
        }
        public void Bzip2_Perf()
        {
            // Verify that the parallel compress option works properly
            // with BZip2.
            TestContext.WriteLine("Creating the fodder files...");

            _txrx = TestUtilities.StartProgressMonitor("BZip2PerfTest",
                                                       "BZip2 Performance Test",
                                                       "Creating files");
            var update = new Action<Int32,Int32,Int64>((op,ix,sz) => {
                    switch(op)
                    {
                        case 0:
                        _txrx.Send("pb 1 max " + sz);
                        _txrx.Send("status Creating file " + ix);
                        break;
                        case 1:
                        _txrx.Send("pb 1 value " + sz);
                        break;
                        case 2:
                        _txrx.Send("pb 0 step");
                        _txrx.Send("pb 1 value 0");
                        break;
                    }
            });
            _txrx.Send("bars 2");
            int threshold = 1024 * 1024;
            int n = _rnd.Next(3) + 3;
            int minSize = 0x2000000 + this._rnd.Next(0x4000000);
            int maxSize = 0x2000000 + minSize + this._rnd.Next(0x80000);
            string dirInZip = "files";
            string extractDir = "extract";
            string subdir = dirInZip;
            _txrx.Send("pb 0 max " + n);

            var filesToZip = TestUtilities.GenerateFilesFlat(subdir, n,
                                                             minSize, maxSize, update);
            var fi = new FileInfo(filesToZip[_rnd.Next(filesToZip.Length)]);
            Assert.IsTrue(fi.Length > threshold,
                          "For file {1}, length ({0}) does not meet threshold",
                          fi.Name, fi.Length);

            // Get the unzip.exe tool:
            string dnzDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                dnzDir = Path.GetDirectoryName(dnzDir);
            string unzip = Path.Combine(dnzDir, "Tools\\Unzip\\bin\\debug\\Unzip.exe");
            Assert.IsTrue(File.Exists(unzip),
                          "The unzip.exe tool is not available.");

            _txrx.Send("pb 0 max " + (4*2));
            _txrx.Send("status done creating files...");
            // two passes: once for regular, once for parallel compress
            var ts = new TimeSpan[2];
            var fileSize = new Int64[2];
            for (int k=0; k < 2; k++)
            {
                System.Threading.Thread.Sleep(1200);
                var msg = string.Format("test BZip2 perf check, cycle {0}/2 (est. time: 22 mins)",k+1);
                _txrx.Send(msg);
                string zipFileToCreate = "BZip2_Perf."+k+".zip";
                TestContext.WriteLine("pass {0}, Creating the zip...", k);
                var stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();

                // Now, Create the zip archive with DotNetZip
                _cancelIndex = -1;
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.ParallelDeflateThreshold = (k==0)
                        ? -1 : threshold;
                    zip1.CompressionMethod = CompressionMethod.BZip2;
                    zip1.AddFiles(filesToZip, dirInZip);
                    zip1.SaveProgress += SaveProgress;
                    zip1.Save(zipFileToCreate);
                }
                stopwatch.Stop();
                ts[k] = stopwatch.Elapsed;
                fi = new FileInfo(zipFileToCreate);
                fileSize[k] = fi.Length;
                TestContext.WriteLine("size of resulting zip: {0}k",
                                      fileSize[k] / 1024);

                _txrx.Send("pb 0 step");

                _txrx.Send("status verifying the number of files");
                // Verify the number of files in the zip
                TestContext.WriteLine("Verifying the number of files in the zip...");
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                     filesToZip.Length,
                                     "Incorrect number of entries in the zip file.");

                _txrx.Send("pb 0 step");
                // examine and unpack the zip archive via DNZ tools.
                // Get info on the zip file:
                string unzipOut = this.Exec(unzip, "-i " + zipFileToCreate);

                // Verify that the output states that the compression method
                // used for each entry was BZIP2...
                _txrx.Send("status checking for BZIP compression...");
                TestContext.WriteLine("Verifying that BZIP2 was used...");
                Assert.AreEqual<int>
                    (TestUtilities.CountOccurrences(unzipOut, "Compression: BZip2"), n);

                _txrx.Send("pb 0 step");

                _txrx.Send("status Extracting via infozip unzip.exe...");
                // Extract the zip.  eg, unzip.exe test.zip -d  <extractdir>
                TestContext.WriteLine("Extracting via unzip.exe...");
                this.Exec(unzip, zipFileToCreate + " -d " + extractDir);

                // Verify the count of extracted files
                int fileCount = Directory.GetFiles(Path.Combine(extractDir,dirInZip)).Length;
                Assert.IsTrue(fileCount == n,
                              "Not all files were extracted? (found {0}, expected {1})",
                              fileCount, n);
                Directory.Delete(extractDir, true);

                _txrx.Send("pb 0 step");
            }

            var delta = (ts[0].TotalSeconds - ts[1].TotalSeconds) /
                (0.01 * ts[0].TotalSeconds);
            TestContext.WriteLine("Parallel compression reduced compression time by {0:N1}%",
                                  delta);

            // verify the time required for parallel compression is lower.
            Assert.IsTrue(ts[1] < ts[0],
                          "Parallel compression took MORE time.");

            delta = Math.Abs((int)(fileSize[1]-fileSize[0])) /
                (0.01 * fileSize[0]);

            Assert.IsTrue(delta < 5.0,
                          "Parallel compression is not within 5% of normal filesize.");
            TestContext.WriteLine("A-ok");
        }
        public void WZA_InMemory_wi8493a()
        {
            if (!WinZipIsPresent)
                throw new Exception("no winzip! [WZA_InMemory_wi8493a]");

            string zipFileToCreate = "WZA_InMemory_wi8493a.zip";
            string password = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            string[] TextFiles = new string[25 + _rnd.Next(8)];
            for (int i = 0; i < TextFiles.Length; i++)
            {
                TextFiles[i] = Path.Combine(TopLevelDir, String.Format("TextFile{0}.txt", i));
                TestUtilities.CreateAndFillFileText(TextFiles[i], _rnd.Next(14000) + 13000);
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (var zip = new ZipFile())
                {
                    zip.Password = password;
                    zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                    zip.AddEntry("Readme.txt", "Hello, World! ABC ABC ABC ABC ABCDE ABC ABCDEF ABC ABCD");
                    zip.AddFiles(TextFiles, "files");
                    zip.Save(ms);
                }
                File.WriteAllBytes(zipFileToCreate,ms.ToArray());

                BasicVerifyZip(zipFileToCreate, password);
            }
        }
        public void Update_MultipleSaves_wi10694()
        {
            string zipFileToCreate = "Update_MultipleSaves_wi10694.zip";
            var shortDir = "fodder";
            string subdir = Path.Combine(TopLevelDir, shortDir);
            string[] filesToZip = TestUtilities.GenerateFilesFlat(subdir);

            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, "Download");
                zip1.AddFiles(filesToZip, "other");
                zip1.Save(zipFileToCreate);
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), 2 * filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            using (var zip2 = ZipFile.Read(zipFileToCreate))
            {
                var entries = zip2.Entries.Where(e => e.FileName.Contains("Download")).ToArray();
                //PART1 - Add directory and save
                zip2.AddDirectoryByName("XX");
                zip2.Save();

                //PART2 - Rename paths (not related to XX directory from above) and save
                foreach (var zipEntry in entries)
                {
                    zipEntry.FileName = zipEntry.FileName.Replace("Download", "Download2");
                }
                zip2.Save();
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), 2 * filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");
        }
        public void ParallelDeflateStream_Create_CompareSpeeds()
        {
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip, _rnd.Next(5) + 5, 2048 * 1024 + _rnd.Next(200000));

            var ts = new TimeSpan[2];

            // 2 sets of 2 cycles: first set is warmup, 2nd is timed.
            // Actually they're both timed but times for the 2nd set
            // overwrite the times for the 1st set.
            // Within a set, the first run is non-parallel, 2nd is timed parallel.
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("ParallelDeflateStream_Create.{0}.{1}.zip", i, j));

                    var sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    using (var zip = new ZipFile())
                    {
                        if (j == 0)
                            zip.ParallelDeflateThreshold = -1L; // disable parallel deflate
                        else
                            zip.ParallelDeflateThreshold = 128 * 1024;  // threshold for parallel deflating

                        zip.AddFiles(files, "fodder");

                        zip.Save(zipFileToCreate);
                    }
                    sw.Stop();

                    BasicVerifyZip(zipFileToCreate);

                    Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                         "The zip file created has the wrong number of entries.");
                    ts[j] = sw.Elapsed;
                    TestContext.WriteLine("Cycle {0},{1}, Timespan: {2}", i, j, ts[j]);
                }
            }
            Assert.IsTrue(ts[1] < ts[0], "Parallel deflating is NOT faster than single-threaded, for large files.");
        }
        public void UpdateZip_RemoveEntry_ByFilename_WithPassword()
        {
            string password = "******";
            string filename = null;
            int entriesToBeAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = "ByFilename_WithPassword.zip";
            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create a bunch of files, fill them with content
            int numFilesToCreate = _rnd.Next(13) + 24;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = String.Format("file{0:D3}.txt", j);
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                 filename);
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                entriesToBeAdded++;
            }

            // Add the files to the zip, save the zip
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                zip1.Password = password;
                zip1.AddFiles(filenames, "");

                zip1.Comment = "UpdateTests::UpdateZip_RemoveEntry_ByFilename_WithPassword(): This archive will be updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesToBeAdded,
                "The Zip file has the wrong number of entries.");


            // selectively remove a few files in the zip archive
            var filesToRemove = new List<string>();
            int numToRemove = _rnd.Next(numFilesToCreate - 4) + 1;
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                for (j = 0; j < numToRemove; j++)
                {
                    // select a new, uniquely named file to create
                    do
                    {
                        filename = String.Format("file{0:D3}.txt", _rnd.Next(numFilesToCreate));
                    } while (filesToRemove.Contains(filename));
                    // add this file to the list
                    filesToRemove.Add(filename);
                    zip2.RemoveEntry(filename);
                }

                zip2.Comment = "This archive has been modified. Some files have been removed.";
                zip2.Save();
            }


            // extract all files, verify none should have been removed,
            // and verify the contents of those that remain
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s1 in zip3.EntryFileNames)
                {
                    Assert.IsFalse(filesToRemove.Contains(s1), String.Format("File ({0}) was not expected.", s1));

                    zip3[s1].ExtractWithPassword("extract", password);
                    repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                     s1);

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s1));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(repeatedLine, sLine,
                                String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));

                }
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesToBeAdded - filesToRemove.Count,
                "The updated Zip file has the wrong number of entries.");
        }
        public void ParallelDeflateStream_Create_InvalidThreshold()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "ParallelDeflateStream_Create_InvalidThreshold.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip, _rnd.Next(5) + 5, 128 * 1024 + _rnd.Next(20000));

            using (var zip = new ZipFile())
            {
                zip.ParallelDeflateThreshold = 17129;
                zip.AddFiles(files, "fodder");
                zip.Save(zipFileToCreate);
            }

            // not reached
        }
        public void Progress_ReadFile()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string  zipFileToCreate = Path.Combine(TopLevelDir, "Progress_ReadFile.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            using (ZipFile zip = new ZipFile())
            {
                zip.AddFiles(files);
                zip.Save(zipFileToCreate);
            }

            int count = TestUtilities.CountEntries(zipFileToCreate);
            Assert.IsTrue(count>0);

            var options = new ReadOptions {
                    StatusMessageWriter = new StringWriter(),
                    ReadProgress = ReadProgress1
            };
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                // this should be fine
                zip.RemoveEntry(zip[1]);
                zip.Save();
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());
            Assert.AreEqual<Int32>(count, TestUtilities.CountEntries(zipFileToCreate)+1);
        }
        public void ContainsEntryTest()
        {
            string zipFileToCreate = "ContainsEntry.zip";
            string dirToZip = "dirToZip";
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            using (var zip = new ZipFile())
            {
                zip.AddFiles(files);
                zip.Save(zipFileToCreate);
            }

            Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate));
            using (var zip2 = ZipFile.Read(zipFileToCreate))
            {
                for (int i=0; i < 28; i++)
                {
                    int n = _rnd.Next(files.Length);
                    TestContext.WriteLine("Checking {0}", files[n]);
                    Assert.IsTrue(zip2.ContainsEntry(files[n]), "missing entry");
                }
            }
        }
        public void SilentDeletion_wi10639()
        {
            string zipFileToCreate = "SilentDeletion.zip";
            string dirToZip = "dirToZip";
            string extractDir = "extracted";
            string password = TestUtilities.GenerateRandomPassword();
            string wrongPassword = "******";
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            TestContext.WriteLine("Creating the zip.");
            using (var zip = new ZipFile())
            {
                zip.Password = password;
                zip.AddFiles(files, dirToZip);
                zip.Save(zipFileToCreate);
            }

            TestContext.WriteLine("Extract one file with wrong password.");

             // pick a random entry to extract
            int ix = -1;
            string extractedFile = null;
            // perform two passes: first with correct password to extract the
            // file.  2nd with incorrect password to see if the file is
            // deleted.

            Directory.CreateDirectory(extractDir);
            for (int i=0; i < 2; i++)
            {
                try
                {
                    using (var zip = ZipFile.Read(zipFileToCreate))
                    {
                        if (i==0)
                        {
                            do
                            {
                                ix = this._rnd.Next(zip.Entries.Count);
                            }
                            while (zip[ix].IsDirectory);
                            TestContext.WriteLine("Selected entry: {0}", zip[ix].FileName);
                            extractedFile = Path.Combine(extractDir, zip[ix].FileName.Replace("/","\\"));
                            TestContext.WriteLine("name for extracted file: {0}", extractedFile);
                            Assert.IsFalse(File.Exists(extractedFile), "The file exists.");
                        }
                        TestContext.WriteLine("Cycle {0}: ExtractWithPassword()", i);
                        zip[ix].ExtractWithPassword(extractDir,
                                                    ExtractExistingFileAction.OverwriteSilently,
                                                    (i==0)? password : wrongPassword);
                    }
                }
                catch (Ionic.Zip.BadPasswordException bpe1)
                {
                    // only swallow exceptions on the first go-round
                    if (i==0) throw;
                }
                Assert.IsTrue(File.Exists(extractedFile), "Cycle {0}: The extracted file does not exist.", i);
            }
        }
        private static void _DotNetZip_CreateZip(List<string> filesToZip,
                                                 EncryptionAlgorithm encryption,
                                                 string password,
                                                 string comment,
                                                 string zipFileToCreate,
                                                 bool nonSeekable)
        {
            // Want to test the library when saving to non-seekable output streams.  Like
            // stdout or ASPNET's Response.OutputStream.  This simulates it.
            if (nonSeekable)
            {
                using (var outStream = new Alienlab.Zip.Tests.NonSeekableOutputStream(File.Create(zipFileToCreate)))
                {
                    using (ZipFile zip1 = new ZipFile())
                    {
                        zip1.Encryption = encryption;
                        if (zip1.Encryption != EncryptionAlgorithm.None)
                            zip1.Password = password;

                        zip1.AddFiles(filesToZip, "");
                        zip1.Comment = comment;
                        zip1.Save(outStream);
                    }
                }
            }
            else
            {
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.Encryption = encryption;
                    if (zip1.Encryption != EncryptionAlgorithm.None)
                        zip1.Password = password;

                    zip1.AddFiles(filesToZip, "");
                    zip1.Comment = comment;
                    zip1.Save(zipFileToCreate);
                }
            }
        }