< Summary

Line coverage
41%
Covered lines: 49
Uncovered lines: 69
Coverable lines: 118
Total lines: 385
Line coverage: 41.5%
Branch coverage
37%
Covered branches: 18
Total branches: 48
Branch coverage: 37.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .ctor(...)0%4260%
File 1: .ctor(...)100%210%
File 1: Dispose()0%2040%
File 1: Create(...)0%2040%
File 1: Write(...)0%4260%
File 1: WriteAll(...)100%210%
File 1: WriteAll(...)0%2040%
File 2: .ctor(...)100%66100%
File 2: .ctor(...)100%210%
File 2: Dispose()100%44100%
File 2: Create(...)50%4.07483.33%
File 2: Write(...)50%6.97670%
File 2: WriteAll(...)100%11100%
File 2: WriteAll(...)75%4.07483.33%

File(s)

C:\projects\jeremyansel-io-locator\JeremyAnsel.IO.Locator\JeremyAnsel.IO.Locator\ArchiveWritableFileLocator.cs

#LineLine coverage
 1// <copyright file="ArchiveWritableFileLocator.cs" company="Jérémy Ansel">
 2// Copyright (c) 2015, 2019 Jérémy Ansel
 3// </copyright>
 4// <license>
 5// Licensed under the MIT license. See LICENSE.txt
 6// </license>
 7
 8namespace JeremyAnsel.IO.Locator
 9{
 10    using System;
 11    using System.Collections.Generic;
 12    using System.IO;
 13    using SharpCompress.Common;
 14    using SharpCompress.Writers;
 15
 16    /// <summary>
 17    /// A writable archive file locator.
 18    /// </summary>
 19    internal sealed class ArchiveWritableFileLocator : IWritableFileLocator
 20    {
 21        /// <summary>
 22        /// A file stream.
 23        /// </summary>
 24        private Stream? fileStream;
 25
 26        /// <summary>
 27        /// An archive.
 28        /// </summary>
 29        private IWriter? archive;
 30
 31        /// <summary>
 32        /// The file keys.
 33        /// </summary>
 34        private readonly SortedSet<string> keys;
 35
 36        /// <summary>
 37        /// Initializes a new instance of the <see cref="ArchiveWritableFileLocator"/> class.
 38        /// </summary>
 39        /// <param name="root">The root path.</param>
 40        /// <param name="archiveType">The archive type.</param>
 41        /// <param name="compressionType">The compression type.</param>
 042        public ArchiveWritableFileLocator(string root, ArchiveType archiveType, CompressionType compressionType)
 43        {
 044            this.keys = new SortedSet<string>();
 45
 046            using (var memory = new MemoryFileLocator())
 47            {
 048                if (File.Exists(root))
 49                {
 050                    long length = 0;
 51
 052                    using (var file = File.OpenRead(root))
 53                    {
 054                        length = file.Length;
 055                    }
 56
 057                    if (length != 0)
 58                    {
 059                        using var reader = FileLocatorFactory.Create(root);
 060                        memory.WriteAll(reader);
 61                    }
 62                }
 63
 064                this.fileStream = File.OpenWrite(root);
 065                this.archive = WriterFactory.Open(this.fileStream, archiveType, new WriterOptions(compressionType));
 66
 067                if (!memory.IsEmpty)
 68                {
 069                    this.WriteAll(memory);
 70                }
 071            }
 072        }
 73
 74        /// <summary>
 75        /// Initializes a new instance of the <see cref="ArchiveWritableFileLocator"/> class.
 76        /// </summary>
 77        /// <param name="root">A stream.</param>
 78        /// <param name="archiveType">The archive type.</param>
 79        /// <param name="compressionType">The compression type.</param>
 080        public ArchiveWritableFileLocator(Stream root, ArchiveType archiveType, CompressionType compressionType)
 81        {
 082            this.keys = new SortedSet<string>();
 83
 084            this.archive = WriterFactory.Open(root, archiveType, new WriterOptions(compressionType));
 085        }
 86
 87        /// <summary>
 88        /// Immediately releases the unmanaged resources used by the <see cref="ArchiveWritableFileLocator"/> object.
 89        /// </summary>
 90        public void Dispose()
 91        {
 092            if (this.archive != null)
 93            {
 094                this.archive.Dispose();
 095                this.archive = null;
 96            }
 97
 098            if (this.fileStream != null)
 99            {
 0100                this.fileStream.Dispose();
 0101                this.fileStream = null;
 102            }
 103
 0104            GC.SuppressFinalize(this);
 0105        }
 106
 107        /// <summary>
 108        /// Create a file.
 109        /// </summary>
 110        /// <param name="path">A path.</param>
 111        public void Create(string path)
 112        {
 0113            if (string.IsNullOrEmpty(path))
 114            {
 0115                throw new ArgumentNullException(nameof(path));
 116            }
 117
 0118            path = Utilities.PathNormalize(path);
 119
 0120            if (this.keys.Contains(path))
 121            {
 0122                throw new ArgumentOutOfRangeException(nameof(path));
 123            }
 124
 0125            using (var buffer = new MemoryStream())
 126            {
 0127                buffer.WriteByte(0);
 0128                buffer.Seek(0, SeekOrigin.Begin);
 129
 0130                this.archive!.Write(path, buffer);
 0131            }
 132
 0133            this.keys.Add(path);
 0134        }
 135
 136        /// <summary>
 137        /// Write a file.
 138        /// </summary>
 139        /// <param name="path">A path.</param>
 140        /// <param name="data">The data.</param>
 141        public void Write(string path, Stream? data)
 142        {
 0143            if (string.IsNullOrEmpty(path))
 144            {
 0145                throw new ArgumentNullException(nameof(path));
 146            }
 147
 0148            if (data == null)
 149            {
 0150                throw new ArgumentNullException(nameof(data));
 151            }
 152
 0153            path = Utilities.PathNormalize(path);
 154
 0155            if (this.keys.Contains(path))
 156            {
 0157                throw new ArgumentOutOfRangeException(nameof(path));
 158            }
 159
 0160            this.archive!.Write(path, data);
 0161            this.keys.Add(path);
 0162        }
 163
 164        /// <summary>
 165        /// Write the files from a file locator.
 166        /// </summary>
 167        /// <param name="locator">A file locator.</param>
 168        public void WriteAll(IFileLocator? locator)
 169        {
 0170            this.WriteAll(locator, string.Empty);
 0171        }
 172
 173        /// <summary>
 174        /// Write the files from a file locator.
 175        /// </summary>
 176        /// <param name="locator">A file locator.</param>
 177        /// <param name="root">The root path.</param>
 178        public void WriteAll(IFileLocator? locator, string root)
 179        {
 0180            if (locator == null)
 181            {
 0182                throw new ArgumentNullException(nameof(locator));
 183            }
 184
 0185            foreach (var file in locator.EnumerateFiles(root))
 186            {
 0187                using var stream = locator.Open(file);
 0188                this.Write(file, stream);
 189            }
 0190        }
 191    }
 192}

https://raw.githubusercontent.com/JeremyAnsel/JeremyAnsel.IO.Locator/90359a183919dae2d6e9fc4cabae797b0df998d4/JeremyAnsel.IO.Locator/JeremyAnsel.IO.Locator/ArchiveWritableFileLocator.cs

#LineLine coverage
 1// <copyright file="ArchiveWritableFileLocator.cs" company="Jérémy Ansel">
 2// Copyright (c) 2015, 2019 Jérémy Ansel
 3// </copyright>
 4// <license>
 5// Licensed under the MIT license. See LICENSE.txt
 6// </license>
 7
 8namespace JeremyAnsel.IO.Locator
 9{
 10    using System;
 11    using System.Collections.Generic;
 12    using System.IO;
 13    using SharpCompress.Common;
 14    using SharpCompress.Writers;
 15
 16    /// <summary>
 17    /// A writable archive file locator.
 18    /// </summary>
 19    internal sealed class ArchiveWritableFileLocator : IWritableFileLocator
 20    {
 21        /// <summary>
 22        /// A file stream.
 23        /// </summary>
 24        private Stream? fileStream;
 25
 26        /// <summary>
 27        /// An archive.
 28        /// </summary>
 29        private IWriter? archive;
 30
 31        /// <summary>
 32        /// The file keys.
 33        /// </summary>
 34        private readonly SortedSet<string> keys;
 35
 36        /// <summary>
 37        /// Initializes a new instance of the <see cref="ArchiveWritableFileLocator"/> class.
 38        /// </summary>
 39        /// <param name="root">The root path.</param>
 40        /// <param name="archiveType">The archive type.</param>
 41        /// <param name="compressionType">The compression type.</param>
 642        public ArchiveWritableFileLocator(string root, ArchiveType archiveType, CompressionType compressionType)
 43        {
 644            this.keys = new SortedSet<string>();
 45
 646            using (var memory = new MemoryFileLocator())
 47            {
 648                if (File.Exists(root))
 49                {
 650                    long length = 0;
 51
 652                    using (var file = File.OpenRead(root))
 53                    {
 654                        length = file.Length;
 655                    }
 56
 657                    if (length != 0)
 58                    {
 359                        using var reader = FileLocatorFactory.Create(root);
 360                        memory.WriteAll(reader);
 61                    }
 62                }
 63
 664                this.fileStream = File.OpenWrite(root);
 665                this.archive = WriterFactory.Open(this.fileStream, archiveType, new WriterOptions(compressionType));
 66
 667                if (!memory.IsEmpty)
 68                {
 369                    this.WriteAll(memory);
 70                }
 671            }
 672        }
 73
 74        /// <summary>
 75        /// Initializes a new instance of the <see cref="ArchiveWritableFileLocator"/> class.
 76        /// </summary>
 77        /// <param name="root">A stream.</param>
 78        /// <param name="archiveType">The archive type.</param>
 79        /// <param name="compressionType">The compression type.</param>
 080        public ArchiveWritableFileLocator(Stream root, ArchiveType archiveType, CompressionType compressionType)
 81        {
 082            this.keys = new SortedSet<string>();
 83
 084            this.archive = WriterFactory.Open(root, archiveType, new WriterOptions(compressionType));
 085        }
 86
 87        /// <summary>
 88        /// Immediately releases the unmanaged resources used by the <see cref="ArchiveWritableFileLocator"/> object.
 89        /// </summary>
 90        public void Dispose()
 91        {
 692            if (this.archive != null)
 93            {
 694                this.archive.Dispose();
 695                this.archive = null;
 96            }
 97
 698            if (this.fileStream != null)
 99            {
 6100                this.fileStream.Dispose();
 6101                this.fileStream = null;
 102            }
 103
 6104            GC.SuppressFinalize(this);
 6105        }
 106
 107        /// <summary>
 108        /// Create a file.
 109        /// </summary>
 110        /// <param name="path">A path.</param>
 111        public void Create(string path)
 112        {
 6113            if (string.IsNullOrEmpty(path))
 114            {
 0115                throw new ArgumentNullException(nameof(path));
 116            }
 117
 6118            path = Utilities.PathNormalize(path);
 119
 6120            if (this.keys.Contains(path))
 121            {
 0122                throw new ArgumentOutOfRangeException(nameof(path));
 123            }
 124
 6125            using (var buffer = new MemoryStream())
 126            {
 6127                buffer.WriteByte(0);
 6128                buffer.Seek(0, SeekOrigin.Begin);
 129
 6130                this.archive!.Write(path, buffer);
 6131            }
 132
 6133            this.keys.Add(path);
 6134        }
 135
 136        /// <summary>
 137        /// Write a file.
 138        /// </summary>
 139        /// <param name="path">A path.</param>
 140        /// <param name="data">The data.</param>
 141        public void Write(string path, Stream? data)
 142        {
 3143            if (string.IsNullOrEmpty(path))
 144            {
 0145                throw new ArgumentNullException(nameof(path));
 146            }
 147
 3148            if (data == null)
 149            {
 0150                throw new ArgumentNullException(nameof(data));
 151            }
 152
 3153            path = Utilities.PathNormalize(path);
 154
 3155            if (this.keys.Contains(path))
 156            {
 0157                throw new ArgumentOutOfRangeException(nameof(path));
 158            }
 159
 3160            this.archive!.Write(path, data);
 3161            this.keys.Add(path);
 3162        }
 163
 164        /// <summary>
 165        /// Write the files from a file locator.
 166        /// </summary>
 167        /// <param name="locator">A file locator.</param>
 168        public void WriteAll(IFileLocator? locator)
 169        {
 3170            this.WriteAll(locator, string.Empty);
 3171        }
 172
 173        /// <summary>
 174        /// Write the files from a file locator.
 175        /// </summary>
 176        /// <param name="locator">A file locator.</param>
 177        /// <param name="root">The root path.</param>
 178        public void WriteAll(IFileLocator? locator, string root)
 179        {
 3180            if (locator == null)
 181            {
 0182                throw new ArgumentNullException(nameof(locator));
 183            }
 184
 12185            foreach (var file in locator.EnumerateFiles(root))
 186            {
 3187                using var stream = locator.Open(file);
 3188                this.Write(file, stream);
 189            }
 3190        }
 191    }
 192}
 193