Example #1
0
        public void GNUAsFile()
        {
            List<ITarHeader> list = new List<ITarHeader>();
            var gnuFile = WriteToTempFile(gnuStream);
            TarReader reader = new TarReader(gnuFile);
            while (reader.MoveNext(true))
            {
                list.Add(reader.FileInfo);
                Trace.WriteLine($"{reader.FileInfo.EntryType}: {reader.FileInfo.FileName}");
            }

            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/"));
            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/world/"));
            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/world/hello"));
        }
Example #2
0
        public void Add_Empty_GlobalExtendedAttributes()
        {
            using MemoryStream archive = new MemoryStream();

            using (TarWriter writer = new TarWriter(archive, leaveOpen: true))
            {
                PaxGlobalExtendedAttributesTarEntry gea = new PaxGlobalExtendedAttributesTarEntry(new Dictionary <string, string>());
                writer.WriteEntry(gea);
            }

            archive.Seek(0, SeekOrigin.Begin);
            using (TarReader reader = new TarReader(archive))
            {
                PaxGlobalExtendedAttributesTarEntry gea = reader.GetNextEntry() as PaxGlobalExtendedAttributesTarEntry;
                Assert.NotNull(gea);
                Assert.Equal(TarEntryFormat.Pax, gea.Format);
                Assert.Equal(TarEntryType.GlobalExtendedAttributes, gea.EntryType);

                Assert.Equal(0, gea.GlobalExtendedAttributes.Count);

                Assert.Null(reader.GetNextEntry());
            }
        }
        protected void Read_Archive_Folder_File_Utf8_Internal(TarEntryFormat format, TestTarFormat testFormat)
        {
            string testCaseName = "folder_file_utf8";

            using MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName);

            using TarReader reader = new TarReader(ms);

            if (testFormat is TestTarFormat.pax_gea)
            {
                VerifyGlobalExtendedAttributes(reader);
            }

            TarEntry directory = reader.GetNextEntry();

            VerifyDirectoryEntry(directory, format, "f\u00f6ld\u00ebr/"); //földër

            TarEntry file = reader.GetNextEntry();

            VerifyRegularFileEntry(file, format, "f\u00f6ld\u00ebr/\u00e1\u00f6\u00f1.txt", $"Hello {testCaseName}"); // földër/áöñ.txt

            Assert.Null(reader.GetNextEntry());
        }
        public void Add_Directory(TarEntryFormat format, bool withContents)
        {
            using TempDirectory root = new TempDirectory();
            string dirName = "dir";
            string dirPath = Path.Join(root.Path, dirName);

            Directory.CreateDirectory(dirPath);

            if (withContents)
            {
                // Add a file inside the directory, we need to ensure the contents
                // of the directory are ignored when using AddFile
                File.Create(Path.Join(dirPath, "file.txt")).Dispose();
            }

            using MemoryStream archive = new MemoryStream();
            using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true))
            {
                writer.WriteEntry(fileName: dirPath, entryName: dirName);
            }

            archive.Seek(0, SeekOrigin.Begin);
            using (TarReader reader = new TarReader(archive))
            {
                TarEntry entry = reader.GetNextEntry();
                Assert.Equal(format, entry.Format);

                Assert.NotNull(entry);
                Assert.Equal(dirName, entry.Name);
                Assert.Equal(TarEntryType.Directory, entry.EntryType);
                Assert.Null(entry.DataStream);

                VerifyPlatformSpecificMetadata(dirPath, entry);

                Assert.Null(reader.GetNextEntry()); // If the dir had contents, they should've been excluded
            }
        }
        public void BlockAlignmentPadding_DoesNotAffectNextEntries(int contentSize, bool copyData)
        {
            byte[] fileContents = new byte[contentSize];
            Array.Fill <byte>(fileContents, 0x1);

            using var archive = new MemoryStream();
            using (var writer = new TarWriter(archive, leaveOpen: true))
            {
                var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file");
                entry1.DataStream = new MemoryStream(fileContents);
                writer.WriteEntry(entry1);

                var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file");
                writer.WriteEntry(entry2);
            }

            archive.Position     = 0;
            using var unseekable = new WrappedStream(archive, archive.CanRead, archive.CanWrite, canSeek: false);
            using var reader     = new TarReader(unseekable);

            TarEntry e = reader.GetNextEntry(copyData);

            Assert.Equal(contentSize, e.Length);

            byte[] buffer = new byte[contentSize];
            while (e.DataStream.Read(buffer) > 0)
            {
                ;
            }
            AssertExtensions.SequenceEqual(fileContents, buffer);

            e = reader.GetNextEntry(copyData);
            Assert.Equal(0, e.Length);

            e = reader.GetNextEntry(copyData);
            Assert.Null(e);
        }
Example #6
0
        protected async Task Read_Archive_File_LongSymbolicLink_Async_Internal(TarEntryFormat format, TestTarFormat testFormat)
        {
            string testCaseName = "file_longsymlink";

            await using (MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName))
            {
                await using (TarReader reader = new TarReader(ms))
                {
                    if (testFormat is TestTarFormat.pax_gea)
                    {
                        TarEntry entry = await reader.GetNextEntryAsync();

                        VerifyGlobalExtendedAttributes(entry);
                    }

                    TarEntry directory = await reader.GetNextEntryAsync();

                    VerifyDirectoryEntry(directory, format,
                                         "000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555/");

                    TarEntry file = await reader.GetNextEntryAsync();

                    VerifyRegularFileEntry(file, format,
                                           "000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555/00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999000000000011111111112222222222333333333344444444445.txt",
                                           $"Hello {testCaseName}");

                    TarEntry symbolicLink = await reader.GetNextEntryAsync();

                    VerifySymbolicLinkEntry(symbolicLink, format,
                                            "link.txt",
                                            "000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555/00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999000000000011111111112222222222333333333344444444445.txt");

                    Assert.Null(await reader.GetNextEntryAsync());
                }
            }
        }
        protected void Read_Archive_File_HardLink_Internal(TarEntryFormat format, TestTarFormat testFormat)
        {
            string testCaseName = "file_hardlink";

            using MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName);

            using TarReader reader = new TarReader(ms);

            if (testFormat is TestTarFormat.pax_gea)
            {
                VerifyGlobalExtendedAttributes(reader);
            }

            TarEntry file = reader.GetNextEntry();

            VerifyRegularFileEntry(file, format, "file.txt", $"Hello {testCaseName}");

            TarEntry hardLink = reader.GetNextEntry();

            // The 'tar' tool detects hardlinks as regular files and saves them as such in the archives, for all formats
            VerifyRegularFileEntry(hardLink, format, "hardlink.txt", $"Hello {testCaseName}");

            Assert.Null(reader.GetNextEntry());
        }
Example #8
0
        public async Task ExtractEntriesWithSlashDotPrefix_Async()
        {
            using (TempDirectory root = new TempDirectory())
                await using (MemoryStream archiveStream = GetStrangeTarMemoryStream("prefixDotSlashAndCurrentFolderEntry"))
                    await using (TarReader reader = new TarReader(archiveStream, leaveOpen: false))
                    {
                        string   rootPath = Path.TrimEndingDirectorySeparator(root.Path);
                        TarEntry entry;
                        while ((entry = await reader.GetNextEntryAsync()) != null)
                        {
                            Assert.NotNull(entry);
                            Assert.StartsWith("./", entry.Name);
                            // Normalize the path (remove redundant segments), remove trailing separators
                            // this is so the first entry can be skipped if it's the same as the root directory
                            string entryPath = Path.TrimEndingDirectorySeparator(Path.GetFullPath(Path.Join(rootPath, entry.Name)));
                            if (entryPath != rootPath)
                            {
                                await entry.ExtractToFileAsync(entryPath, overwrite : true);

                                Assert.True(Path.Exists(entryPath), $"Entry was not extracted: {entryPath}");
                            }
                        }
                    }
        }
Example #9
0
        public static IReader Open(Stream stream, Options options = 1)
        {
            stream.CheckNotNull("stream");
            RewindableStream stream2 = new RewindableStream(stream);

            stream2.StartRecording();
            stream2.Rewind(false);
            if (BZip2Stream.IsBZip2(stream2))
            {
                stream2.Rewind(false);
                if (TarArchive.IsTarFile(new BZip2Stream(stream2, CompressionMode.Decompress, false, false)))
                {
                    stream2.Rewind(true);
                    return(new TarReader(stream2, CompressionType.BZip2, options));
                }
            }
            stream2.Rewind(false);
            if (!TarArchive.IsTarFile(stream2))
            {
                throw new InvalidOperationException("Cannot determine compressed stream type.");
            }
            stream2.Rewind(true);
            return(TarReader.Open(stream2, options));
        }
Example #10
0
        public async Task WritePaxAttributes_Timestamps_AutomaticallyAdded_Async()
        {
            DateTimeOffset minimumTime = DateTimeOffset.UtcNow - TimeSpan.FromHours(1);

            await using (MemoryStream archiveStream = new MemoryStream())
            {
                await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
                {
                    PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
                    await writer.WriteEntryAsync(regularFile);
                }

                archiveStream.Position = 0;
                await using (TarReader reader = new TarReader(archiveStream))
                {
                    PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry;

                    AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 4);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaMTime, minimumTime);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaATime, minimumTime);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaCTime, minimumTime);
                }
            }
        }
Example #11
0
        public async Task Create_Works_Async()
        {
            var disk = new DeveloperDisk()
            {
                Image     = new MemoryStream(Encoding.UTF8.GetBytes("Hello, world!")),
                Signature = new byte[] { 1, 2, 3, 4 },
                Version   = new SystemVersion()
                {
                    BuildID             = new Guid("5abf1921-e3e3-4bfc-94c5-6c6805f23815"),
                    ProductBuildVersion = new AppleVersion(1, 'A', 1),
                    ProductCopyright    = "Quamotion bv",
                    ProductName         = "Kaponata",
                    ProductVersion      = new Version(1, 0),
                },
                CreationTime = new DateTimeOffset(2000, 1, 1, 0, 0, 0, 0, TimeSpan.Zero),
            };

            var factory = new DeveloperDiskRegistryImageFactory();

            (var manifest, var configStream, var layerStream) = await factory.CreateRegistryImageAsync(disk, default).ConfigureAwait(false);

            Assert.NotNull(manifest);
            Assert.NotNull(configStream);
            Assert.Equal(0, configStream.Position);
            Assert.NotEqual(0, configStream.Length);

            Assert.NotNull(layerStream);
            Assert.Equal(0, layerStream.Position);
            Assert.NotEqual(0, layerStream.Length);

            var config = await JsonSerializer.DeserializeAsync <Image>(configStream, default).ConfigureAwait(false);

            // The RootFS is a Tar archive which contains the developer disk image, signature and a copy of the SystemVersion.plist file
            var reader = new TarReader(layerStream);

            (TarHeader? header, Stream entryStream) = await reader.ReadAsync(default).ConfigureAwait(false);
        public void Add_PaxGlobalExtendedAttributes_NoEntries(bool withAttributes)
        {
            using MemoryStream archive = new MemoryStream();

            Dictionary <string, string> globalExtendedAttributes = new Dictionary <string, string>();

            if (withAttributes)
            {
                globalExtendedAttributes.Add("hello", "world");
            }

            using (TarWriter writer = new TarWriter(archive, globalExtendedAttributes, leaveOpen: true))
            {
            } // Dispose with no entries

            archive.Seek(0, SeekOrigin.Begin);
            using (TarReader reader = new TarReader(archive))
            {
                // Unknown until reading first entry
                Assert.Equal(TarEntryFormat.Unknown, reader.Format);
                Assert.Null(reader.GlobalExtendedAttributes);

                Assert.Null(reader.GetNextEntry());

                Assert.Equal(TarEntryFormat.Pax, reader.Format);
                Assert.NotNull(reader.GlobalExtendedAttributes);

                int expectedCount = withAttributes ? 1 : 0;
                Assert.Equal(expectedCount, reader.GlobalExtendedAttributes.Count);

                if (expectedCount > 0)
                {
                    Assert.Equal("world", reader.GlobalExtendedAttributes["hello"]);
                }
            }
        }
        public void Read_Archive_File_SymbolicLink(TarFormat format, TestTarFormat testFormat)
        {
            string testCaseName = "file_symlink";

            using MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName);

            using TarReader reader = new TarReader(ms);

            if (testFormat == TestTarFormat.pax_gea)
            {
                // The GEA are collected after reading the first entry, not on the constructor
                Assert.Null(reader.GlobalExtendedAttributes);
            }

            // Format is determined after reading the first entry, not on the constructor
            Assert.Equal(TarFormat.Unknown, reader.Format);
            TarEntry file = reader.GetNextEntry();

            Assert.Equal(format, reader.Format);
            if (testFormat == TestTarFormat.pax_gea)
            {
                Assert.NotNull(reader.GlobalExtendedAttributes);
                Assert.True(reader.GlobalExtendedAttributes.Any());
                Assert.Contains(AssetPaxGeaKey, reader.GlobalExtendedAttributes);
                Assert.Equal(AssetPaxGeaValue, reader.GlobalExtendedAttributes[AssetPaxGeaKey]);
            }


            Verify_Archive_RegularFile(file, format, reader.GlobalExtendedAttributes, "file.txt", $"Hello {testCaseName}");

            TarEntry symbolicLink = reader.GetNextEntry();

            Verify_Archive_SymbolicLink(symbolicLink, reader.GlobalExtendedAttributes, "link.txt", "file.txt");

            Assert.Null(reader.GetNextEntry());
        }
Example #14
0
        private static void Main(string[] args)
        {
            var parser     = new ParameterParser <ConsoleParameters>();
            var parameters = parser.Parse(args);

            Console.WriteLine("SanteDB Secure Clinical Backup Extractor");
            Console.WriteLine("Version {0}", Assembly.GetEntryAssembly().GetName().Version);
            Console.WriteLine(Assembly.GetEntryAssembly().GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright);

            if (parameters.Help || args.Length == 0)
            {
                parser.WriteHelp(Console.Out);
            }
            else
            {
                using (var fs = File.OpenRead(parameters.Source))
                {
                    // Validate header
                    byte[] header = new byte[MAGIC.Length];
                    fs.Read(header, 0, MAGIC.Length);
                    if (!header.SequenceEqual(MAGIC))
                    {
                        throw new InvalidOperationException("Backup file is invalid");
                    }

                    Stream inStream = fs;
                    try
                    {
                        // Encrypted?
                        if (fs.ReadByte() == 1)
                        {
                            // Read length of IV
                            byte[] ivLengthByte = new byte[4];
                            fs.Read(ivLengthByte, 0, 4);
                            var ivLength = BitConverter.ToInt32(ivLengthByte, 0);

                            // Read IV
                            byte[] iv = new byte[ivLength];
                            fs.Read(iv, 0, ivLength);

                            // Now Create crypto stream with password
                            var password = PasswordPrompt("Archive Password:"******"Extracting : {0}", tr.Entry.Key);
                                    var destDir = Path.Combine(parameters.Destination, tr.Entry.Key.Replace('/', Path.DirectorySeparatorChar));
                                    if (!Directory.Exists(Path.GetDirectoryName(destDir)))
                                    {
                                        Directory.CreateDirectory(Path.GetDirectoryName(destDir));
                                    }
                                    if (!tr.Entry.IsDirectory)
                                    {
                                        using (var s = tr.OpenEntryStream())
                                            using (var ofs = File.Create(Path.Combine(parameters.Destination, tr.Entry.Key)))
                                                s.CopyTo(ofs);
                                    }
                                }
                            }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Could not extract backup: {0}", e);
                    }
                }
            }
        }
Example #15
0
 // Constructor used when reading an existing archive.
 internal PosixTarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin)
 {
 }
 public async Task GarbageEntryChecksumZeroReturnNullAsync()
 {
     await using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, "golang_tar", "issue12435");
     await using TarReader reader           = new TarReader(archiveStream);
     Assert.Null(await reader.GetNextEntryAsync());
 }
 [InlineData("writer-big")]     // The size field contains an euro char
 public async Task Throw_ArchivesWithRandomCharsAsync(string testCaseName)
 {
     await using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, "golang_tar", testCaseName);
     await using TarReader reader           = new TarReader(archiveStream);
     await Assert.ThrowsAsync <FormatException>(async() => await reader.GetNextEntryAsync());
 }
 public async Task Throw_SingleExtendedAttributesEntryWithNoActualEntryAsync()
 {
     await using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, "golang_tar", "pax-path-hdr");
     await using TarReader reader           = new TarReader(archiveStream);
     await Assert.ThrowsAsync <EndOfStreamException>(async() => await reader.GetNextEntryAsync());
 }
Example #19
0
        /// <summary>
        /// Opens a Reader for Non-seeking usage
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static IReader Open(Stream stream, Options options = Options.KeepStreamsOpen)
        {
            stream.CheckNotNull("stream");

            RewindableStream rewindableStream = new RewindableStream(stream);

            rewindableStream.StartRecording();
            if (ZipArchive.IsZipFile(rewindableStream, null))
            {
                rewindableStream.Rewind(true);
                return(ZipReader.Open(rewindableStream, null, options));
            }
#if GZIP
            rewindableStream.Rewind(false);
            if (GZipArchive.IsGZipFile(rewindableStream))
            {
                rewindableStream.Rewind(false);
                GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, CompressionType.GZip, options));
                }
                rewindableStream.Rewind(true);
                return(GZipReader.Open(rewindableStream, options));
            }
#endif

#if BZIP2
            rewindableStream.Rewind(false);
            if (BZip2Stream.IsBZip2(rewindableStream))
            {
                rewindableStream.Rewind(false);
                BZip2Stream testStream = new BZip2Stream(rewindableStream, CompressionMode.Decompress, false);
#if TAR
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, CompressionType.BZip2, options));
                }
#endif
            }
#endif

#if TAR
            rewindableStream.Rewind(false);
            if (TarArchive.IsTarFile(rewindableStream))
            {
                rewindableStream.Rewind(true);
                return(TarReader.Open(rewindableStream, options));
            }
#endif
#if RAR
            rewindableStream.Rewind(false);
            if (RarArchive.IsRarFile(rewindableStream, options))
            {
                rewindableStream.Rewind(true);
                return(RarReader.Open(rewindableStream, options));
            }
#endif

            throw new InvalidOperationException("Cannot determine compressed stream type.  Supported Reader Formats: Zip, GZip, BZip2, Tar, Rar");
        }
Example #20
0
        public void VerifyIncludeBaseDirectory(bool includeBaseDirectory)
        {
            using TempDirectory source      = new TempDirectory();
            using TempDirectory destination = new TempDirectory();

            UnixFileMode baseDirectoryMode = TestPermission1;

            SetUnixFileMode(source.Path, baseDirectoryMode);

            string fileName1 = "file1.txt";
            string filePath1 = Path.Join(source.Path, fileName1);

            File.Create(filePath1).Dispose();
            UnixFileMode filename1Mode = TestPermission2;

            SetUnixFileMode(filePath1, filename1Mode);

            string subDirectoryName = "dir/"; // The trailing separator is preserved in the TarEntry.Name
            string subDirectoryPath = Path.Join(source.Path, subDirectoryName);

            Directory.CreateDirectory(subDirectoryPath);
            UnixFileMode subDirectoryMode = TestPermission3;

            SetUnixFileMode(subDirectoryPath, subDirectoryMode);

            string fileName2 = "file2.txt";
            string filePath2 = Path.Join(subDirectoryPath, fileName2);

            File.Create(filePath2).Dispose();
            UnixFileMode filename2Mode = TestPermission4;

            SetUnixFileMode(filePath2, filename2Mode);

            string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

            TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory);

            using FileStream fileStream = File.OpenRead(destinationArchiveFileName);
            using TarReader reader      = new TarReader(fileStream);

            List <TarEntry> entries = new List <TarEntry>();

            TarEntry entry;

            while ((entry = reader.GetNextEntry()) != null)
            {
                entries.Add(entry);
            }

            int expectedCount = 3 + (includeBaseDirectory ? 1 : 0);

            Assert.Equal(expectedCount, entries.Count);

            string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty;

            if (includeBaseDirectory)
            {
                TarEntry baseEntry = entries.FirstOrDefault(x =>
                                                            x.EntryType == TarEntryType.Directory &&
                                                            x.Name == prefix);
                Assert.NotNull(baseEntry);
                AssertEntryModeFromFileSystemEquals(baseEntry, baseDirectoryMode);
            }

            TarEntry entry1 = entries.FirstOrDefault(x =>
                                                     x.EntryType == TarEntryType.RegularFile &&
                                                     x.Name == prefix + fileName1);

            Assert.NotNull(entry1);
            AssertEntryModeFromFileSystemEquals(entry1, filename1Mode);

            TarEntry directory = entries.FirstOrDefault(x =>
                                                        x.EntryType == TarEntryType.Directory &&
                                                        x.Name == prefix + subDirectoryName);

            Assert.NotNull(directory);
            AssertEntryModeFromFileSystemEquals(directory, subDirectoryMode);

            string   actualFileName2 = subDirectoryName + fileName2; // Notice the trailing separator in subDirectoryName
            TarEntry entry2          = entries.FirstOrDefault(x =>
                                                              x.EntryType == TarEntryType.RegularFile &&
                                                              x.Name == prefix + actualFileName2);

            Assert.NotNull(entry2);
            AssertEntryModeFromFileSystemEquals(entry2, filename2Mode);
        }
Example #21
0
        public Hapi.Chart.Chart Serialize()
        {
            var chart = new Hapi.Chart.Chart();

            chart.Metadata = this.Metadata;

            this.stream.Seek(0, SeekOrigin.Begin);

            using (var gzipStream = new GZipStream(this.stream, CompressionMode.Decompress, leaveOpen: true))
                using (var reader = TarReader.Open(gzipStream, new ReaderOptions()
                {
                    LeaveStreamOpen = true
                }))
                {
                    while (reader.MoveToNextEntry())
                    {
                        if (this.IsTemplate(reader.Entry.Key))
                        {
                            using (Stream entryStream = reader.OpenEntryStream())
                            {
                                var template = new Hapi.Chart.Template()
                                {
                                    Data = ByteString.FromStream(entryStream),
                                    Name = Normalize(reader.Entry.Key).Substring(this.directoryName.Length + 1)
                                };

                                chart.Templates.Add(template);
                            }
                        }
                        else if (this.IsValues(reader.Entry.Key))
                        {
                            using (Stream entryStream = reader.OpenEntryStream())
                                using (StreamReader entryReader = new StreamReader(entryStream))
                                {
                                    chart.Values = new Hapi.Chart.Config()
                                    {
                                        Raw = entryReader.ReadToEnd()
                                    };
                                }
                        }
                        else if (!this.IsTemplate(reader.Entry.Key) &&
                                 !this.IsMetadata(reader.Entry.Key) &&
                                 !this.IsValues(reader.Entry.Key))
                        {
                            // TODO: respect .helmignore
                            using (Stream entryStream = reader.OpenEntryStream())
                            {
                                chart.Files.Add(new Any()
                                {
                                    TypeUrl = Normalize(reader.Entry.Key).Substring(this.directoryName.Length + 1),
                                    Value   = ByteString.FromStream(entryStream)
                                });
                            }
                        }
                    }
                }

            // Dependencies are currently not supported
            // chart.Dependencies.Add();
            return(chart);
        }
 public TarArchiveReadStream(TarReader tarReader, Action onClose)
 {
     _tarReader = tarReader;
     _onClose   = onClose;
 }
Example #23
0
 // Constructor called when reading a TarEntry from a TarReader.
 internal GnuTarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin, TarEntryFormat.Gnu)
 {
 }
        public static bool TryOpen(Stream stream, ReaderOptions options, ArchiveTypeMask archiveTypes, out IReader reader)
        {
            stream.CheckNotNull("stream");
            options = options ?? new ReaderOptions()
            {
                LeaveStreamOpen = false
            };
            RewindableStream rewindableStream = new RewindableStream(stream);

            rewindableStream.StartRecording();
            if (archiveTypes.HasFlag(ArchiveTypeMask.Zip) && ZipArchive.IsZipFile(rewindableStream, options.Password))
            {
                rewindableStream.Rewind(true);
                reader = ZipReader.Open(rewindableStream, options);
                return(true);
            }
            rewindableStream.Rewind(false);
            if (archiveTypes.HasFlag(ArchiveTypeMask.GZip) && GZipArchive.IsGZipFile(rewindableStream))
            {
                rewindableStream.Rewind(false);
                GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
                if (archiveTypes.HasFlag(ArchiveTypeMask.Tar) && TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    reader = new TarReader(rewindableStream, options, CompressionType.GZip);
                    return(true);
                }
                rewindableStream.Rewind(true);
                reader = GZipReader.Open(rewindableStream, options);
                return(true);
            }

            rewindableStream.Rewind(false);
            if (archiveTypes.HasFlag(ArchiveTypeMask.BZip2) && BZip2Stream.IsBZip2(rewindableStream))
            {
                rewindableStream.Rewind(false);
                BZip2Stream testStream = new BZip2Stream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress, false);
                if (archiveTypes.HasFlag(ArchiveTypeMask.Tar) && TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    reader = new TarReader(rewindableStream, options, CompressionType.BZip2);
                    return(true);
                }
            }

            rewindableStream.Rewind(false);
            if (archiveTypes.HasFlag(ArchiveTypeMask.LZip) && LZipStream.IsLZipFile(rewindableStream))
            {
                rewindableStream.Rewind(false);
                LZipStream testStream = new LZipStream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress);
                if (archiveTypes.HasFlag(ArchiveTypeMask.Tar) && TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    reader = new TarReader(rewindableStream, options, CompressionType.LZip);
                    return(true);
                }
            }
            rewindableStream.Rewind(false);
            if (archiveTypes.HasFlag(ArchiveTypeMask.Rar) && RarArchive.IsRarFile(rewindableStream, options))
            {
                rewindableStream.Rewind(true);
                reader = RarReader.Open(rewindableStream, options);
                return(true);
            }

            rewindableStream.Rewind(false);
            if (archiveTypes.HasFlag(ArchiveTypeMask.Tar) && TarArchive.IsTarFile(rewindableStream))
            {
                rewindableStream.Rewind(true);
                reader = TarReader.Open(rewindableStream, options);
                return(true);
            }
            rewindableStream.Rewind(false);
            if (XZStream.IsXZStream(rewindableStream))
            {
                rewindableStream.Rewind(true);
                XZStream testStream = new XZStream(rewindableStream);
                if (archiveTypes.HasFlag(ArchiveTypeMask.Tar) && TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    reader = new TarReader(rewindableStream, options, CompressionType.Xz);
                    return(true);
                }
            }
            reader = null;
            return(false);
        }
Example #25
0
 // Constructor used when reading an existing archive.
 internal UstarTarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin)
 {
 }
Example #26
0
        public SoundEffect(Stream inputStream, bool isOpus = false)
        {
            byte[] pcmData = null;

            if (isOpus)
            {
                using (var opusFile = new OggOpusFile(inputStream)) {
                    if (opusFile.LinkCount > 1)
                    {
                        throw new NotSupportedException("Opus files with multiple links are not supported.");
                    }

                    _md = new SfxMetadata()
                    {
                        Bits     = 16,
                        Rate     = 48000,
                        Channels = opusFile.GetChannelCount(),
                        Length   = (int)opusFile.GetPcmTotal(),
                    };

                    int valuesRead;
                    pcmData = new byte[sizeof(short) * _md.Channels * _md.Length];
                    short[] readBuffer = new short[5760 * 2];
                    using (var dataWriter = new BinaryWriter(new MemoryStream(pcmData))) {
                        while ((valuesRead = opusFile.Read(readBuffer, 0, readBuffer.Length) * _md.Channels) > 0)
                        {
                            for (int i = 0; i < valuesRead; i++)
                            {
                                dataWriter.Write(readBuffer[i]);
                            }
                        }
                    }
                }
            }
            else
            {
                using (var s = inputStream) {
                    var tr = new TarReader(s);
                    while (tr.MoveNext(false))
                    {
                        switch (tr.FileInfo.FileName)
                        {
                        case "sound.bin":
                            var bytes = new byte[tr.FileInfo.SizeInBytes];
                            using (var ms = new MemoryStream(bytes)) {
                                tr.Read(ms);
                                ms.Position = 0;
                                using (var br = new BinaryReader(ms)) {
                                    _md = SfxMetadata.Read(br);
                                }
                            }
                            break;

                        case "sound.pcm":
                            pcmData = new byte[tr.FileInfo.SizeInBytes];
                            tr.Read(new MemoryStream(pcmData));
                            break;

                        default:
                            throw new ContentException("Unrecognized sound file " + tr.FileInfo.FileName);
                        }
                    }
                }
            }

            ALFormat format;

            switch (_md.Channels)
            {
            case 1:
                switch (_md.Bits)
                {
                case 8:
                    format = ALFormat.Mono8;
                    break;

                case 16:
                    format = ALFormat.Mono16;
                    break;

                case 32:
                    format = ALFormat.MonoFloat32Ext;
                    break;

                default:
                    throw new NotSupportedException("Sounds must be 8, 16, or 32 bit.");
                }
                break;

            case 2:
                switch (_md.Bits)
                {
                case 8:
                    format = ALFormat.Stereo8;
                    break;

                case 16:
                    format = ALFormat.Stereo16;
                    break;

                case 32:
                    format = ALFormat.StereoFloat32Ext;
                    break;

                default:
                    throw new NotSupportedException("Sounds must be 8, 16, or 32 bit.");
                }
                break;

            default:
                throw new NotSupportedException("Sound effects must be mono or stereo.");
            }

            _buffer = AL.GenBuffer();
            AL.BufferData(_buffer, format, pcmData, pcmData.Length, _md.Rate);
        }
Example #27
0
 // Constructor called when reading a TarEntry from a TarReader.
 internal V7TarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin, TarEntryFormat.V7)
 {
 }
Example #28
0
        void Initialize(Stream stream, Shader shader = null)
        {
            ThreadContext.Current.EnsureGLContext();

            if (shader == null)
            {
                shader = new SpriteShader();
            }

            int filterMode = 0;
            var defs       = new Dictionary <string, SpriteDefinition>();

            var tr = new TarReader(stream);

            while (tr.MoveNext(false))
            {
                switch (tr.FileInfo.FileName)
                {
                case "atlas.bin":
                    using (var atlasStream = new MemoryStream()) {
                        tr.Read(atlasStream);
                        atlasStream.Position = 0;
                        using (var br = new BinaryReader(atlasStream)) {
                            filterMode = br.ReadInt32();
                            for (var count = br.ReadInt32(); count > 0; --count)
                            {
                                var key   = br.ReadString();
                                var value = SpriteDefinition.Read(br);
                                defs.Add(key, value);
                            }
                        }
                    }
                    break;

                case "sheet.png":
                    using (var sheetStream = new MemoryStream((int)tr.FileInfo.SizeInBytes)) {
                        tr.Read(sheetStream);
                        sheetStream.Position = 0;
                        var tex = new Texture(sheetStream, new TextureSettings {
                            MagFilter = filterMode > 0 ? TextureFilter.Linear : TextureFilter.Nearest,
                            MinFilter = filterMode == 1 ? TextureFilter.Linear : filterMode == 2 ? TextureFilter.Trilinear : TextureFilter.Nearest,
                        });
                        _material = new SpriteMaterial(shader, tex);
                    }
                    break;

                default:
                    throw new ContentException("Unrecognized atlas file " + tr.FileInfo.FileName);
                }
            }

            if (defs == null)
            {
                throw new ContentException("Missing atlas file.");
            }
            if (_material == null)
            {
                throw new ContentException("Missing image file.");
            }

            _sprites = new Dictionary <string, Sprite>();

            _vbuffer = new VertexBuffer(VertexFormat.PositionColorUV);
            _ibuffer = new IndexBuffer();
            var vstride = _vbuffer.Format.Stride * 4;

            int vOffset = 0, iOffset = 0, vcount = 0;
            var vertices = new float[vstride * defs.Count];
            var indices  = new int[6 * defs.Count];
            var tsz      = new Vector2(_material.Texture.Size.Width, _material.Texture.Size.Height);

            foreach (var kvp in defs)
            {
                var def   = kvp.Value;
                var pos   = def.Position;
                var sz    = def.Size;
                var orig  = def.Origin;
                var color = ParseColor(def.Color);
                orig.X *= sz.X;
                orig.Y *= sz.Y;

                if (def.Border != Vector4.Zero)
                {
                    _sprites.Add(kvp.Key, new SlicedSprite(_material, pos, sz, orig, color, def.Border, def.TileX, def.TileY, def.Hollow));
                    continue;
                }

                var uv = new Vector4(
                    pos.X / tsz.X,
                    ((pos.Y + sz.Y)) / tsz.Y,
                    (pos.X + sz.X) / tsz.X,
                    (pos.Y) / tsz.Y
                    );

                Array.Copy(new[] {
                    -orig.X, -orig.Y, 0f, color.X, color.Y, color.Z, color.W, uv.X, uv.Y,
                    sz.X - orig.X, -orig.Y, 0f, color.X, color.Y, color.Z, color.W, uv.Z, uv.Y,
                    sz.X - orig.X, sz.Y - orig.Y, 0f, color.X, color.Y, color.Z, color.W, uv.Z, uv.W,
                    -orig.X, sz.Y - orig.Y, 0f, color.X, color.Y, color.Z, color.W, uv.X, uv.W
                }, 0, vertices, vOffset, vstride);

                Array.Copy(new[] {
                    vcount + 0, vcount + 1, vcount + 2, vcount + 2, vcount + 3, vcount + 0
                }, 0, indices, iOffset, 6);

                var sprite = new Sprite(_material, sz, _vbuffer, _ibuffer, iOffset, 6);
                _sprites.Add(kvp.Key, sprite);
                vOffset += vstride;
                iOffset += 6;
                vcount  += 4;
            }

            _vbuffer.Data = vertices;
            _vbuffer.Commit();

            _ibuffer.Data = indices;
            _ibuffer.Commit();
        }
Example #29
0
        public void TestEOF()
        {
            List<ITarHeader> list = new List<ITarHeader>();
            var reader = new TarReader(gnuStream);
            while (!reader.EOF)
            {
                reader.MoveNext(true);
                list.Add(reader.FileInfo);
            }

            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/"));
            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/world/"));
            Assert.IsNotNull(list.FirstOrDefault(x => x.FileName == "hello/world/hello"));
        }
        /// <summary>
        /// Opens a Reader for Non-seeking usage
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static IReader Open(Stream stream, ReaderOptions options = null)
        {
            stream.CheckNotNull("stream");
            options = options ?? new ReaderOptions()
            {
                LeaveStreamOpen = false
            };
            RewindableStream rewindableStream = new RewindableStream(stream);

            rewindableStream.StartRecording();
            if (ZipArchive.IsZipFile(rewindableStream, options.Password))
            {
                rewindableStream.Rewind(true);
                return(ZipReader.Open(rewindableStream, options));
            }
            rewindableStream.Rewind(false);
            if (GZipArchive.IsGZipFile(rewindableStream))
            {
                rewindableStream.Rewind(false);
                GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, options, CompressionType.GZip));
                }
                rewindableStream.Rewind(true);
                return(GZipReader.Open(rewindableStream, options));
            }

            rewindableStream.Rewind(false);
            if (BZip2Stream.IsBZip2(rewindableStream))
            {
                rewindableStream.Rewind(false);
                BZip2Stream testStream = new BZip2Stream(rewindableStream, CompressionMode.Decompress, true);
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, options, CompressionType.BZip2));
                }
            }

            rewindableStream.Rewind(false);
            if (LZipStream.IsLZipFile(rewindableStream))
            {
                rewindableStream.Rewind(false);
                LZipStream testStream = new LZipStream(rewindableStream, CompressionMode.Decompress, true);
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, options, CompressionType.LZip));
                }
            }
            rewindableStream.Rewind(false);
            if (RarArchive.IsRarFile(rewindableStream, options))
            {
                rewindableStream.Rewind(true);
                return(RarReader.Open(rewindableStream, options));
            }

            rewindableStream.Rewind(false);
            if (TarArchive.IsTarFile(rewindableStream))
            {
                rewindableStream.Rewind(true);
                return(TarReader.Open(rewindableStream, options));
            }
            rewindableStream.Rewind(false);
            if (XZStream.IsXZStream(rewindableStream))
            {
                rewindableStream.Rewind(true);
                XZStream testStream = new XZStream(rewindableStream);
                if (TarArchive.IsTarFile(testStream))
                {
                    rewindableStream.Rewind(true);
                    return(new TarReader(rewindableStream, options, CompressionType.Xz));
                }
            }
            throw new InvalidOperationException("Cannot determine compressed stream type.  Supported Reader Formats: Zip, GZip, BZip2, Tar, Rar, LZip, XZ");
        }
        private void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(Configuration.Settings.Language.GetTesseractDictionaries.DownloadFailed);
                DialogResult = DialogResult.Cancel;
                return;
            }

            string dictionaryFolder = Configuration.TesseractDataFolder;
            if (!Directory.Exists(dictionaryFolder))
                Directory.CreateDirectory(dictionaryFolder);

            int index = comboBoxDictionaries.SelectedIndex;

            var tempFileName = Path.GetTempFileName() + ".tar";
            using (var ms = new MemoryStream(e.Result))
            using (var fs = new FileStream(tempFileName, FileMode.Create))
            using (var zip = new GZipStream(ms, CompressionMode.Decompress))
            {
                byte[] buffer = new byte[1024];
                int nRead;
                while ((nRead = zip.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fs.Write(buffer, 0, nRead);
                }
            }

            using (var tr = new TarReader(tempFileName))
            {
                foreach (var th in tr.Files)
                {
                    string fn = Path.Combine(dictionaryFolder, Path.GetFileName(th.FileName.Trim()));
                    th.WriteData(fn);
                }
            }
            File.Delete(tempFileName);

            Cursor = Cursors.Default;
            labelPleaseWait.Text = string.Empty;
            buttonOK.Enabled = true;
            buttonDownload.Enabled = true;
            comboBoxDictionaries.Enabled = true;
            MessageBox.Show(string.Format(Configuration.Settings.Language.GetDictionaries.XDownloaded, comboBoxDictionaries.Items[index]));
        }
Example #32
0
        /// <summary>
        /// Suck the brains out of the app
        /// </summary>
        static void Main(string[] args)
        {
            Console.WriteLine("OpenIZ BrainBug - Android Extraction Tool");
            Console.WriteLine("Version {0}", Assembly.GetEntryAssembly().GetName().Version);

            var parameters = new ParameterParser <ConsoleParameters>().Parse(args);

            if (parameters.Help)
            {
                new ParameterParser <ConsoleParameters>().WriteHelp(Console.Out);
                return;
            }
            if (parameters.TargetFile == null && parameters.ExtractDir == null)
            {
                Console.WriteLine("Either --tar or --extract must be specified");
                return;
            }

            if (parameters.PackageId != null)
            {
                var           exeFile = Path.Combine(parameters.SdkPath, "platform-tools", "adb.exe");
                StringBuilder argStr  = new StringBuilder();

                if (!String.IsNullOrEmpty(parameters.DeviceId))
                {
                    argStr.AppendFormat(" -s {0} ", parameters.DeviceId);
                }
                argStr.Append("backup ");

                argStr.AppendFormat("-f \"backup.ab\"", parameters.BackupFile);

                argStr.Append(" -noapk -noobb ");
                argStr.Append(parameters.PackageId);
                Console.WriteLine("Starting {0} {1}", exeFile, argStr.ToString());
                var pi = new Process();
                pi.StartInfo.FileName               = String.Format("\"{0}\"", exeFile);
                pi.StartInfo.Arguments              = argStr.ToString();
                pi.StartInfo.CreateNoWindow         = true;
                pi.StartInfo.RedirectStandardError  = true;
                pi.StartInfo.RedirectStandardOutput = true;
                pi.StartInfo.UseShellExecute        = false;
                pi.Start();
                Console.WriteLine(pi.StandardOutput.ReadToEnd());
                Console.WriteLine(pi.StandardError.ReadToEnd());
                pi.WaitForExit();

                if (File.Exists(parameters.BackupFile))
                {
                    File.Delete(parameters.BackupFile);
                }
                File.Move("backup.ab", parameters.BackupFile);
            }

            if (!File.Exists(parameters.BackupFile))
            {
                Console.WriteLine("Cannot find specified backup file!");
                return;
            }

            try
            {
                Console.WriteLine("Extracting {0}...", parameters.BackupFile);
                byte[] buffer = new byte[8096];
                using (FileStream ins = File.OpenRead(parameters.BackupFile))
                {
                    ins.Read(buffer, 0, 24);
                    String magic = System.Text.Encoding.UTF8.GetString(buffer, 0, 24);
                    //ins.Seek(24, SeekOrigin.Begin);
                    using (FileStream outs = File.Create(parameters.TargetFile))
                    {
                        using (ZLibNet.ZLibStream df = new ZLibNet.ZLibStream(ins, ZLibNet.CompressionMode.Decompress))
                        {
                            int br = 8096;
                            while (br == 8096)
                            {
                                br = df.Read(buffer, 0, 8096);
                                outs.Write(buffer, 0, br);
                            }
                        }
                    }
                }

                // Extract
                if (parameters.ExtractDir != null)
                {
                    if (!Directory.Exists(parameters.ExtractDir))
                    {
                        Directory.CreateDirectory(parameters.ExtractDir);
                    }
                    using (var fs = File.OpenRead(parameters.TargetFile))
                        using (var tar = TarReader.Open(fs))
                            while (tar.MoveToNextEntry())
                            {
                                string outName = Path.Combine(parameters.ExtractDir, tar.Entry.Key);
                                if (!Directory.Exists(Path.GetDirectoryName(outName)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(outName));
                                }
                                Console.WriteLine("{0} > {1}", tar.Entry.Key, outName);

                                if (!tar.Entry.IsDirectory)
                                {
                                    using (var ofs = File.Create(outName))
                                        tar.WriteEntryTo(ofs);
                                }
                            }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Example #33
0
        public async Task IncludeAllSegmentsOfPath_Async(bool includeBaseDirectory)
        {
            using (TempDirectory source = new TempDirectory())
                using (TempDirectory destination = new TempDirectory())
                {
                    string segment1 = Path.Join(source.Path, "segment1");
                    Directory.CreateDirectory(segment1);
                    string segment2 = Path.Join(segment1, "segment2");
                    Directory.CreateDirectory(segment2);
                    string textFile = Path.Join(segment2, "file.txt");
                    File.Create(textFile).Dispose();

                    string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

                    await TarFile.CreateFromDirectoryAsync(source.Path, destinationArchiveFileName, includeBaseDirectory);

                    FileStreamOptions readOptions = new()
                    {
                        Access  = FileAccess.Read,
                        Mode    = FileMode.Open,
                        Options = FileOptions.Asynchronous,
                    };

                    await using (FileStream fileStream = File.Open(destinationArchiveFileName, readOptions))
                    {
                        await using (TarReader reader = new TarReader(fileStream))
                        {
                            string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty;

                            TarEntry entry;

                            if (includeBaseDirectory)
                            {
                                entry = await reader.GetNextEntryAsync();

                                Assert.NotNull(entry);
                                Assert.Equal(TarEntryType.Directory, entry.EntryType);
                                Assert.Equal(prefix, entry.Name);
                            }

                            entry = await reader.GetNextEntryAsync();

                            Assert.NotNull(entry);
                            Assert.Equal(TarEntryType.Directory, entry.EntryType);
                            Assert.Equal(prefix + "segment1/", entry.Name);

                            entry = await reader.GetNextEntryAsync();

                            Assert.NotNull(entry);
                            Assert.Equal(TarEntryType.Directory, entry.EntryType);
                            Assert.Equal(prefix + "segment1/segment2/", entry.Name);

                            entry = await reader.GetNextEntryAsync();

                            Assert.NotNull(entry);
                            Assert.Equal(TarEntryType.RegularFile, entry.EntryType);
                            Assert.Equal(prefix + "segment1/segment2/file.txt", entry.Name);

                            Assert.Null(await reader.GetNextEntryAsync());
                        }
                    }
                }
        }