< Summary - SonghayCore

Line coverage
79%
Covered lines: 133
Uncovered lines: 35
Coverable lines: 168
Total lines: 473
Line coverage: 79.1%
Branch coverage
48%
Covered branches: 39
Total branches: 80
Branch coverage: 48.7%
Method coverage

Method coverage is only available for sponsors.

Upgrade to PRO version

Metrics

File(s)

/home/rasx/sourceRoot/SonghayCore/SonghayCore/ProgramFileUtility._.cs

#LineLine coverage
 1namespace Songhay;
 2
 3/// <summary>
 4/// A few static helper members for <see cref="System.IO"/>.
 5/// </summary>
 6public static partial class ProgramFileUtility
 7{
 8    static ProgramFileUtility()
 19    {
 110        Backslash = '\\';
 111        ForwardSlash = '/';
 112        IsForwardSlashSystemField = Path.DirectorySeparatorChar.Equals(ForwardSlash);
 113        TraceSource = TraceSources.Instance.GetConfiguredTraceSource();
 114    }
 15
 16    static readonly TraceSource? TraceSource;
 17
 18    /// <summary>
 19    /// Counts the parent directory chars.
 20    /// </summary>
 21    /// <param name="path">The path.</param>
 22    /// <remarks>
 23    /// This method is useful when running <see cref="GetParentDirectory(string, int)"/>.
 24    ///
 25    /// WARNING: call <see cref="NormalizePath(string)"/> to prevent incorrectly returning <c>0</c>
 26    /// in cross-platform scenarios.
 27    /// </remarks>
 28    public static int CountParentDirectoryChars(string? path)
 2529    {
 2530        if (string.IsNullOrWhiteSpace(path)) return default;
 31
 2532        var parentDirectoryCharsPattern = $@"\.\.\{Path.DirectorySeparatorChar}";
 2533        var matches = Regex.Matches(path, parentDirectoryCharsPattern);
 34
 2535        return matches.Count;
 2536    }
 37
 38    /// <summary>
 39    /// Finds the parent directory.
 40    /// </summary>
 41    /// <param name="path">The path.</param>
 42    /// <param name="parentName">Name of the parent.</param>
 43    /// <param name="levels">The levels.</param>
 44    public static string? FindParentDirectory(string? path, string? parentName, int levels) =>
 045        FindParentDirectoryInfo(path, parentName, levels)?.FullName;
 46
 47    /// <summary>
 48    /// Finds the parent <see cref="DirectoryInfo"/>.
 49    /// </summary>
 50    /// <param name="path">The path.</param>
 51    /// <param name="parentName">Name of the parent.</param>
 52    /// <param name="levels">The levels.</param>
 53    public static DirectoryInfo? FindParentDirectoryInfo(string? path, string? parentName, int levels)
 054    {
 055        if (string.IsNullOrWhiteSpace(path))
 056            throw new DirectoryNotFoundException("The expected directory is not here.");
 57
 058        var info = new DirectoryInfo(path);
 59
 060        var isParent = (info.Name == parentName);
 061        var hasNullParent = (info.Parent == null);
 062        var hasTargetParent = !hasNullParent && (info.Parent?.Name == parentName);
 63
 064        if (!info.Exists) return null;
 065        if (isParent) return info;
 066        if (hasNullParent) return null;
 067        if (hasTargetParent) return info.Parent;
 68
 069        levels = Math.Abs(levels);
 070        --levels;
 71
 072        var hasNoMoreLevels = (levels == 0);
 73
 074        return hasNoMoreLevels ? null : FindParentDirectoryInfo(info.Parent?.FullName, parentName, levels);
 075    }
 76
 77    /// <summary>Combines path and root based
 78    /// on the ambient value of <see cref="Path.DirectorySeparatorChar"/>
 79    /// of the current OS.</summary>
 80    /// <param name="root">The root.</param>
 81    /// <param name="path">The path.</param>
 82    /// <remarks>
 83    /// For detail, see:
 84    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/14
 85    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/32
 86    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/97
 87    /// </remarks>
 88    public static string GetCombinedPath(string? root, string? path)
 7489    {
 7490        root.ThrowWhenNullOrWhiteSpace();
 7491        path.ThrowWhenNullOrWhiteSpace();
 92
 7493        path = GetRelativePath(path);
 94
 7495        return Path.IsPathRooted(path)
 7496            ? path
 7497            : Path.Combine(NormalizePath(root)!, path!);
 7498    }
 99
 100    /// <summary>Combines path and root based
 101    /// on the ambient value of <see cref="Path.DirectorySeparatorChar"/>
 102    /// of the current OS.</summary>
 103    /// <param name="root">The root.</param>
 104    /// <param name="path">The path.</param>
 105    /// <param name="fileIsExpected">
 106    /// when <c>true</c> will throw <see cref="FileNotFoundException"/>
 107    /// when combined path is not of a file; otherwise
 108    /// will throw <see cref="DirectoryNotFoundException"/>
 109    /// when combined path is not a directory
 110    /// </param>
 111    /// <remarks>
 112    /// For detail, see:
 113    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/14
 114    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/32
 115    /// 📚 https://github.com/BryanWilhite/SonghayCore/issues/97
 116    /// </remarks>
 117    public static string GetCombinedPath(string? root, string? path, bool fileIsExpected)
 6118    {
 6119        var combinedPath = GetCombinedPath(root, path);
 120
 6121        if (fileIsExpected)
 4122        {
 4123            if (!File.Exists(combinedPath))
 1124                throw new FileNotFoundException($"The expected file, `{combinedPath}`, is not here.");
 3125        }
 126        else
 2127        {
 2128            if (!Directory.Exists(combinedPath))
 1129                throw new DirectoryNotFoundException($"The expected directory, `{combinedPath}`, is not here.");
 1130        }
 131
 4132        return combinedPath;
 4133    }
 134
 135    /// <summary>
 136    /// Gets the parent directory.
 137    /// </summary>
 138    /// <param name="path">The path.</param>
 139    /// <param name="levels">The levels.</param>
 140    /// <remarks>
 141    /// A recursive wrapper for <see cref="Directory.GetParent(string)"/>.
 142    /// </remarks>
 143    public static string? GetParentDirectory(string? path, int levels)
 84144    {
 84145        path.ThrowWhenNullOrWhiteSpace();
 146
 84147        levels = Math.Abs(levels);
 84148        if (levels == 0) return path;
 149
 84150        var info = Directory.GetParent(path);
 84151        if (info == null) return path;
 84152        path = info.FullName;
 153
 84154        --levels;
 155
 84156        return levels >= 1 ? GetParentDirectory(path, levels) : path;
 84157    }
 158
 159    /// <summary>
 160    /// Gets the parent <see cref="DirectoryInfo"/>.
 161    /// </summary>
 162    /// <param name="path">The path.</param>
 163    /// <param name="levels">The levels.</param>
 164    /// <remarks>
 165    /// A recursive wrapper for <see cref="Directory.GetParent(string)"/>.
 166    /// </remarks>
 167    public static DirectoryInfo? GetParentDirectoryInfo(string? path, int levels)
 4168    {
 4169        path.ThrowWhenNullOrWhiteSpace();
 170
 4171        var info = new DirectoryInfo(path);
 172
 4173        levels = Math.Abs(levels);
 4174        if (levels == 0) return info;
 175
 4176        if (info.Parent == null) return info;
 4177        path = info.Parent.FullName;
 178
 4179        --levels;
 180
 4181        return (levels >= 1) ? GetParentDirectoryInfo(path, levels) : info.Parent;
 4182    }
 183
 184    /// <summary>
 185    /// Gets the relative path from the specified file segment
 186    /// without leading dots (<c>.</c>) or <see cref="Path.DirectorySeparatorChar" /> chars.
 187    /// </summary>
 188    /// <param name="fileSegment">The file segment.</param>
 189    /// <remarks>
 190    /// This method is the equivalent of calling:
 191    ///  * <see cref="TrimLeadingDirectorySeparatorChars(string)"/>
 192    ///  * <see cref="NormalizePath(string)"/>
 193    ///  * <see cref="RemoveBackslashPrefixes(string)"/>
 194    ///  * <see cref="RemoveForwardslashPrefixes(string)"/>
 195    /// </remarks>
 196    public static string? GetRelativePath(string? fileSegment)
 78197    {
 78198        fileSegment.ThrowWhenNullOrWhiteSpace();
 199
 78200        fileSegment = TrimLeadingDirectorySeparatorChars(fileSegment);
 78201        fileSegment = NormalizePath(fileSegment);
 78202        fileSegment = RemoveBackslashPrefixes(fileSegment);
 78203        fileSegment = RemoveForwardslashPrefixes(fileSegment);
 204
 78205        return fileSegment;
 78206    }
 207
 208    /// <summary>
 209    /// Returns <c>true</c> when the current OS
 210    /// uses forward-slash (<c>/</c>) paths or not.
 211    /// </summary>
 3212    public static bool IsForwardSlashSystem() => IsForwardSlashSystemField;
 213
 214    /// <summary>
 215    /// Normalizes the specified path with respect
 216    /// to the ambient value of <see cref="Path.DirectorySeparatorChar"/>.
 217    /// </summary>
 218    /// <param name="path">The path.</param>
 219    public static string? NormalizePath(string? path)
 177220    {
 177221        if (string.IsNullOrWhiteSpace(path)) return null;
 222
 177223        return IsForwardSlashSystemField
 177224            ? path.Replace(Backslash, ForwardSlash)
 177225            : path.Replace(ForwardSlash, Backslash);
 177226    }
 227
 228    /// <summary>
 229    /// Removes conventional Directory prefixes
 230    /// for relative paths, e.g. <c>..\</c> or <c>.\</c>
 231    /// </summary>
 232    /// <param name="path">The path.</param>
 233    public static string? RemoveBackslashPrefixes(string? path) =>
 78234        path?
 78235            .TrimStart(Backslash)
 78236            .Replace($"..{Backslash}", string.Empty)
 78237            .Replace($".{Backslash}", string.Empty);
 238
 239    /// <summary>
 240    /// Removes conventional Directory prefixes
 241    /// for relative paths based on the ambient value\
 242    /// of <see cref="Path.DirectorySeparatorChar"/>.
 243    /// </summary>
 244    /// <param name="path">The path.</param>
 245    public static string? RemoveConventionalPrefixes(string? path) =>
 0246        IsForwardSlashSystemField
 0247            ? RemoveForwardslashPrefixes(path)
 0248            : RemoveBackslashPrefixes(path);
 249
 250    /// <summary>
 251    /// Removes conventional Directory prefixes
 252    /// for relative paths, e.g. <c>../</c> or <c>./</c>.
 253    /// </summary>
 254    /// <param name="path">The path.</param>
 255    public static string? RemoveForwardslashPrefixes(string? path) =>
 78256        path?
 78257            .TrimStart(ForwardSlash)
 78258            .Replace($"..{ForwardSlash}", string.Empty)
 78259            .Replace($".{ForwardSlash}", string.Empty);
 260
 261    /// <summary>
 262    /// Trims the leading directory separator chars.
 263    /// </summary>
 264    /// <param name="path">The path.</param>
 265    /// <remarks>
 266    /// Trims leading <see cref="Path.AltDirectorySeparatorChar"/> and/or <see cref="Path.DirectorySeparatorChar"/>,
 267    /// formatting relative paths for <see cref="Path.Combine(string, string)"/>.
 268    /// </remarks>
 269    public static string? TrimLeadingDirectorySeparatorChars(string? path) =>
 104270        string.IsNullOrWhiteSpace(path) ? path : path.TrimStart(Backslash, ForwardSlash);
 271
 272    static readonly bool IsForwardSlashSystemField;
 273    static readonly char Backslash;
 274    static readonly char ForwardSlash;
 275}

/home/rasx/sourceRoot/SonghayCore/SonghayCore/ProgramFileUtility.Compression.cs

#LineLine coverage
 1namespace Songhay;
 2
 3public static partial class ProgramFileUtility
 4{
 5    /// <summary>
 6    /// Read zip archive entries.
 7    /// </summary>
 8    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 9    /// <param name="fileAction">The action to take per text file.</param>
 10    /// <remarks>
 11    /// Use <c>entriesProjector</c> for any filtering or sorting.
 12    /// </remarks>
 13    public static void ReadZipArchiveEntries(FileInfo? archiveInfo, Action<string>? fileAction) =>
 214        ReadZipArchiveEntries(archiveInfo, fileAction, entriesProjector: null);
 15
 16    /// <summary>
 17    /// Read zip archive entries.
 18    /// </summary>
 19    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 20    /// <param name="fileAction">The action to take per text file.</param>
 21    /// <param name="entriesProjector">The entries projector for LINQ filtering/sorting.</param>
 22    /// <remarks>
 23    /// Use <c>entriesProjector</c> for any filtering or sorting.
 24    /// </remarks>
 25    public static void ReadZipArchiveEntries(FileInfo? archiveInfo, Action<string>? fileAction,
 26        Func<ReadOnlyCollection<ZipArchiveEntry>, IEnumerable<ZipArchiveEntry>>? entriesProjector) =>
 427        UseZipArchiveEntries(archiveInfo,
 428            entries => entries.ForEachInEnumerable(i =>
 1629            {
 1630                TraceSource?.TraceVerbose(i.FullName);
 1631                using var entryStream = new StreamReader(i.Open());
 1632                var s = entryStream.ReadToEnd();
 1633                fileAction?.Invoke(s);
 3634            }),
 435            entriesProjector);
 36
 37    /// <summary>
 38    /// Read zip archive entries as strings, line by line.
 39    /// </summary>
 40    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 41    /// <param name="lineAction">The action to take per text file line.</param>
 42    /// <remarks>
 43    /// This member is designed for compressed text documents that are too large to load into memory.
 44    /// The <c>fileAction</c> includes the line number and the current line.
 45    /// </remarks>
 46    public static void ReadZipArchiveEntriesByLine(FileInfo? archiveInfo, Action<int, string>? lineAction) =>
 047        ReadZipArchiveEntriesByLine(archiveInfo, lineAction, entriesProjector: null);
 48
 49    /// <summary>
 50    /// Read zip archive entries as strings, line by line.
 51    /// </summary>
 52    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 53    /// <param name="lineAction">The action to take per text file line.</param>
 54    /// <param name="entriesProjector">The entries projector for LINQ filtering/sorting.</param>
 55    /// <remarks>
 56    /// This member is designed for compressed text documents that are too large to load into memory.
 57    /// The <c>fileAction</c> includes the line number and the current line.
 58    /// </remarks>
 59    public static void ReadZipArchiveEntriesByLine(FileInfo? archiveInfo, Action<int, string>? lineAction,
 60        Func<ReadOnlyCollection<ZipArchiveEntry>, IEnumerable<ZipArchiveEntry>>? entriesProjector)
 261    {
 262        UseZipArchiveEntries(archiveInfo,
 263            entries => entries.ForEachInEnumerable(i =>
 264            {
 265                TraceSource?.TraceVerbose(i.FullName);
 266                using var entryStream = new StreamReader(i.Open());
 267                string? line;
 268                var lineNumber = 0;
 1069                while ((line = entryStream.ReadLine()) != null)
 870                {
 871                    ++lineNumber;
 872                    lineAction?.Invoke(lineNumber, line);
 873                }
 674            }),
 275            entriesProjector);
 276    }
 77
 78    /// <summary>
 79    /// Centralizes the use of <see cref="ZipArchive"/>
 80    /// in <see cref="ZipArchiveMode.Read"/>.
 81    /// </summary>
 82    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 83    /// <param name="archiveAction">The action to take for the ZIP archive in use.</param>
 84    public static void UseZipArchive(FileInfo? archiveInfo, Action<ZipArchive?>? archiveAction) =>
 885        UseZipArchive(archiveInfo, archiveAction, ZipArchiveMode.Read);
 86
 87    /// <summary>
 88    /// Centralizes the use of <see cref="ZipArchive"/>
 89    /// </summary>
 90    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 91    /// <param name="archiveAction">The action to take for the ZIP archive in use.</param>
 92    /// <param name="zipArchiveMode">The <see cref="ZipArchiveMode"/>.</param>
 93    public static void UseZipArchive(FileInfo? archiveInfo, Action<ZipArchive?>? archiveAction,
 94        ZipArchiveMode zipArchiveMode)
 895    {
 896        ArgumentNullException.ThrowIfNull(archiveInfo);
 897        if (!archiveInfo.Exists)
 098            throw new FileNotFoundException($"The expected file {archiveInfo.FullName} is not here.");
 99
 8100        using var stream = new FileStream(archiveInfo.FullName, FileMode.Open);
 8101        using var zipFile = new ZipArchive(stream, zipArchiveMode, leaveOpen: false);
 102
 8103        archiveAction?.Invoke(zipFile);
 16104    }
 105
 106    /// <summary>
 107    /// Centralizes the use of <see cref="ReadOnlyCollection{ZipArchiveEntry}"/>.
 108    /// </summary>
 109    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 110    /// <param name="entriesAction">The action to take for ZIP archive entries.</param>
 111    public static void UseZipArchiveEntries(FileInfo? archiveInfo,
 112        Action<ReadOnlyCollection<ZipArchiveEntry>>? entriesAction) =>
 0113        UseZipArchiveEntries(archiveInfo, entriesAction, entriesProjector: null);
 114
 115    /// <summary>
 116    /// Centralizes the use of <see cref="ReadOnlyCollection{ZipArchiveEntry}"/>.
 117    /// </summary>
 118    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 119    /// <param name="entriesAction">The action to take for ZIP archive entries.</param>
 120    /// <param name="entriesProjector">The entries projector for LINQ filtering/sorting.</param>
 121    public static void UseZipArchiveEntries(FileInfo? archiveInfo,
 122        Action<ReadOnlyCollection<ZipArchiveEntry>>? entriesAction,
 123        Func<ReadOnlyCollection<ZipArchiveEntry>, IEnumerable<ZipArchiveEntry>>? entriesProjector)
 6124    {
 6125        UseZipArchive(archiveInfo, archive =>
 6126        {
 6127            if (archive == null) return;
 6128
 6129            var entries = archive.Entries;
 6130
 6131            if (entriesProjector != null)
 4132                entries = entriesProjector.Invoke(entries).ToList().AsReadOnly();
 6133
 6134            entriesAction?.Invoke(entries);
 12135        });
 6136    }
 137
 138    /// <summary>
 139    /// Write zip archive entry with <see cref="CompressionLevel.Optimal"/>.
 140    /// </summary>
 141    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 142    /// <param name="fileInfo">The file information for writing the entry.</param>
 143    public static void WriteZipArchiveEntry(FileInfo? archiveInfo, FileInfo fileInfo) =>
 0144        WriteZipArchiveEntry(archiveInfo, fileInfo, CompressionLevel.Optimal);
 145
 146    /// <summary>
 147    /// Write zip archive entry.
 148    /// </summary>
 149    /// <param name="archiveInfo">The ZIP archive <see cref="FileInfo"/>.</param>
 150    /// <param name="fileInfo">The file information for writing the entry.</param>
 151    /// <param name="compressionLevel">The <see cref="CompressionLevel"/>.</param>
 152    public static void WriteZipArchiveEntry(FileInfo? archiveInfo, FileInfo fileInfo,
 153        CompressionLevel compressionLevel) =>
 0154        UseZipArchive(archiveInfo, archive =>
 0155        {
 0156            if (archive == null) return;
 0157
 0158            var entry = archive.CreateEntry(fileInfo.Name, compressionLevel);
 0159            using var writer = new StreamWriter(entry.Open());
 0160            var s = File.ReadAllText(fileInfo.FullName);
 0161            writer.Write(s);
 0162            writer.Flush();
 0163        }, ZipArchiveMode.Update);
 164}

/home/rasx/sourceRoot/SonghayCore/SonghayCore/ProgramFileUtility.GetEncodedString.cs

#LineLine coverage
 1namespace Songhay;
 2
 3public static partial class ProgramFileUtility
 4{
 5    /// <summary>
 6    /// Gets the UTF-8 encoded string from.
 7    /// </summary>
 8    /// <param name="utf16Value">The raw value.</param>
 09    public static string GetEncodedString(string? utf16Value) => GetEncodedString(utf16Value, Encoding.UTF8);
 10
 11    /// <summary>
 12    /// Gets the encoded <see cref="string"/>
 13    /// from its default <see cref="Encoding.Unicode"/> encoding.
 14    /// </summary>
 15    /// <param name="utf16Value">The raw value.</param>
 16    /// <param name="outputEncoding">The output encoding.</param>
 17    /// <remarks>
 18    /// <see cref="Encoding.Unicode"/> encoding is the UTF-16
 19    /// encoding of strings in .NET.
 20    /// See: https://docs.microsoft.com/en-us/dotnet/api/system.text.unicodeencoding
 21    /// </remarks>
 22    public static string GetEncodedString(string? utf16Value, Encoding? outputEncoding)
 123    {
 124        utf16Value.ThrowWhenNullOrWhiteSpace();
 125        ArgumentNullException.ThrowIfNull(outputEncoding);
 26
 127        byte[] byteArray = Encoding.Convert(
 128            Encoding.Unicode,
 129            outputEncoding,
 130            Encoding.Unicode.GetBytes(utf16Value));
 31
 132        return new string(outputEncoding.GetChars(byteArray));
 133    }
 34}

Methods/Properties

.cctor()
CountParentDirectoryChars(System.String)
FindParentDirectory(System.String,System.String,System.Int32)
FindParentDirectoryInfo(System.String,System.String,System.Int32)
GetCombinedPath(System.String,System.String)
GetCombinedPath(System.String,System.String,System.Boolean)
GetParentDirectory(System.String,System.Int32)
GetParentDirectoryInfo(System.String,System.Int32)
GetRelativePath(System.String)
IsForwardSlashSystem()
NormalizePath(System.String)
RemoveBackslashPrefixes(System.String)
RemoveConventionalPrefixes(System.String)
RemoveForwardslashPrefixes(System.String)
TrimLeadingDirectorySeparatorChars(System.String)
ReadZipArchiveEntries(System.IO.FileInfo,System.Action`1<System.String>)
ReadZipArchiveEntries(System.IO.FileInfo,System.Action`1<System.String>,System.Func`2<System.Collections.ObjectModel.ReadOnlyCollection`1<System.IO.Compression.ZipArchiveEntry>,System.Collections.Generic.IEnumerable`1<System.IO.Compression.ZipArchiveEntry>>)
ReadZipArchiveEntriesByLine(System.IO.FileInfo,System.Action`2<System.Int32,System.String>)
ReadZipArchiveEntriesByLine(System.IO.FileInfo,System.Action`2<System.Int32,System.String>,System.Func`2<System.Collections.ObjectModel.ReadOnlyCollection`1<System.IO.Compression.ZipArchiveEntry>,System.Collections.Generic.IEnumerable`1<System.IO.Compression.ZipArchiveEntry>>)
UseZipArchive(System.IO.FileInfo,System.Action`1<System.IO.Compression.ZipArchive>)
UseZipArchive(System.IO.FileInfo,System.Action`1<System.IO.Compression.ZipArchive>,System.IO.Compression.ZipArchiveMode)
UseZipArchiveEntries(System.IO.FileInfo,System.Action`1<System.Collections.ObjectModel.ReadOnlyCollection`1<System.IO.Compression.ZipArchiveEntry>>)
UseZipArchiveEntries(System.IO.FileInfo,System.Action`1<System.Collections.ObjectModel.ReadOnlyCollection`1<System.IO.Compression.ZipArchiveEntry>>,System.Func`2<System.Collections.ObjectModel.ReadOnlyCollection`1<System.IO.Compression.ZipArchiveEntry>,System.Collections.Generic.IEnumerable`1<System.IO.Compression.ZipArchiveEntry>>)
WriteZipArchiveEntry(System.IO.FileInfo,System.IO.FileInfo)
WriteZipArchiveEntry(System.IO.FileInfo,System.IO.FileInfo,System.IO.Compression.CompressionLevel)
GetEncodedString(System.String)
GetEncodedString(System.String,System.Text.Encoding)