예제 #1
0
        protected GZipAccess(Stream stream, CompressedArchiveAccessMode mode)
        {
            IsReadOnly = mode == CompressedArchiveAccessMode.Read;
            BaseStream = stream;
            var fileStream = stream as FileStream;

            if (fileStream != null)
            {
                RootLocation = fileStream.Name;
            }
            _entries = GZipMemberEntry.GetMemberEntries(stream, Properties.Settings.Default.MaxGZipEntriesSearch).ToList();
            if (IsReadOnly)
            {
                if (!_entries.Any())
                {
                    throw new InvalidDataException(Resources.Strings.GZipAccess_NoEntriesFound);
                }
            }
            else
            {
                if (_entries.Any())
                {
                    throw new InvalidOperationException(Resources.Strings.GZipAccess_EntriesAlreadyPresent);
                }
            }
        }
예제 #2
0
            /// <summary>
            /// Creates an instance of <see cref="CompressedArchiveFileAccess"/>, depending on <paramref name="mode"/>.
            /// </summary>
            /// <param name="filePath">The absolute path for the compressed archive.</param>
            /// <param name="mode">The access mode to use for operations on the compressed archive.</param>
            /// <param name="implementation">If not <c>null</c>, use a specific implementation if possible. Otherwise, use default, or any.</param>
            /// <returns>An instance of <see cref="CompressedArchiveFileAccess"/> that provides access to the compressed archive located at <paramref name="filePath"/>.</returns>
            /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="filePath"/> is <c>null</c>.</exception>
            /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the file is accessed incorrectly for the given <paramref name="mode"/>.</exception>
            /// <exception cref="System.ArgumentException">Thrown if <paramref name="filePath"/> is empty or white space, contains invalid characters, or is otherwise invalid</exception>
            /// <exception cref="System.NotSupportedException">Thrown if <paramref name="filePath"/> refers to a non-file device, e.g. a COM port, et. al.</exception>
            /// <exception cref="System.IO.FileNotFoundException">Thrown if <paramref name="filePath"/> cannot be found.</exception>
            /// <exception cref="System.IO.IOException">Thrown if an I/O error occurs.</exception>
            /// <exception cref="System.Security.SecurityException">Thrown if the requested action on <paramref name="filePath"/> cannot be performed, e.g. no read / create access is granted, et. al.</exception>
            /// <exception cref="System.IO.DirectoryNotFoundException">Thrown if the directory cannot be found, e.g. an unavailable network drive forms part of the file path.</exception>
            /// <exception cref="System.UnauthorizedAccessException">Thrown if access is denied, e.g. read/write access requested for a read-only file or directory.</exception>
            /// <exception cref="System.IO.PathTooLongException">Thrown if <paramref name="filePath"/> is too long.</exception>
            /// <exception cref="System.InvalidOperationException">Thrown if it is not possible to create an instance of <see cref="CompressedArchiveFileAccess"/> from the file at <paramref name="filePath"/>,
            /// despite the file appearing to be valid.</exception>
            public static CompressedArchiveFileAccess Create(string filePath, CompressedArchiveAccessMode mode, CompressedArchiveAccessImplementation?implementation)
            {
                var fileMode   = CompressedArchiveAccessModeToFileMode(mode);
                var fileAccess = CompressedArchiveAccessModeToFileAccess(mode);
                var fileName   = Path.GetFileName(filePath);

                var successfullyAccessedFormats = new List <CompressedArchiveFormat>();
                var fileStream = new FileStream(filePath, fileMode, fileAccess);
                var formats    = filePath.GetCompressedArchiveFormatsFromFileName();
                ICompressedArchiveAccess compressedArchiveAccess = null;

#if OPEN_NESTED_FORMAT_IMMEDIATELY
                Stream stream = fileStream;
                foreach (var format in formats)
                {
                    compressedArchiveAccess = Utility.CompressedArchiveAccess.Open(stream, format, mode);
                    if (compressedArchiveAccess != null)
                    {
                        successfullyAccessedFormats.Add(format);
                        if (!compressedArchiveAccess.IsArchive)
                        {
                            fileName = Path.GetFileNameWithoutExtension(fileName);
                            var entry = compressedArchiveAccess.FindEntry(fileName);
                            stream = entry == null ? null : compressedArchiveAccess.OpenEntry(entry);
                            if (stream == null)
                            {
                                compressedArchiveAccess = null;
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
#else
                var format = formats.FirstOrDefault();
                if (format != CompressedArchiveFormat.None)
                {
                    compressedArchiveAccess = Utility.CompressedArchiveAccess.Open(fileStream, format, mode, implementation);
                }
#endif

                if (compressedArchiveAccess == null)
                {
                    var identifiedFormats          = string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, formats);
                    var successfullyCreatedFormats = string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, successfullyAccessedFormats);
                    var failedFormats = string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, formats.Except(successfullyAccessedFormats));
                    var errorMessage  = string.Format(CultureInfo.CurrentCulture, Resources.Strings.CompressedArchiveAccess_UnableToProcessError_Format, filePath, identifiedFormats, successfullyCreatedFormats, failedFormats);
                    throw new InvalidOperationException(errorMessage);
                }

                var compressedArchiveFileAccess = new CompressedArchiveFileAccess(filePath, compressedArchiveAccess)
                {
                    Stream = fileStream
                };
                return(compressedArchiveFileAccess);
            }
예제 #3
0
        /// <summary>
        /// Wraps the internal open method.
        /// </summary>
        /// <param name="stream">A stream containing a ZIP archive.</param>
        /// <param name="mode">The mode in which to access the archive.</param>
        /// <returns>The native object representing a ZIP archive.</returns>
        /// <exception cref="System.FileFormatException">Thrown if archive was opened for reading, but is of zero size.</exception>
        /// <exception cref="System.IOException">Thrown if <paramref name="stream"/> is not empty and archive was opened in Create mode.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="stream"/> is <c>null</c></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if an invalid combination of file access and mode is used.</exception>
        /// <exception cref="System.NotSupportedException">Thrown if an invalid file sharing mode is in use.</exception>
        /// <exception cref="System.ArgumentException">Thrown if invalid file access, sharing, and mode combinations are used.</exception>
        private static IDisposable Open(Stream stream, CompressedArchiveAccessMode mode)
        {
            var fileMode         = CompressedArchiveAccessModeToFileMode(mode);
            var fileAccess       = CompressedArchiveAccessModeToFileAccess(mode);
            var streaming        = mode == CompressedArchiveAccessMode.Create; // actually, eventually turns into -> use async option for stream access
            var zipArchiveObject = OpenFromStreamMethod.Value.Invoke(null, new object[] { stream, fileMode, fileAccess, streaming }) as IDisposable;

            return(zipArchiveObject);
        }
예제 #4
0
        private static CompressionMode CompressedArchiveAccessModeToCompressionMode(CompressedArchiveAccessMode mode)
        {
            var compressionMode = CompressionMode.Compress;

            switch (mode)
            {
            case CompressedArchiveAccessMode.Read:
                compressionMode = CompressionMode.Decompress;
                break;

            case CompressedArchiveAccessMode.Create:
            case CompressedArchiveAccessMode.Update:
                break;
            }
            return(compressionMode);
        }
예제 #5
0
        /// <summary>
        /// Validates the provided mode.
        /// </summary>
        /// <param name="mode">The mode to validate.</param>
        /// <returns>The value of <paramref name="mode"/> if valid.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if an unsupported value for <paramref name="mode"/> is provided.</exception>
        private static CompressedArchiveAccessMode ValidateMode(CompressedArchiveAccessMode mode)
        {
            switch (mode)
            {
            case CompressedArchiveAccessMode.Read:
                break;

            case CompressedArchiveAccessMode.Create:
                break;

            case CompressedArchiveAccessMode.Update:
                throw new InvalidOperationException(Resources.Strings.TarArchiveAccess_InvalidMode);

            default:
                throw new ArgumentOutOfRangeException("mode", mode, Resources.Strings.TarArchiveAccess_InvalidMode);
            }
            return(mode);
        }
예제 #6
0
        /// <summary>
        /// Converts a <see cref="CompressedArchiveAccessMode"/> to an appropriate <see cref="FileMode"/>.
        /// </summary>
        /// <param name="mode">A compressed archive access mode.</param>
        /// <returns>The appropriate <see cref="FileMode"/> to use.</returns>
        protected static FileMode CompressedArchiveAccessModeToFileMode(CompressedArchiveAccessMode mode)
        {
            var fileMode = FileMode.Open;

            switch (mode)
            {
            case CompressedArchiveAccessMode.Create:
                fileMode = FileMode.Create;
                break;

            case CompressedArchiveAccessMode.Update:
                fileMode = FileMode.OpenOrCreate;
                break;

            default:
                break;
            }
            return(fileMode);
        }
예제 #7
0
        /// <summary>
        /// Converts a <see cref="CompressedArchiveAccessMode"/> to an appropriate <see cref="FileAccess"/>.
        /// </summary>
        /// <param name="mode">A compressed archive access mode.</param>
        /// <returns>The appropriate <see cref="FileAccess"/> to use.</returns>
        protected static FileAccess CompressedArchiveAccessModeToFileAccess(CompressedArchiveAccessMode mode)
        {
            var fileAccess = FileAccess.Read;

            switch (mode)
            {
            case CompressedArchiveAccessMode.Create:
                fileAccess = FileAccess.Write;
                break;

            case CompressedArchiveAccessMode.Update:
                fileAccess = FileAccess.ReadWrite;
                break;

            default:
                break;
            }
            return(fileAccess);
        }
예제 #8
0
            public static TestCompressedArchiveAccess Create(
                Stream stream,
                CompressedArchiveAccessMode mode,
                CompressedArchiveFormat format,
                CompressedArchiveAccessImplementation implementation,
                string firstEntryName = null,
                bool isArchive        = true,
                bool isCompressed     = true)
            {
                var testArchiveAccess = new TestCompressedArchiveAccess()
                {
                    Mode = mode, _format = format, Implementation = implementation
                };

                testArchiveAccess._isArchive    = isArchive;
                testArchiveAccess._isCompressed = isCompressed;
                if (!string.IsNullOrWhiteSpace(firstEntryName))
                {
                    testArchiveAccess.CreateAndAddEntry(firstEntryName);
                }
                return(testArchiveAccess);
            }
예제 #9
0
        /// <summary>
        /// Initialize a new instance of the type from the given stream.
        /// </summary>
        /// <param name="stream">Stream containing data in TAR format.</param>
        /// <param name="mode">The access mode to use for TAR operations.</param>
        private TarAccessSharpZipLib(Stream stream, CompressedArchiveAccessMode mode)
        {
            IsReadOnly = mode == CompressedArchiveAccessMode.Read;
            _entries   = ListTarEntries(stream);
            switch (mode)
            {
            case CompressedArchiveAccessMode.Create:
                TarArchive = ICSharpCode.SharpZipLib.Tar.TarArchive.CreateOutputTarArchive(stream);
                TarArchive.SetKeepOldFiles(keepExistingFiles: false);
                var fileStream = stream as FileStream;
                if (fileStream != null)
                {
                    RootLocation = fileStream.Name;
                }
                break;

            default:
                TarArchive = ICSharpCode.SharpZipLib.Tar.TarArchive.CreateInputTarArchive(stream);
                break;
            }
            TarArchive.IsStreamOwner = true;
        }
예제 #10
0
        private static ZipFile Open(Stream stream, CompressedArchiveAccessMode mode)
        {
            try
            {
                ZipFile zipFile;
                switch (mode)
                {
                case CompressedArchiveAccessMode.Create:
                    zipFile = ZipFile.Create(stream);
                    zipFile.IsStreamOwner = true;     // This creation mode does NOT assume ownership of the stream.
                    break;

                default:
                    zipFile = new ZipFile(stream);     // This creation mode DOES assume ownership of the stream.
                    break;
                }
                return(zipFile);
            }
            catch (ZipException e)
            {
                throw new InvalidDataException(e.Message, e); // to be consistent with the native implementation.
            }
        }
예제 #11
0
 private GZipAccessNative(Stream stream, CompressedArchiveAccessMode mode)
     : base(stream, mode)
 {
     Mode = CompressedArchiveAccessModeToCompressionMode(mode);
 }
예제 #12
0
        /// <summary>
        /// Creates a new instance of <see cref="TarAccessSharpZipLib"/> using the given mode.
        /// </summary>
        /// <param name="stream">Stream containing data in TAR format.</param>
        /// <param name="mode">The access mode to use for TAR operations.</param>
        /// <returns>A new instance of <see cref="TarAccessSharpZipLib"/>.</returns>
        /// <remarks>The TAR implementation assumes ownership of <paramref name="stream"/> and will dispose it.</remarks>
        public static TarAccessSharpZipLib Create(Stream stream, CompressedArchiveAccessMode mode)
        {
            var tarAccess = new TarAccessSharpZipLib(stream, ValidateMode(mode));

            return(tarAccess);
        }
예제 #13
0
 /// <summary>
 /// Creates a new instance of <see cref="ZipArchiveAccess"/> using the given mode.
 /// </summary>
 /// <param name="stream">Stream containing data in ZIP archive format.</param>
 /// <param name="mode">The access mode to use for ZIP operations.</param>
 /// <returns>A new instance of <see cref="ZipArchiveAccess"/>.</returns>
 /// <remarks>The ZIP archive assumes ownership of <paramref name="stream"/> and will dispose it.</remarks>
 public static ZipArchiveAccess Create(Stream stream, CompressedArchiveAccessMode mode)
 {
     return(new ZipArchiveAccess(stream, mode));
 }
예제 #14
0
        private IDisposable _zipArchiveObject; // the backing object

        /// <summary>
        /// Initialize a new instance of the type from the given stream.
        /// </summary>
        /// <param name="stream">Stream containing data in ZIP archive format.</param>
        /// <param name="mode">The access mode to use for ZIP operations.</param>
        private ZipArchiveAccess(Stream stream, CompressedArchiveAccessMode mode)
        {
            Mode = mode;
            _zipArchiveObject = Open(stream, mode);
        }
예제 #15
0
 /// <summary>
 /// Initialize a new instance of the type from the given stream.
 /// </summary>
 /// <param name="stream">Stream containing data in ZIP archive format.</param>
 /// <param name="mode">The access mode to use for ZIP operations.</param>
 private ZipArchiveAccessSharpZipLib(Stream stream, CompressedArchiveAccessMode mode)
 {
     Mode    = mode;
     ZipFile = Open(stream, mode);
 }
예제 #16
0
 private GZipAccessSharpZipLib(Stream stream, CompressedArchiveAccessMode mode)
     : base(stream, mode)
 {
 }
        private static IDisposable Open(Stream stream, CompressedArchiveAccessMode mode)
        {
            var zipArchive = new ZipArchive(stream, (ZipArchiveMode)mode);

            return(zipArchive);
        }
예제 #18
0
 public void CompressedArchiveAccess_OpenUnknownFormatFromStream_ThrowsNotSupportedException(CompressedArchiveAccessMode mode)
 {
     Assert.Throws <NotSupportedException>(() => CompressedArchiveAccess.Open(Stream.Null, this.GetFakeCompressedArchiveFormatForTest(), mode));
 }
예제 #19
0
        /// <summary>
        /// Opens or creates an instance of <see cref="ICompressedArchiveAccess"/> based on the value of <paramref name="mode"/> from a file.
        /// </summary>
        /// <param name="filePath">The absolute path for the compressed archive.</param>
        /// <param name="mode">The access mode to use for operations on the compressed archive.</param>
        /// <param name="implementation">If not <c>null</c>, use a specific implementation if possible. Otherwise, use default, or any.</param>
        /// <returns>An instance of the compressed archive.</returns>
        /// <remarks>The format of the compressed archive accessor is determined via file extension.</remarks>
        /// <exception cref="System.NotSupportedException">Thrown if it is not possible to locate a factory for the given <paramref name="filePath"/>, or
        /// if <paramref name="filePath"/> was opened with an unsupported file sharing mode in use.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="filePath"/> is <c>null</c></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if an invalid combination of file access and mode is used.</exception>
        /// <exception cref="System.ArgumentException">Thrown if invalid file access, sharing, and mode combinations are used.</exception>
        /// <exception cref="System.IO.FileFormatException">Thrown if archive was opened for reading, but is of zero size.</exception>
        /// <exception cref="System.IO.IOException">Thrown if <paramref name="filePath"/> is not empty and archive was opened in Create mode.</exception>
        public static ICompressedArchiveAccess Open(string filePath, CompressedArchiveAccessMode mode, CompressedArchiveAccessImplementation?implementation = null)
        {
            var archive = CompressedArchiveFileAccess.Create(filePath, mode, implementation);

            return(archive);
        }
예제 #20
0
 public static FileAccess ConvertModeToFileAccess(CompressedArchiveAccessMode mode)
 {
     return(CompressedArchiveAccessModeToFileAccess(mode));
 }
예제 #21
0
        /// <summary>
        /// Creates a new instance of <see cref="GZipAccessNative"/> using the given mode.
        /// </summary>
        /// <param name="stream">Stream containing data in GZIP compressed format.</param>
        /// <param name="mode">The access mode to use for GZIP operations.</param>
        /// <returns>A new instance of <see cref="GZipAccessNative"/>.</returns>
        /// <remarks>The GZIP implementation assumes ownership of <paramref name="stream"/> and will dispose it.</remarks>
        public static GZipAccessNative Create(Stream stream, CompressedArchiveAccessMode mode)
        {
            var gzipAccess = new GZipAccessNative(stream, ValidateMode(mode));

            return(gzipAccess);
        }
예제 #22
0
 public void CompressedArchiveAccess_ConvertCompressedArchiveAccessModeToFileMode_ReturnsExpectedFileAccess(CompressedArchiveAccessMode mode, FileAccess expectedFileAccess)
 {
     Assert.Equal(expectedFileAccess, TestCompressedArchiveAccess.ConvertModeToFileAccess(mode));
 }
예제 #23
0
        /// <summary>
        /// Opens or creates an instance of <see cref="ICompressedArchiveAccess"/> based on the value of <paramref name="mode"/> from a stream.
        /// </summary>
        /// <param name="stream">The stream to use for the compressed archive accessor.</param>
        /// <param name="format">The format of the compressed archive.</param>
        /// <param name="mode">The access mode to use for operations on the compressed archive.</param>
        /// <param name="implementation">If not <c>null</c>, use a specific implementation if possible. Otherwise, use default, or any.</param>
        /// <returns>An instance of a compressed archive accessor for the given format.</returns>
        /// <remarks>The archive takes ownership of <paramref name="stream"/> and will dispose it.</remarks>
        /// <exception cref="System.NotSupportedException">Thrown if it is not possible to locate a factory for the given <paramref name="format"/>, or
        /// if <paramref name="stream"/> was opened with an unsupported file sharing mode in use.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="stream"/> is <c>null</c></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if an invalid combination of file access and mode is used.</exception>
        /// <exception cref="System.ArgumentException">Thrown if invalid file access, sharing, and mode combinations are used.</exception>
        /// <exception cref="System.IO.FileFormatException">Thrown if archive was opened for reading, but is of zero size.</exception>
        /// <exception cref="System.IO.IOException">Thrown if <paramref name="stream"/> is not empty and archive was opened in Create mode.</exception>
        public static ICompressedArchiveAccess Open(Stream stream, CompressedArchiveFormat format, CompressedArchiveAccessMode mode, CompressedArchiveAccessImplementation?implementation = null)
        {
            if (!implementation.HasValue)
            {
                implementation = format.GetPreferredCompressedArchiveImplementation();
            }
            var identifier = new CompressedArchiveIdentifier(format, implementation.Value);

            CompressedArchiveAccessFactory factory;

            if (!Factories.Value.TryGetValue(identifier, out factory))
            {
                identifier = new CompressedArchiveIdentifier(format, CompressedArchiveAccessImplementation.Any);
                Factories.Value.TryGetValue(identifier, out factory);
            }

            if (factory == null)
            {
                var message = string.Format(CultureInfo.CurrentCulture, Resources.Strings.CompressedArchiveAccess_UnsupportedFormatErrorMessage_Format, format);
                throw new NotSupportedException(message);
            }
            var archive = factory(stream, mode);

            return(archive);
        }