Remove dotnet-archive and Microsoft.Dotnet.Archive

This commit is contained in:
John Luo 2017-06-22 12:47:06 -07:00
parent 7d3461eed4
commit 0e4db81898
36 changed files with 3 additions and 5591 deletions

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26507.0
VisualStudioVersion = 15.0.26510.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}"
EndProject
@ -39,10 +39,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartRequestDelegateUrlApp"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateDefaultBuilderApp", "test\TestSites\CreateDefaultBuilderApp\CreateDefaultBuilderApp.csproj", "{79CF58CE-B020-45D8-BDB5-2D8036BEAD14}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-archive", "src\dotnet-archive\dotnet-archive.csproj", "{AE4216BF-D471-471B-82F3-6B6D004F7D17}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Archive", "src\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj", "{302400A0-98BB-4C04-88D4-C32DC2D4B945}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrimDeps", "tools\TrimDeps\TrimDeps.csproj", "{67E4C92F-6D12-4C52-BB79-B8D11BFC6B82}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjectionApp", "test\TestSites\DependencyInjectionApp\DependencyInjectionApp.csproj", "{65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}"
@ -85,14 +81,6 @@ Global
{79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Release|Any CPU.Build.0 = Release|Any CPU
{AE4216BF-D471-471B-82F3-6B6D004F7D17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE4216BF-D471-471B-82F3-6B6D004F7D17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE4216BF-D471-471B-82F3-6B6D004F7D17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE4216BF-D471-471B-82F3-6B6D004F7D17}.Release|Any CPU.Build.0 = Release|Any CPU
{302400A0-98BB-4C04-88D4-C32DC2D4B945}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{302400A0-98BB-4C04-88D4-C32DC2D4B945}.Debug|Any CPU.Build.0 = Debug|Any CPU
{302400A0-98BB-4C04-88D4-C32DC2D4B945}.Release|Any CPU.ActiveCfg = Release|Any CPU
{302400A0-98BB-4C04-88D4-C32DC2D4B945}.Release|Any CPU.Build.0 = Release|Any CPU
{67E4C92F-6D12-4C52-BB79-B8D11BFC6B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67E4C92F-6D12-4C52-BB79-B8D11BFC6B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67E4C92F-6D12-4C52-BB79-B8D11BFC6B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -116,8 +104,6 @@ Global
{3A85FA52-F601-422E-A42E-9F187DB28492} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4}
{401C741B-6C7C-4E08-9F09-C3D43D22C0DE} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4}
{79CF58CE-B020-45D8-BDB5-2D8036BEAD14} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4}
{AE4216BF-D471-471B-82F3-6B6D004F7D17} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
{302400A0-98BB-4C04-88D4-C32DC2D4B945} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
{67E4C92F-6D12-4C52-BB79-B8D11BFC6B82} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}
{65FE2E38-4529-4C93-A7B0-CF12DD7A70C3} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4}
EndGlobalSection

View File

@ -2,7 +2,5 @@
<ItemGroup>
<ExcludeFromPack Include="$(RepositoryRoot)src\Microsoft.AspNetCore.RuntimeStore\Microsoft.AspNetCore.RuntimeStore.csproj" />
<ExcludeFromPack Include="$(RepositoryRoot)src\Archive.AspNetCore.All\Archive.AspNetCore.All.csproj" />
<ExcludeFromPack Include="$(RepositoryRoot)src\dotnet-archive\dotnet-archive.csproj" />
<ExcludeFromPack Include="$(RepositoryRoot)src\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj" />
</ItemGroup>
</Project>

View File

@ -12,8 +12,6 @@
<!-- Project for building the NuGet Fallback Archive (LZMA for CLI) -->
<FallbackArchiveDir>$(RepositoryRoot)src\Archive.AspNetCore.All\</FallbackArchiveDir>
<FallbackArchiveProj>$(FallbackArchiveDir)Archive.AspNetCore.All.csproj</FallbackArchiveProj>
<ArchiverProject>$(RepositoryRoot)src\dotnet-archive\dotnet-archive.csproj</ArchiverProject>
<ArchiverBinary>$(RepositoryRoot)src\dotnet-archive\bin\$(Configuration)\netcoreapp2.0\dotnet-archive.dll</ArchiverBinary>
<!-- Determine ASP.NET Package Version -->
<NoTimestampSuffix Condition="'$(TIMESTAMP_FREE_VERSION)' != ''">$(TIMESTAMP_FREE_VERSION)</NoTimestampSuffix>
@ -274,10 +272,6 @@
<TimestampSource>$(COHERENCE_SIGNED_DROP_LOCATION)\Signed\Packages</TimestampSource>
</PropertyGroup>
<!-- Build the dotnet-archiver project -->
<MSBuild Projects="$(ArchiverProject)" Targets="Restore" Properties="Configuration=$(Configuration)" />
<MSBuild Projects="$(ArchiverProject)" Targets="Build" Properties="Configuration=$(Configuration)" />
<!-- Run the actual target twice, once for timestamped packages, once for non-timestamped packages -->
<!-- Here, we're re-invoking KoreBuild, but limiting it to a specific target. -->
<!-- This won't rerun the whole build, but it ensures that the necessary MSBuild Tasks and Properties are initialized -->

View File

@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\build\dependencies.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

View File

@ -1,107 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using SevenZip;
using System;
using System.IO;
namespace Microsoft.DotNet.Archive
{
internal static class CompressionUtility
{
enum MeasureBy
{
Input,
Output
}
private class LzmaProgress : ICodeProgress
{
private IProgress<ProgressReport> progress;
private long totalSize;
private string phase;
private MeasureBy measureBy;
public LzmaProgress(IProgress<ProgressReport> progress, string phase, long totalSize, MeasureBy measureBy)
{
this.progress = progress;
this.totalSize = totalSize;
this.phase = phase;
this.measureBy = measureBy;
}
public void SetProgress(long inSize, long outSize)
{
progress.Report(phase, measureBy == MeasureBy.Input ? inSize : outSize, totalSize);
}
}
public static void Compress(Stream inStream, Stream outStream, IProgress<ProgressReport> progress)
{
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
CoderPropID[] propIDs =
{
CoderPropID.DictionarySize,
CoderPropID.PosStateBits,
CoderPropID.LitContextBits,
CoderPropID.LitPosBits,
CoderPropID.Algorithm,
CoderPropID.NumFastBytes,
CoderPropID.MatchFinder,
CoderPropID.EndMarker
};
object[] properties =
{
(Int32)(1 << 26),
(Int32)(1),
(Int32)(8),
(Int32)(0),
(Int32)(2),
(Int32)(96),
"bt4",
false
};
encoder.SetCoderProperties(propIDs, properties);
encoder.WriteCoderProperties(outStream);
Int64 inSize = inStream.Length;
for (int i = 0; i < 8; i++)
{
outStream.WriteByte((Byte)(inSize >> (8 * i)));
}
var lzmaProgress = new LzmaProgress(progress, "Compressing", inSize, MeasureBy.Input);
lzmaProgress.SetProgress(0, 0);
encoder.Code(inStream, outStream, -1, -1, lzmaProgress);
lzmaProgress.SetProgress(inSize, outStream.Length);
}
public static void Decompress(Stream inStream, Stream outStream, IProgress<ProgressReport> progress)
{
byte[] properties = new byte[5];
if (inStream.Read(properties, 0, 5) != 5)
throw (new Exception("input .lzma is too short"));
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
decoder.SetDecoderProperties(properties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = inStream.ReadByte();
if (v < 0)
throw (new Exception("Can't Read 1"));
outSize |= ((long)(byte)v) << (8 * i);
}
long compressedSize = inStream.Length - inStream.Position;
var lzmaProgress = new LzmaProgress(progress, "Decompressing", outSize, MeasureBy.Output);
lzmaProgress.SetProgress(0, 0);
decoder.Code(inStream, outStream, compressedSize, outSize, lzmaProgress);
lzmaProgress.SetProgress(inStream.Length, outSize);
}
}
}

View File

@ -1,59 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Diagnostics;
namespace Microsoft.DotNet.Archive
{
public class ConsoleProgressReport : IProgress<ProgressReport>
{
private string _currentPhase;
private int _lastLineLength = 0;
private double _lastProgress = -1;
private Stopwatch _stopwatch;
private object _stateLock = new object();
public void Report(ProgressReport value)
{
long progress = (long)(100 * ((double)value.Ticks / value.Total));
if (progress == _lastProgress && value.Phase == _currentPhase)
{
return;
}
_lastProgress = progress;
lock (_stateLock)
{
string line = $"{value.Phase} {progress}%";
if (value.Phase == _currentPhase)
{
if (Console.IsOutputRedirected)
{
Console.Write($"...{progress}%");
}
else
{
Console.Write(new string('\b', _lastLineLength));
Console.Write(line);
}
_lastLineLength = line.Length;
if (progress == 100)
{
Console.WriteLine($" {_stopwatch.ElapsedMilliseconds} ms");
}
}
else
{
Console.Write(line);
_currentPhase = value.Phase;
_lastLineLength = line.Length;
_stopwatch = Stopwatch.StartNew();
}
}
}
}
}

View File

@ -1,541 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace Microsoft.DotNet.Archive
{
public class IndexedArchive : IDisposable
{
private class DestinationFileInfo
{
public DestinationFileInfo(string destinationPath, string hash)
{
// Normalize the path
DestinationPath = destinationPath.Replace(Path.DirectorySeparatorChar, '/');
Hash = hash;
}
public string DestinationPath { get; }
public string Hash { get; }
}
private class ArchiveSource
{
public ArchiveSource(string sourceArchive, string sourceFile, string archivePath, string hash, long size)
{
Hash = hash;
Size = size;
// Normalize the paths
SourceArchive = sourceArchive?.Replace(Path.DirectorySeparatorChar, '/');
SourceFile = sourceFile.Replace(Path.DirectorySeparatorChar, '/');
ArchivePath = archivePath.Replace(Path.DirectorySeparatorChar, '/');
}
public string SourceArchive { get; set; }
public string SourceFile { get; set; }
public string ArchivePath { get; }
public string Hash { get; }
public string FileName { get { return Path.GetFileNameWithoutExtension(ArchivePath); } }
public string Extension { get { return Path.GetExtension(ArchivePath); } }
public long Size { get; }
public void CopyTo(Stream destination)
{
if (!String.IsNullOrEmpty(SourceArchive))
{
using (var zip = new ZipArchive(File.OpenRead(SourceArchive), ZipArchiveMode.Read))
using (var sourceStream = zip.GetEntry(SourceFile)?.Open())
{
if (sourceStream == null)
{
throw new Exception($"Couldn't find entry {SourceFile} in archive {SourceArchive}");
}
sourceStream.CopyTo(destination);
}
}
else
{
using (var sourceStream = File.OpenRead(SourceFile))
{
sourceStream.CopyTo(destination);
}
}
}
}
static string[] ZipExtensions = new[] { ".zip", ".nupkg" };
static string IndexFileName = "index.txt";
// maps file hash to archve path
// $ prefix indicates that the file is not in the archive and path is a hash
private Dictionary<string, ArchiveSource> _archiveFiles = new Dictionary<string, ArchiveSource>();
// maps file hash to external path
private Dictionary<string, string> _externalFiles = new Dictionary<string, string>();
// lists all extracted files & hashes
private List<DestinationFileInfo> _destFiles = new List<DestinationFileInfo>();
private bool _disposed = false;
private ThreadLocal<SHA256> _sha = new ThreadLocal<SHA256>(() => SHA256.Create());
public IndexedArchive()
{ }
private static Stream CreateTemporaryStream()
{
string temp = Path.GetTempPath();
string tempFile = Path.Combine(temp, Guid.NewGuid().ToString());
return File.Create(tempFile, 4096, FileOptions.DeleteOnClose);
}
private static FileStream CreateTemporaryFileStream()
{
string temp = Path.GetTempPath();
string tempFile = Path.Combine(temp, Guid.NewGuid().ToString());
return new FileStream(tempFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete, 4096, FileOptions.DeleteOnClose);
}
public void Save(string archivePath, IProgress<ProgressReport> progress)
{
CheckDisposed();
using (var archiveStream = CreateTemporaryStream())
{
using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true))
{
BuildArchive(archive, progress);
} // close archive
archiveStream.Seek(0, SeekOrigin.Begin);
using (var lzmaStream = File.Create(archivePath))
{
CompressionUtility.Compress(archiveStream, lzmaStream, progress);
}
} // close archiveStream
}
private void BuildArchive(ZipArchive archive, IProgress<ProgressReport> progress)
{
// write the file index
var indexEntry = archive.CreateEntry(IndexFileName, CompressionLevel.NoCompression);
using (var stream = indexEntry.Open())
using (var textWriter = new StreamWriter(stream))
{
foreach (var entry in _destFiles)
{
var archiveFile = _archiveFiles[entry.Hash];
string archivePath = _archiveFiles[entry.Hash].ArchivePath;
if (archiveFile.SourceFile == null)
{
archivePath = "$" + archivePath;
}
textWriter.WriteLine($"{entry.DestinationPath}|{archivePath}");
}
}
// sort the files so that similar files are close together
var filesToArchive = _archiveFiles.Values.ToList();
filesToArchive.Sort((f1, f2) =>
{
// first sort by extension
var comp = String.Compare(f1.Extension, f2.Extension, StringComparison.OrdinalIgnoreCase);
if (comp == 0)
{
// then sort by filename
comp = String.Compare(f1.FileName, f2.FileName, StringComparison.OrdinalIgnoreCase);
}
if (comp == 0)
{
// sort by file size (helps differentiate ref/lib/facade)
comp = f1.Size.CompareTo(f2.Size);
}
if (comp == 0)
{
// finally sort by full archive path so we have stable output
comp = String.Compare(f1.ArchivePath, f2.ArchivePath, StringComparison.OrdinalIgnoreCase);
}
return comp;
});
int filesAdded = 0;
// add all the files
foreach (var fileToArchive in filesToArchive)
{
var entry = archive.CreateEntry(fileToArchive.ArchivePath, CompressionLevel.NoCompression);
using (var entryStream = entry.Open())
{
fileToArchive.CopyTo(entryStream);
}
progress.Report("Archiving files", ++filesAdded, filesToArchive.Count);
}
}
private abstract class ExtractOperation
{
public ExtractOperation(string destinationPath)
{
DestinationPath = destinationPath;
}
public string DestinationPath { get; }
public virtual void DoOperation()
{
string directory = Path.GetDirectoryName(DestinationPath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
Execute();
}
protected abstract void Execute();
}
private class CopyOperation : ExtractOperation
{
public CopyOperation(ExtractSource source, string destinationPath) : base(destinationPath)
{
Source = source;
}
public ExtractSource Source { get; }
protected override void Execute()
{
if (Source.LocalPath != null)
{
File.Copy(Source.LocalPath, DestinationPath, true);
}
else
{
using (var destinationStream = File.Create(DestinationPath))
{
Source.CopyToStream(destinationStream);
}
}
}
}
private class ZipOperation : ExtractOperation
{
public ZipOperation(string destinationPath) : base(destinationPath)
{
}
private List<Tuple<string, ExtractSource>> entries = new List<Tuple<string, ExtractSource>>();
public void AddEntry(string entryName, ExtractSource source)
{
entries.Add(Tuple.Create(entryName, source));
}
protected override void Execute()
{
using (var archiveStream = File.Create(DestinationPath))
using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create))
{
foreach (var zipSource in entries)
{
var entry = archive.CreateEntry(zipSource.Item1, CompressionLevel.Optimal);
using (var entryStream = entry.Open())
{
zipSource.Item2.CopyToStream(entryStream);
}
}
}
}
}
private class ExtractSource
{
private string _entryName;
private readonly string _localPath;
private ThreadLocalZipArchive _archive;
public ExtractSource(string sourceString, Dictionary<string, string> externalFiles, ThreadLocalZipArchive archive)
{
if (sourceString[0] == '$')
{
var externalHash = sourceString.Substring(1);
if (!externalFiles.TryGetValue(externalHash, out _localPath))
{
throw new Exception("Could not find external file with hash {externalHash}.");
}
}
else
{
_entryName = sourceString;
_archive = archive;
}
}
public string LocalPath { get { return _localPath; } }
public void CopyToStream(Stream destinationStream)
{
if (_localPath != null)
{
using (var sourceStream = File.OpenRead(_localPath))
{
sourceStream.CopyTo(destinationStream);
}
}
else
{
using (var sourceStream = _archive.Archive.GetEntry(_entryName).Open())
{
sourceStream.CopyTo(destinationStream);
}
}
}
}
private static char[] pipeSeperator = new[] { '|' };
public void Extract(string compressedArchivePath, string outputDirectory, IProgress<ProgressReport> progress)
{
using (var archiveStream = CreateTemporaryFileStream())
{
// decompress the LZMA stream
using (var lzmaStream = File.OpenRead(compressedArchivePath))
{
CompressionUtility.Decompress(lzmaStream, archiveStream, progress);
}
var archivePath = ((FileStream)archiveStream).Name;
// reset the uncompressed stream
archiveStream.Seek(0, SeekOrigin.Begin);
// read as a zip archive
using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Read))
using (var tlArchive = new ThreadLocalZipArchive(archivePath, archive))
{
List<ExtractOperation> extractOperations = new List<ExtractOperation>();
Dictionary<string, ExtractSource> sourceCache = new Dictionary<string, ExtractSource>();
// process the index to determine all extraction operations
var indexEntry = archive.GetEntry(IndexFileName);
using (var indexReader = new StreamReader(indexEntry.Open()))
{
Dictionary<string, ZipOperation> zipOperations = new Dictionary<string, ZipOperation>(StringComparer.OrdinalIgnoreCase);
for (var line = indexReader.ReadLine(); line != null; line = indexReader.ReadLine())
{
var lineParts = line.Split(pipeSeperator);
if (lineParts.Length != 2)
{
throw new Exception("Unexpected index line format, too many '|'s.");
}
string target = lineParts[0];
string source = lineParts[1];
ExtractSource extractSource;
if (!sourceCache.TryGetValue(source, out extractSource))
{
sourceCache[source] = extractSource = new ExtractSource(source, _externalFiles, tlArchive);
}
var zipSeperatorIndex = target.IndexOf("::", StringComparison.OrdinalIgnoreCase);
if (zipSeperatorIndex != -1)
{
string zipRelativePath = target.Substring(0, zipSeperatorIndex);
string zipEntryName = target.Substring(zipSeperatorIndex + 2);
string destinationPath = Path.Combine(outputDirectory, zipRelativePath);
// operations on a zip file will be sequential
ZipOperation currentZipOperation;
if (!zipOperations.TryGetValue(destinationPath, out currentZipOperation))
{
extractOperations.Add(currentZipOperation = new ZipOperation(destinationPath));
zipOperations.Add(destinationPath, currentZipOperation);
}
currentZipOperation.AddEntry(zipEntryName, extractSource);
}
else
{
string destinationPath = Path.Combine(outputDirectory, target);
extractOperations.Add(new CopyOperation(extractSource, destinationPath));
}
}
}
int opsExecuted = 0;
// execute all operations
//foreach(var extractOperation in extractOperations)
extractOperations.AsParallel().ForAll(extractOperation =>
{
extractOperation.DoOperation();
progress.Report("Expanding", Interlocked.Increment(ref opsExecuted), extractOperations.Count);
});
}
}
}
public void AddExternalDirectory(string externalDirectory)
{
CheckDisposed();
foreach (var externalFile in Directory.EnumerateFiles(externalDirectory, "*", SearchOption.AllDirectories))
{
AddExternalFile(externalFile);
}
}
public void AddExternalFile(string externalFile)
{
CheckDisposed();
using (var fs = File.OpenRead(externalFile))
{
string hash = GetHash(fs);
// $ prefix indicates that the file is not in the archive and path is relative to an external directory
_archiveFiles[hash] = new ArchiveSource(null, null, "$" + hash, hash, fs.Length);
_externalFiles[hash] = externalFile;
}
}
public void AddDirectory(string sourceDirectory, IProgress<ProgressReport> progress, string destinationDirectory = null)
{
var sourceFiles = Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories).ToArray();
int filesAdded = 0;
sourceFiles.AsParallel().ForAll(sourceFile =>
{
// path relative to the destination/extracted directory to write the file
string destinationRelativePath = sourceFile.Substring(sourceDirectory.Length + 1);
if (destinationDirectory != null)
{
destinationRelativePath = Path.Combine(destinationDirectory, destinationRelativePath);
}
string extension = Path.GetExtension(sourceFile);
if (ZipExtensions.Any(ze => ze.Equals(extension, StringComparison.OrdinalIgnoreCase)))
{
AddZip(sourceFile, destinationRelativePath);
}
else
{
AddFile(sourceFile, destinationRelativePath);
}
progress.Report($"Adding {sourceDirectory}", Interlocked.Increment(ref filesAdded), sourceFiles.Length);
});
}
public void AddZip(string sourceZipFile, string destinationZipFile)
{
CheckDisposed();
using (var sourceArchive = new ZipArchive(File.OpenRead(sourceZipFile), ZipArchiveMode.Read))
{
foreach (var entry in sourceArchive.Entries)
{
string hash = null;
long size = entry.Length;
string destinationPath = $"{destinationZipFile}::{entry.FullName}";
using (var stream = entry.Open())
{
hash = GetHash(stream);
}
AddArchiveSource(sourceZipFile, entry.FullName, destinationPath, hash, size);
}
}
}
public void AddFile(string sourceFilePath, string destinationPath)
{
CheckDisposed();
string hash;
long size;
// lifetime of this stream is managed by AddStream
using (var stream = File.Open(sourceFilePath, FileMode.Open))
{
hash = GetHash(stream);
size = stream.Length;
}
AddArchiveSource(null, sourceFilePath, destinationPath, hash, size);
}
private void AddArchiveSource(string sourceArchive, string sourceFile, string destinationPath, string hash, long size)
{
lock (_archiveFiles)
{
_destFiles.Add(new DestinationFileInfo(destinationPath, hash));
// see if we already have this file in the archive/external
ArchiveSource existing = null;
if (_archiveFiles.TryGetValue(hash, out existing))
{
// if we have raw source file, prefer that over a zipped source file
if (sourceArchive == null && existing.SourceArchive != null)
{
existing.SourceArchive = null;
existing.SourceFile = sourceFile;
}
}
else
{
var archivePath = Path.Combine(hash, Path.GetFileName(destinationPath));
_archiveFiles.Add(hash, new ArchiveSource(sourceArchive, sourceFile, archivePath, hash, size));
}
}
}
public string GetHash(Stream stream)
{
var hashBytes = _sha.Value.ComputeHash(stream);
return GetHashString(hashBytes);
}
private static string GetHashString(byte[] hashBytes)
{
StringBuilder builder = new StringBuilder(hashBytes.Length * 2);
foreach (var b in hashBytes)
{
builder.AppendFormat("{0:x2}", b);
}
return builder.ToString();
}
public void Dispose()
{
if (!_disposed)
{
if (_sha != null)
{
_sha.Dispose();
_sha = null;
}
}
}
private void CheckDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(IndexedArchive));
}
}
}
}

View File

@ -1,58 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// Common/CRC.cs
namespace SevenZip
{
class CRC
{
public static readonly uint[] Table;
static CRC()
{
Table = new uint[256];
const uint kPoly = 0xEDB88320;
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (int j = 0; j < 8; j++)
if ((r & 1) != 0)
r = (r >> 1) ^ kPoly;
else
r >>= 1;
Table[i] = r;
}
}
uint _value = 0xFFFFFFFF;
public void Init() { _value = 0xFFFFFFFF; }
public void UpdateByte(byte b)
{
_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
}
public void Update(byte[] data, uint offset, uint size)
{
for (uint i = 0; i < size; i++)
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
}
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
static uint CalculateDigest(byte[] data, uint offset, uint size)
{
CRC crc = new CRC();
// crc.Init();
crc.Update(data, offset, size);
return crc.GetDigest();
}
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
{
return (CalculateDigest(data, offset, size) == digest);
}
}
}

View File

@ -1,75 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// InBuffer.cs
namespace SevenZip.Buffer
{
public class InBuffer
{
byte[] m_Buffer;
uint m_Pos;
uint m_Limit;
uint m_BufferSize;
System.IO.Stream m_Stream;
bool m_StreamWasExhausted;
ulong m_ProcessedSize;
public InBuffer(uint bufferSize)
{
m_Buffer = new byte[bufferSize];
m_BufferSize = bufferSize;
}
public void Init(System.IO.Stream stream)
{
m_Stream = stream;
m_ProcessedSize = 0;
m_Limit = 0;
m_Pos = 0;
m_StreamWasExhausted = false;
}
public bool ReadBlock()
{
if (m_StreamWasExhausted)
return false;
m_ProcessedSize += m_Pos;
int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
m_Pos = 0;
m_Limit = (uint)aNumProcessedBytes;
m_StreamWasExhausted = (aNumProcessedBytes == 0);
return (!m_StreamWasExhausted);
}
public void ReleaseStream()
{
// m_Stream.Close();
m_Stream = null;
}
public bool ReadByte(byte b) // check it
{
if (m_Pos >= m_Limit)
if (!ReadBlock())
return false;
b = m_Buffer[m_Pos++];
return true;
}
public byte ReadByte()
{
// return (byte)m_Stream.ReadByte();
if (m_Pos >= m_Limit)
if (!ReadBlock())
return 0xFF;
return m_Buffer[m_Pos++];
}
public ulong GetProcessedSize()
{
return m_ProcessedSize + m_Pos;
}
}
}

View File

@ -1,50 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// OutBuffer.cs
namespace SevenZip.Buffer
{
public class OutBuffer
{
byte[] m_Buffer;
uint m_Pos;
uint m_BufferSize;
System.IO.Stream m_Stream;
ulong m_ProcessedSize;
public OutBuffer(uint bufferSize)
{
m_Buffer = new byte[bufferSize];
m_BufferSize = bufferSize;
}
public void SetStream(System.IO.Stream stream) { m_Stream = stream; }
public void FlushStream() { m_Stream.Flush(); }
public void CloseStream() { m_Stream.Dispose(); }
public void ReleaseStream() { m_Stream = null; }
public void Init()
{
m_ProcessedSize = 0;
m_Pos = 0;
}
public void WriteByte(byte b)
{
m_Buffer[m_Pos++] = b;
if (m_Pos >= m_BufferSize)
FlushData();
}
public void FlushData()
{
if (m_Pos == 0)
return;
m_Stream.Write(m_Buffer, 0, (int)m_Pos);
m_Pos = 0;
}
public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; }
}
}

View File

@ -1,27 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// IMatchFinder.cs
using System;
namespace SevenZip.Compression.LZ
{
interface IInWindowStream
{
void SetStream(System.IO.Stream inStream);
void Init();
void ReleaseStream();
Byte GetIndexByte(Int32 index);
UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
UInt32 GetNumAvailableBytes();
}
interface IMatchFinder : IInWindowStream
{
void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
UInt32 GetMatches(UInt32[] distances);
void Skip(UInt32 num);
}
}

View File

@ -1,370 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// LzBinTree.cs
using System;
namespace SevenZip.Compression.LZ
{
public class BinTree : InWindow, IMatchFinder
{
UInt32 _cyclicBufferPos;
UInt32 _cyclicBufferSize = 0;
UInt32 _matchMaxLen;
UInt32[] _son;
UInt32[] _hash;
UInt32 _cutValue = 0xFF;
UInt32 _hashMask;
UInt32 _hashSizeSum = 0;
bool HASH_ARRAY = true;
const UInt32 kHash2Size = 1 << 10;
const UInt32 kHash3Size = 1 << 16;
const UInt32 kBT2HashSize = 1 << 16;
const UInt32 kStartMaxLen = 1;
const UInt32 kHash3Offset = kHash2Size;
const UInt32 kEmptyHashValue = 0;
const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;
UInt32 kNumHashDirectBytes = 0;
UInt32 kMinMatchCheck = 4;
UInt32 kFixHashSize = kHash2Size + kHash3Size;
public void SetType(int numHashBytes)
{
HASH_ARRAY = (numHashBytes > 2);
if (HASH_ARRAY)
{
kNumHashDirectBytes = 0;
kMinMatchCheck = 4;
kFixHashSize = kHash2Size + kHash3Size;
}
else
{
kNumHashDirectBytes = 2;
kMinMatchCheck = 2 + 1;
kFixHashSize = 0;
}
}
public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }
public new void ReleaseStream() { base.ReleaseStream(); }
public new void Init()
{
base.Init();
for (UInt32 i = 0; i < _hashSizeSum; i++)
_hash[i] = kEmptyHashValue;
_cyclicBufferPos = 0;
ReduceOffsets(-1);
}
public new void MovePos()
{
if (++_cyclicBufferPos >= _cyclicBufferSize)
_cyclicBufferPos = 0;
base.MovePos();
if (_pos == kMaxValForNormalize)
Normalize();
}
public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }
public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
{ return base.GetMatchLen(index, distance, limit); }
public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }
public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
{
if (historySize > kMaxValForNormalize - 256)
throw new Exception();
_cutValue = 16 + (matchMaxLen >> 1);
UInt32 windowReservSize = (historySize + keepAddBufferBefore +
matchMaxLen + keepAddBufferAfter) / 2 + 256;
base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
_matchMaxLen = matchMaxLen;
UInt32 cyclicBufferSize = historySize + 1;
if (_cyclicBufferSize != cyclicBufferSize)
_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
UInt32 hs = kBT2HashSize;
if (HASH_ARRAY)
{
hs = historySize - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
hs |= (hs >> 8);
hs >>= 1;
hs |= 0xFFFF;
if (hs > (1 << 24))
hs >>= 1;
_hashMask = hs;
hs++;
hs += kFixHashSize;
}
if (hs != _hashSizeSum)
_hash = new UInt32[_hashSizeSum = hs];
}
public UInt32 GetMatches(UInt32[] distances)
{
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kMinMatchCheck)
{
MovePos();
return 0;
}
}
UInt32 offset = 0;
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
UInt32 cur = _bufferOffset + _pos;
UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
UInt32 hashValue, hash2Value = 0, hash3Value = 0;
if (HASH_ARRAY)
{
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
hash2Value = temp & (kHash2Size - 1);
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
hash3Value = temp & (kHash3Size - 1);
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
}
else
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
UInt32 curMatch = _hash[kFixHashSize + hashValue];
if (HASH_ARRAY)
{
UInt32 curMatch2 = _hash[hash2Value];
UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
_hash[hash2Value] = _pos;
_hash[kHash3Offset + hash3Value] = _pos;
if (curMatch2 > matchMinPos)
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
{
distances[offset++] = maxLen = 2;
distances[offset++] = _pos - curMatch2 - 1;
}
if (curMatch3 > matchMinPos)
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
{
if (curMatch3 == curMatch2)
offset -= 2;
distances[offset++] = maxLen = 3;
distances[offset++] = _pos - curMatch3 - 1;
curMatch2 = curMatch3;
}
if (offset != 0 && curMatch2 == curMatch)
{
offset -= 2;
maxLen = kStartMaxLen;
}
}
_hash[kFixHashSize + hashValue] = _pos;
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
UInt32 ptr1 = (_cyclicBufferPos << 1);
UInt32 len0, len1;
len0 = len1 = kNumHashDirectBytes;
if (kNumHashDirectBytes != 0)
{
if (curMatch > matchMinPos)
{
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
_bufferBase[cur + kNumHashDirectBytes])
{
distances[offset++] = maxLen = kNumHashDirectBytes;
distances[offset++] = _pos - curMatch - 1;
}
}
}
UInt32 count = _cutValue;
while(true)
{
if(curMatch <= matchMinPos || count-- == 0)
{
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
break;
}
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
UInt32 pby1 = _bufferOffset + curMatch;
UInt32 len = Math.Min(len0, len1);
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
{
while(++len != lenLimit)
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
break;
if (maxLen < len)
{
distances[offset++] = maxLen = len;
distances[offset++] = delta - 1;
if (len == lenLimit)
{
_son[ptr1] = _son[cyclicPos];
_son[ptr0] = _son[cyclicPos + 1];
break;
}
}
}
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
{
_son[ptr1] = curMatch;
ptr1 = cyclicPos + 1;
curMatch = _son[ptr1];
len1 = len;
}
else
{
_son[ptr0] = curMatch;
ptr0 = cyclicPos;
curMatch = _son[ptr0];
len0 = len;
}
}
MovePos();
return offset;
}
public void Skip(UInt32 num)
{
do
{
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kMinMatchCheck)
{
MovePos();
continue;
}
}
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
UInt32 cur = _bufferOffset + _pos;
UInt32 hashValue;
if (HASH_ARRAY)
{
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
UInt32 hash2Value = temp & (kHash2Size - 1);
_hash[hash2Value] = _pos;
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
UInt32 hash3Value = temp & (kHash3Size - 1);
_hash[kHash3Offset + hash3Value] = _pos;
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
}
else
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
UInt32 curMatch = _hash[kFixHashSize + hashValue];
_hash[kFixHashSize + hashValue] = _pos;
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
UInt32 ptr1 = (_cyclicBufferPos << 1);
UInt32 len0, len1;
len0 = len1 = kNumHashDirectBytes;
UInt32 count = _cutValue;
while (true)
{
if (curMatch <= matchMinPos || count-- == 0)
{
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
break;
}
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
UInt32 pby1 = _bufferOffset + curMatch;
UInt32 len = Math.Min(len0, len1);
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
{
while (++len != lenLimit)
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
break;
if (len == lenLimit)
{
_son[ptr1] = _son[cyclicPos];
_son[ptr0] = _son[cyclicPos + 1];
break;
}
}
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
{
_son[ptr1] = curMatch;
ptr1 = cyclicPos + 1;
curMatch = _son[ptr1];
len1 = len;
}
else
{
_son[ptr0] = curMatch;
ptr0 = cyclicPos;
curMatch = _son[ptr0];
len0 = len;
}
}
MovePos();
}
while (--num != 0);
}
void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
{
for (UInt32 i = 0; i < numItems; i++)
{
UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
items[i] = value;
}
}
void Normalize()
{
UInt32 subValue = _pos - _cyclicBufferSize;
NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
NormalizeLinks(_hash, _hashSizeSum, subValue);
ReduceOffsets((Int32)subValue);
}
public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
}
}

View File

@ -1,135 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// LzInWindow.cs
using System;
namespace SevenZip.Compression.LZ
{
public class InWindow
{
public Byte[] _bufferBase = null; // pointer to buffer with data
System.IO.Stream _stream;
UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
UInt32 _pointerToLastSafePosition;
public UInt32 _bufferOffset;
public UInt32 _blockSize; // Size of Allocated memory block
public UInt32 _pos; // offset (from _buffer) of curent byte
UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
public void MoveBlock()
{
UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
// we need one additional byte, since MovePos moves on 1 byte.
if (offset > 0)
offset--;
UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
// check negative offset ????
for (UInt32 i = 0; i < numBytes; i++)
_bufferBase[i] = _bufferBase[offset + i];
_bufferOffset -= offset;
}
public virtual void ReadBlock()
{
if (_streamEndWasReached)
return;
while (true)
{
int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
if (size == 0)
return;
int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
if (numReadBytes == 0)
{
_posLimit = _streamPos;
UInt32 pointerToPostion = _bufferOffset + _posLimit;
if (pointerToPostion > _pointerToLastSafePosition)
_posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
_streamEndWasReached = true;
return;
}
_streamPos += (UInt32)numReadBytes;
if (_streamPos >= _pos + _keepSizeAfter)
_posLimit = _streamPos - _keepSizeAfter;
}
}
void Free() { _bufferBase = null; }
public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
{
_keepSizeBefore = keepSizeBefore;
_keepSizeAfter = keepSizeAfter;
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
if (_bufferBase == null || _blockSize != blockSize)
{
Free();
_blockSize = blockSize;
_bufferBase = new Byte[_blockSize];
}
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
}
public void SetStream(System.IO.Stream stream) { _stream = stream; }
public void ReleaseStream() { _stream = null; }
public void Init()
{
_bufferOffset = 0;
_pos = 0;
_streamPos = 0;
_streamEndWasReached = false;
ReadBlock();
}
public void MovePos()
{
_pos++;
if (_pos > _posLimit)
{
UInt32 pointerToPostion = _bufferOffset + _pos;
if (pointerToPostion > _pointerToLastSafePosition)
MoveBlock();
ReadBlock();
}
}
public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
// index + limit have not to exceed _keepSizeAfter;
public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
{
if (_streamEndWasReached)
if ((_pos + index) + limit > _streamPos)
limit = _streamPos - (UInt32)(_pos + index);
distance++;
// Byte *pby = _buffer + (size_t)_pos + index;
UInt32 pby = _bufferOffset + _pos + (UInt32)index;
UInt32 i;
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
return i;
}
public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
public void ReduceOffsets(Int32 subValue)
{
_bufferOffset += (UInt32)subValue;
_posLimit -= (UInt32)subValue;
_pos -= (UInt32)subValue;
_streamPos -= (UInt32)subValue;
}
}
}

View File

@ -1,113 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// LzOutWindow.cs
namespace SevenZip.Compression.LZ
{
public class OutWindow
{
byte[] _buffer = null;
uint _pos;
uint _windowSize = 0;
uint _streamPos;
System.IO.Stream _stream;
public uint TrainSize = 0;
public void Create(uint windowSize)
{
if (_windowSize != windowSize)
{
// System.GC.Collect();
_buffer = new byte[windowSize];
}
_windowSize = windowSize;
_pos = 0;
_streamPos = 0;
}
public void Init(System.IO.Stream stream, bool solid)
{
ReleaseStream();
_stream = stream;
if (!solid)
{
_streamPos = 0;
_pos = 0;
TrainSize = 0;
}
}
public bool Train(System.IO.Stream stream)
{
long len = stream.Length;
uint size = (len < _windowSize) ? (uint)len : _windowSize;
TrainSize = size;
stream.Position = len - size;
_streamPos = _pos = 0;
while (size > 0)
{
uint curSize = _windowSize - _pos;
if (size < curSize)
curSize = size;
int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
if (numReadBytes == 0)
return false;
size -= (uint)numReadBytes;
_pos += (uint)numReadBytes;
_streamPos += (uint)numReadBytes;
if (_pos == _windowSize)
_streamPos = _pos = 0;
}
return true;
}
public void ReleaseStream()
{
Flush();
_stream = null;
}
public void Flush()
{
uint size = _pos - _streamPos;
if (size == 0)
return;
_stream.Write(_buffer, (int)_streamPos, (int)size);
if (_pos >= _windowSize)
_pos = 0;
_streamPos = _pos;
}
public void CopyBlock(uint distance, uint len)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
for (; len > 0; len--)
{
if (pos >= _windowSize)
pos = 0;
_buffer[_pos++] = _buffer[pos++];
if (_pos >= _windowSize)
Flush();
}
}
public void PutByte(byte b)
{
_buffer[_pos++] = b;
if (_pos >= _windowSize)
Flush();
}
public byte GetByte(uint distance)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
}
}
}

View File

@ -1,79 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// LzmaBase.cs
namespace SevenZip.Compression.LZMA
{
internal abstract class Base
{
public const uint kNumRepDistances = 4;
public const uint kNumStates = 12;
// static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
// static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
// static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
// static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
public struct State
{
public uint Index;
public void Init() { Index = 0; }
public void UpdateChar()
{
if (Index < 4) Index = 0;
else if (Index < 10) Index -= 3;
else Index -= 6;
}
public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
public bool IsCharState() { return Index < 7; }
}
public const int kNumPosSlotBits = 6;
public const int kDicLogSizeMin = 0;
// public const int kDicLogSizeMax = 30;
// public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
public const uint kMatchMinLen = 2;
public static uint GetLenToPosState(uint len)
{
len -= kMatchMinLen;
if (len < kNumLenToPosStates)
return len;
return (uint)(kNumLenToPosStates - 1);
}
public const int kNumAlignBits = 4;
public const uint kAlignTableSize = 1 << kNumAlignBits;
public const uint kAlignMask = (kAlignTableSize - 1);
public const uint kStartPosModelIndex = 4;
public const uint kEndPosModelIndex = 14;
public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);
public const uint kNumLitPosStatesBitsEncodingMax = 4;
public const uint kNumLitContextBitsMax = 8;
public const int kNumPosStatesBitsMax = 4;
public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
public const int kNumPosStatesBitsEncodingMax = 4;
public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
public const int kNumLowLenBits = 3;
public const int kNumMidLenBits = 3;
public const int kNumHighLenBits = 8;
public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
(1 << kNumHighLenBits);
public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
}
}

View File

@ -1,402 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// LzmaDecoder.cs
using System;
namespace SevenZip.Compression.LZMA
{
using RangeCoder;
public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
{
class LenDecoder
{
BitDecoder m_Choice = new BitDecoder();
BitDecoder m_Choice2 = new BitDecoder();
BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
uint m_NumPosStates = 0;
public void Create(uint numPosStates)
{
for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
{
m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
}
m_NumPosStates = numPosStates;
}
public void Init()
{
m_Choice.Init();
for (uint posState = 0; posState < m_NumPosStates; posState++)
{
m_LowCoder[posState].Init();
m_MidCoder[posState].Init();
}
m_Choice2.Init();
m_HighCoder.Init();
}
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
{
if (m_Choice.Decode(rangeDecoder) == 0)
return m_LowCoder[posState].Decode(rangeDecoder);
else
{
uint symbol = Base.kNumLowLenSymbols;
if (m_Choice2.Decode(rangeDecoder) == 0)
symbol += m_MidCoder[posState].Decode(rangeDecoder);
else
{
symbol += Base.kNumMidLenSymbols;
symbol += m_HighCoder.Decode(rangeDecoder);
}
return symbol;
}
}
}
class LiteralDecoder
{
struct Decoder2
{
BitDecoder[] m_Decoders;
public void Create() { m_Decoders = new BitDecoder[0x300]; }
public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
{
uint symbol = 1;
do
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
while (symbol < 0x100);
return (byte)symbol;
}
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
{
uint symbol = 1;
do
{
uint matchBit = (uint)(matchByte >> 7) & 1;
matchByte <<= 1;
uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
symbol = (symbol << 1) | bit;
if (matchBit != bit)
{
while (symbol < 0x100)
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
break;
}
}
while (symbol < 0x100);
return (byte)symbol;
}
}
Decoder2[] m_Coders;
int m_NumPrevBits;
int m_NumPosBits;
uint m_PosMask;
public void Create(int numPosBits, int numPrevBits)
{
if (m_Coders != null && m_NumPrevBits == numPrevBits &&
m_NumPosBits == numPosBits)
return;
m_NumPosBits = numPosBits;
m_PosMask = ((uint)1 << numPosBits) - 1;
m_NumPrevBits = numPrevBits;
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
m_Coders = new Decoder2[numStates];
for (uint i = 0; i < numStates; i++)
m_Coders[i].Create();
}
public void Init()
{
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
for (uint i = 0; i < numStates; i++)
m_Coders[i].Init();
}
uint GetState(uint pos, byte prevByte)
{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
};
LZ.OutWindow m_OutWindow = new LZ.OutWindow();
RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
LenDecoder m_LenDecoder = new LenDecoder();
LenDecoder m_RepLenDecoder = new LenDecoder();
LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
uint m_DictionarySize;
uint m_DictionarySizeCheck;
uint m_PosStateMask;
public Decoder()
{
m_DictionarySize = 0xFFFFFFFF;
for (int i = 0; i < Base.kNumLenToPosStates; i++)
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
}
void SetDictionarySize(uint dictionarySize)
{
if (m_DictionarySize != dictionarySize)
{
m_DictionarySize = dictionarySize;
m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
m_OutWindow.Create(blockSize);
}
}
void SetLiteralProperties(int lp, int lc)
{
if (lp > 8)
throw new InvalidParamException();
if (lc > 8)
throw new InvalidParamException();
m_LiteralDecoder.Create(lp, lc);
}
void SetPosBitsProperties(int pb)
{
if (pb > Base.kNumPosStatesBitsMax)
throw new InvalidParamException();
uint numPosStates = (uint)1 << pb;
m_LenDecoder.Create(numPosStates);
m_RepLenDecoder.Create(numPosStates);
m_PosStateMask = numPosStates - 1;
}
bool _solid = false;
void Init(System.IO.Stream inStream, System.IO.Stream outStream)
{
m_RangeDecoder.Init(inStream);
m_OutWindow.Init(outStream, _solid);
uint i;
for (i = 0; i < Base.kNumStates; i++)
{
for (uint j = 0; j <= m_PosStateMask; j++)
{
uint index = (i << Base.kNumPosStatesBitsMax) + j;
m_IsMatchDecoders[index].Init();
m_IsRep0LongDecoders[index].Init();
}
m_IsRepDecoders[i].Init();
m_IsRepG0Decoders[i].Init();
m_IsRepG1Decoders[i].Init();
m_IsRepG2Decoders[i].Init();
}
m_LiteralDecoder.Init();
for (i = 0; i < Base.kNumLenToPosStates; i++)
m_PosSlotDecoder[i].Init();
// m_PosSpecDecoder.Init();
for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
m_PosDecoders[i].Init();
m_LenDecoder.Init();
m_RepLenDecoder.Init();
m_PosAlignDecoder.Init();
}
public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
Int64 inSize, Int64 outSize, ICodeProgress progress)
{
Init(inStream, outStream);
Base.State state = new Base.State();
state.Init();
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
UInt64 nowPos64 = 0;
UInt64 outSize64 = (UInt64)outSize;
if (nowPos64 < outSize64)
{
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
throw new DataErrorException();
state.UpdateChar();
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
m_OutWindow.PutByte(b);
nowPos64++;
}
while (nowPos64 < outSize64)
{
progress.SetProgress(inStream.Position, (long)nowPos64);
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
// while(nowPos64 < next)
{
uint posState = (uint)nowPos64 & m_PosStateMask;
if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
{
byte b;
byte prevByte = m_OutWindow.GetByte(0);
if (!state.IsCharState())
b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
(uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
else
b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
m_OutWindow.PutByte(b);
state.UpdateChar();
nowPos64++;
}
else
{
uint len;
if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
{
if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
{
if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
{
state.UpdateShortRep();
m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
nowPos64++;
continue;
}
}
else
{
UInt32 distance;
if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
{
distance = rep1;
}
else
{
if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
distance = rep2;
else
{
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
state.UpdateRep();
}
else
{
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
state.UpdateMatch();
uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
if (posSlot >= Base.kStartPosModelIndex)
{
int numDirectBits = (int)((posSlot >> 1) - 1);
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
if (posSlot < Base.kEndPosModelIndex)
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
else
{
rep0 += (m_RangeDecoder.DecodeDirectBits(
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
}
}
else
rep0 = posSlot;
}
if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
{
if (rep0 == 0xFFFFFFFF)
break;
throw new DataErrorException();
}
m_OutWindow.CopyBlock(rep0, len);
nowPos64 += len;
}
}
}
m_OutWindow.Flush();
m_OutWindow.ReleaseStream();
m_RangeDecoder.ReleaseStream();
}
public void SetDecoderProperties(byte[] properties)
{
if (properties.Length < 5)
throw new InvalidParamException();
int lc = properties[0] % 9;
int remainder = properties[0] / 9;
int lp = remainder % 5;
int pb = remainder / 5;
if (pb > Base.kNumPosStatesBitsMax)
throw new InvalidParamException();
UInt32 dictionarySize = 0;
for (int i = 0; i < 4; i++)
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
SetDictionarySize(dictionarySize);
SetLiteralProperties(lp, lc);
SetPosBitsProperties(pb);
}
public bool Train(System.IO.Stream stream)
{
_solid = true;
return m_OutWindow.Train(stream);
}
/*
public override bool CanRead { get { return true; }}
public override bool CanWrite { get { return true; }}
public override bool CanSeek { get { return true; }}
public override long Length { get { return 0; }}
public override long Position
{
get { return 0; }
set { }
}
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count)
{
return 0;
}
public override void Write(byte[] buffer, int offset, int count)
{
}
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
return 0;
}
public override void SetLength(long value) {}
*/
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace SevenZip.Compression.RangeCoder
{
class Encoder
{
public const uint kTopValue = (1 << 24);
System.IO.Stream Stream;
public UInt64 Low;
public uint Range;
uint _cacheSize;
byte _cache;
long StartPosition;
public void SetStream(System.IO.Stream stream)
{
Stream = stream;
}
public void ReleaseStream()
{
Stream = null;
}
public void Init()
{
StartPosition = Stream.Position;
Low = 0;
Range = 0xFFFFFFFF;
_cacheSize = 1;
_cache = 0;
}
public void FlushData()
{
for (int i = 0; i < 5; i++)
ShiftLow();
}
public void FlushStream()
{
Stream.Flush();
}
public void CloseStream()
{
Stream.Dispose();
}
public void Encode(uint start, uint size, uint total)
{
Low += start * (Range /= total);
Range *= size;
while (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
public void ShiftLow()
{
if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)
{
byte temp = _cache;
do
{
Stream.WriteByte((byte)(temp + (Low >> 32)));
temp = 0xFF;
}
while (--_cacheSize != 0);
_cache = (byte)(((uint)Low) >> 24);
}
_cacheSize++;
Low = ((uint)Low) << 8;
}
public void EncodeDirectBits(uint v, int numTotalBits)
{
for (int i = numTotalBits - 1; i >= 0; i--)
{
Range >>= 1;
if (((v >> i) & 1) == 1)
Low += Range;
if (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
}
public void EncodeBit(uint size0, int numTotalBits, uint symbol)
{
uint newBound = (Range >> numTotalBits) * size0;
if (symbol == 0)
Range = newBound;
else
{
Low += newBound;
Range -= newBound;
}
while (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
public long GetProcessedSizeAdd()
{
return _cacheSize +
Stream.Position - StartPosition + 4;
// (long)Stream.GetProcessedSize();
}
}
class Decoder
{
public const uint kTopValue = (1 << 24);
public uint Range;
public uint Code;
// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
public System.IO.Stream Stream;
public void Init(System.IO.Stream stream)
{
// Stream.Init(stream);
Stream = stream;
Code = 0;
Range = 0xFFFFFFFF;
for (int i = 0; i < 5; i++)
Code = (Code << 8) | (byte)Stream.ReadByte();
}
public void ReleaseStream()
{
// Stream.ReleaseStream();
Stream = null;
}
public void CloseStream()
{
Stream.Dispose();
}
public void Normalize()
{
while (Range < kTopValue)
{
Code = (Code << 8) | (byte)Stream.ReadByte();
Range <<= 8;
}
}
public void Normalize2()
{
if (Range < kTopValue)
{
Code = (Code << 8) | (byte)Stream.ReadByte();
Range <<= 8;
}
}
public uint GetThreshold(uint total)
{
return Code / (Range /= total);
}
public void Decode(uint start, uint size, uint total)
{
Code -= start * Range;
Range *= size;
Normalize();
}
public uint DecodeDirectBits(int numTotalBits)
{
uint range = Range;
uint code = Code;
uint result = 0;
for (int i = numTotalBits; i > 0; i--)
{
range >>= 1;
/*
result <<= 1;
if (code >= range)
{
code -= range;
result |= 1;
}
*/
uint t = (code - range) >> 31;
code -= range & (t - 1);
result = (result << 1) | (1 - t);
if (range < kTopValue)
{
code = (code << 8) | (byte)Stream.ReadByte();
range <<= 8;
}
}
Range = range;
Code = code;
return result;
}
public uint DecodeBit(uint size0, int numTotalBits)
{
uint newBound = (Range >> numTotalBits) * size0;
uint symbol;
if (Code < newBound)
{
symbol = 0;
Range = newBound;
}
else
{
symbol = 1;
Code -= newBound;
Range -= newBound;
}
Normalize();
return symbol;
}
// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
}
}

View File

@ -1,120 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace SevenZip.Compression.RangeCoder
{
struct BitEncoder
{
public const int kNumBitModelTotalBits = 11;
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveBits = 5;
const int kNumMoveReducingBits = 2;
public const int kNumBitPriceShiftBits = 6;
uint Prob;
public void Init() { Prob = kBitModelTotal >> 1; }
public void UpdateModel(uint symbol)
{
if (symbol == 0)
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
else
Prob -= (Prob) >> kNumMoveBits;
}
public void Encode(Encoder encoder, uint symbol)
{
// encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
// UpdateModel(symbol);
uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;
if (symbol == 0)
{
encoder.Range = newBound;
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
}
else
{
encoder.Low += newBound;
encoder.Range -= newBound;
Prob -= (Prob) >> kNumMoveBits;
}
if (encoder.Range < Encoder.kTopValue)
{
encoder.Range <<= 8;
encoder.ShiftLow();
}
}
private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
static BitEncoder()
{
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
for (int i = kNumBits - 1; i >= 0; i--)
{
UInt32 start = (UInt32)1 << (kNumBits - i - 1);
UInt32 end = (UInt32)1 << (kNumBits - i);
for (UInt32 j = start; j < end; j++)
ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
}
}
public uint GetPrice(uint symbol)
{
return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
}
public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }
public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }
}
struct BitDecoder
{
public const int kNumBitModelTotalBits = 11;
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveBits = 5;
uint Prob;
public void UpdateModel(int numMoveBits, uint symbol)
{
if (symbol == 0)
Prob += (kBitModelTotal - Prob) >> numMoveBits;
else
Prob -= (Prob) >> numMoveBits;
}
public void Init() { Prob = kBitModelTotal >> 1; }
public uint Decode(RangeCoder.Decoder rangeDecoder)
{
uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;
if (rangeDecoder.Code < newBound)
{
rangeDecoder.Range = newBound;
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
if (rangeDecoder.Range < Decoder.kTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 0;
}
else
{
rangeDecoder.Range -= newBound;
rangeDecoder.Code -= newBound;
Prob -= (Prob) >> kNumMoveBits;
if (rangeDecoder.Range < Decoder.kTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 1;
}
}
}
}

View File

@ -1,160 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace SevenZip.Compression.RangeCoder
{
struct BitTreeEncoder
{
BitEncoder[] Models;
int NumBitLevels;
public BitTreeEncoder(int numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new BitEncoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
public void Encode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; )
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
Models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
}
}
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (UInt32 i = 0; i < NumBitLevels; i++)
{
UInt32 bit = symbol & 1;
Models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
public UInt32 GetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; )
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
price += Models[m].GetPrice(bit);
m = (m << 1) + bit;
}
return price;
}
public UInt32 ReverseGetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = NumBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += Models[m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
int NumBitLevels, UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = NumBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += Models[startIndex + m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
{
UInt32 m = 1;
for (int i = 0; i < NumBitLevels; i++)
{
UInt32 bit = symbol & 1;
Models[startIndex + m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
}
struct BitTreeDecoder
{
BitDecoder[] Models;
int NumBitLevels;
public BitTreeDecoder(int numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new BitDecoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
public uint Decode(RangeCoder.Decoder rangeDecoder)
{
uint m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
m = (m << 1) + Models[m].Decode(rangeDecoder);
return m - ((uint)1 << NumBitLevels);
}
public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
uint bit = Models[m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
RangeCoder.Decoder rangeDecoder, int NumBitLevels)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
uint bit = Models[startIndex + m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
}
}

View File

@ -1,160 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// ICoder.h
using System;
namespace SevenZip
{
/// <summary>
/// The exception that is thrown when an error in input stream occurs during decoding.
/// </summary>
class DataErrorException : Exception
{
public DataErrorException(): base("Data Error") { }
}
/// <summary>
/// The exception that is thrown when the value of an argument is outside the allowable range.
/// </summary>
class InvalidParamException : Exception
{
public InvalidParamException(): base("Invalid Parameter") { }
}
public interface ICodeProgress
{
/// <summary>
/// Callback progress.
/// </summary>
/// <param name="inSize">
/// input size. -1 if unknown.
/// </param>
/// <param name="outSize">
/// output size. -1 if unknown.
/// </param>
void SetProgress(Int64 inSize, Int64 outSize);
};
public interface ICoder
{
/// <summary>
/// Codes streams.
/// </summary>
/// <param name="inStream">
/// input Stream.
/// </param>
/// <param name="outStream">
/// output Stream.
/// </param>
/// <param name="inSize">
/// input Size. -1 if unknown.
/// </param>
/// <param name="outSize">
/// output Size. -1 if unknown.
/// </param>
/// <param name="progress">
/// callback progress reference.
/// </param>
/// <exception cref="SevenZip.DataErrorException">
/// if input stream is not valid
/// </exception>
void Code(System.IO.Stream inStream, System.IO.Stream outStream,
Int64 inSize, Int64 outSize, ICodeProgress progress);
};
/*
public interface ICoder2
{
void Code(ISequentialInStream []inStreams,
const UInt64 []inSizes,
ISequentialOutStream []outStreams,
UInt64 []outSizes,
ICodeProgress progress);
};
*/
/// <summary>
/// Provides the fields that represent properties idenitifiers for compressing.
/// </summary>
public enum CoderPropID
{
/// <summary>
/// Specifies default property.
/// </summary>
DefaultProp = 0,
/// <summary>
/// Specifies size of dictionary.
/// </summary>
DictionarySize,
/// <summary>
/// Specifies size of memory for PPM*.
/// </summary>
UsedMemorySize,
/// <summary>
/// Specifies order for PPM methods.
/// </summary>
Order,
/// <summary>
/// Specifies Block Size.
/// </summary>
BlockSize,
/// <summary>
/// Specifies number of postion state bits for LZMA (0 <= x <= 4).
/// </summary>
PosStateBits,
/// <summary>
/// Specifies number of literal context bits for LZMA (0 <= x <= 8).
/// </summary>
LitContextBits,
/// <summary>
/// Specifies number of literal position bits for LZMA (0 <= x <= 4).
/// </summary>
LitPosBits,
/// <summary>
/// Specifies number of fast bytes for LZ*.
/// </summary>
NumFastBytes,
/// <summary>
/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
/// </summary>
MatchFinder,
/// <summary>
/// Specifies the number of match finder cyckes.
/// </summary>
MatchFinderCycles,
/// <summary>
/// Specifies number of passes.
/// </summary>
NumPasses,
/// <summary>
/// Specifies number of algorithm.
/// </summary>
Algorithm,
/// <summary>
/// Specifies the number of threads.
/// </summary>
NumThreads,
/// <summary>
/// Specifies mode with end marker.
/// </summary>
EndMarker
};
public interface ISetCoderProperties
{
void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
};
public interface IWriteCoderProperties
{
void WriteCoderProperties(System.IO.Stream outStream);
}
public interface ISetDecoderProperties
{
void SetDecoderProperties(byte[] properties);
}
}

View File

@ -1,10 +0,0 @@
## LZMA SDK
This source came from the C# implementation of LZMA from the LZMA SDK, version 16.02, from http://www.7-zip.org/sdk.html.
## License
LZMA SDK is placed in the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the original LZMA SDK code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
## Thanks!
Thanks goes to Igor Pavlov for making this available.

View File

@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<EnableApiCheck>false</EnableApiCheck>
</PropertyGroup>
</Project>

View File

@ -1,29 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace Microsoft.DotNet.Archive
{
public struct ProgressReport
{
public ProgressReport(string phase, long ticks, long total)
{
Phase = phase;
Ticks = ticks;
Total = total;
}
public string Phase { get; }
public long Ticks { get; }
public long Total { get; }
}
public static class ProgressReportExtensions
{
public static void Report(this IProgress<ProgressReport> progress, string phase, long ticks, long total)
{
progress.Report(new ProgressReport(phase, ticks, total));
}
}
}

View File

@ -1,6 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Reflection;
[assembly: AssemblyMetadataAttribute("Serviceable", "True")]

View File

@ -1,59 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.IO;
using System.IO.Compression;
using System.Threading;
namespace Microsoft.DotNet.Archive
{
/// <summary>
/// Wraps ThreadLocal<ZipArchive> and exposes Dispose semantics that dispose all archives
/// </summary>
internal class ThreadLocalZipArchive : IDisposable
{
private ThreadLocal<ZipArchive> _archive;
private bool _disposed = false;
public ThreadLocalZipArchive(string archivePath, ZipArchive local = null)
{
_archive = new ThreadLocal<ZipArchive>(() =>
new ZipArchive(File.Open(archivePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete), ZipArchiveMode.Read),
trackAllValues:true);
if (local != null)
{
// reuse provided one for current thread
_archive.Value = local;
}
}
public ZipArchive Archive { get { return _archive.Value; } }
public void Dispose()
{
if (!_disposed)
{
if (_archive != null)
{
// dispose all archives
if (_archive.Values != null)
{
foreach (var value in _archive.Values)
{
if (value != null)
{
value.Dispose();
}
}
}
// dispose ThreadLocal
_archive.Dispose();
_archive = null;
}
}
}
}
}

View File

@ -1,29 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandArgument
{
public CommandArgument()
{
Values = new List<string>();
}
public string Name { get; set; }
public string Description { get; set; }
public List<string> Values { get; private set; }
public bool MultipleValues { get; set; }
public string Value
{
get
{
return Values.FirstOrDefault();
}
}
}
}

View File

@ -1,693 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandLineApplication
{
private enum ParseOptionResult
{
Succeeded,
ShowHelp,
ShowVersion,
UnexpectedArgs,
}
// Indicates whether the parser should throw an exception when it runs into an unexpected argument.
// If this field is set to false, the parser will stop parsing when it sees an unexpected argument, and all
// remaining arguments, including the first unexpected argument, will be stored in RemainingArguments property.
private readonly bool _throwOnUnexpectedArg;
public CommandLineApplication(bool throwOnUnexpectedArg = true)
{
_throwOnUnexpectedArg = throwOnUnexpectedArg;
Options = new List<CommandOption>();
Arguments = new List<CommandArgument>();
Commands = new List<CommandLineApplication>();
RemainingArguments = new List<string>();
Invoke = () => 0;
}
public CommandLineApplication Parent { get; set; }
public string Name { get; set; }
public string FullName { get; set; }
public string Syntax { get; set; }
public string Description { get; set; }
public List<CommandOption> Options { get; private set; }
public CommandOption OptionHelp { get; private set; }
public CommandOption OptionVersion { get; private set; }
public List<CommandArgument> Arguments { get; private set; }
public List<string> RemainingArguments { get; private set; }
public bool IsShowingInformation { get; protected set; } // Is showing help or version?
public Func<int> Invoke { get; set; }
public Func<string> LongVersionGetter { get; set; }
public Func<string> ShortVersionGetter { get; set; }
public List<CommandLineApplication> Commands { get; private set; }
public bool HandleResponseFiles { get; set; }
public bool AllowArgumentSeparator { get; set; }
public bool HandleRemainingArguments { get; set; }
public string ArgumentSeparatorHelpText { get; set; }
public CommandLineApplication AddCommand(string name, bool throwOnUnexpectedArg = true)
{
return AddCommand(name, _ => { }, throwOnUnexpectedArg);
}
public CommandLineApplication AddCommand(string name, Action<CommandLineApplication> configuration,
bool throwOnUnexpectedArg = true)
{
var command = new CommandLineApplication(throwOnUnexpectedArg) { Name = name };
return AddCommand(command, configuration, throwOnUnexpectedArg);
}
public CommandLineApplication AddCommand(CommandLineApplication command, bool throwOnUnexpectedArg = true)
{
return AddCommand(command, _ => { }, throwOnUnexpectedArg);
}
public CommandLineApplication AddCommand(
CommandLineApplication command,
Action<CommandLineApplication> configuration,
bool throwOnUnexpectedArg = true)
{
if (command == null || configuration == null)
{
throw new NullReferenceException();
}
command.Parent = this;
Commands.Add(command);
configuration(command);
return command;
}
public CommandOption Option(string template, string description, CommandOptionType optionType)
{
return Option(template, description, optionType, _ => { });
}
public CommandOption Option(string template, string description, CommandOptionType optionType, Action<CommandOption> configuration)
{
var option = new CommandOption(template, optionType) { Description = description };
Options.Add(option);
configuration(option);
return option;
}
public CommandArgument Argument(string name, string description, bool multipleValues = false)
{
return Argument(name, description, _ => { }, multipleValues);
}
public CommandArgument Argument(string name, string description, Action<CommandArgument> configuration, bool multipleValues = false)
{
var lastArg = Arguments.LastOrDefault();
if (lastArg != null && lastArg.MultipleValues)
{
var message = string.Format(LocalizableStrings.LastArgumentMultiValueError,
lastArg.Name);
throw new InvalidOperationException(message);
}
var argument = new CommandArgument { Name = name, Description = description, MultipleValues = multipleValues };
Arguments.Add(argument);
configuration(argument);
return argument;
}
public void OnExecute(Func<int> invoke)
{
Invoke = invoke;
}
public void OnExecute(Func<Task<int>> invoke)
{
Invoke = () => invoke().Result;
}
public int Execute(params string[] args)
{
CommandLineApplication command = this;
CommandArgumentEnumerator arguments = null;
if (HandleResponseFiles)
{
args = ExpandResponseFiles(args).ToArray();
}
for (var index = 0; index < args.Length; index++)
{
var arg = args[index];
bool isLongOption = arg.StartsWith("--");
if (arg == "-?" || arg == "/?")
{
command.ShowHelp();
return 0;
}
else if (isLongOption || arg.StartsWith("-"))
{
CommandOption option;
var result = ParseOption(isLongOption, command, args, ref index, out option);
if (result == ParseOptionResult.ShowHelp)
{
command.ShowHelp();
return 0;
}
else if (result == ParseOptionResult.ShowVersion)
{
command.ShowVersion();
return 0;
}
else if (result == ParseOptionResult.UnexpectedArgs)
{
break;
}
}
else
{
var subcommand = ParseSubCommand(arg, command);
if (subcommand != null)
{
command = subcommand;
}
else
{
if (arguments == null || arguments.CommandName != command.Name)
{
arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator(), command.Name);
}
if (arguments.MoveNext())
{
arguments.Current.Values.Add(arg);
}
else
{
HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
break;
}
}
}
}
if (Commands.Count > 0 && command == this)
{
throw new CommandParsingException(
command,
"Required command missing",
isRequiredSubCommandMissing: true);
}
return command.Invoke();
}
private ParseOptionResult ParseOption(
bool isLongOption,
CommandLineApplication command,
string[] args,
ref int index,
out CommandOption option)
{
option = null;
ParseOptionResult result = ParseOptionResult.Succeeded;
var arg = args[index];
int optionPrefixLength = isLongOption ? 2 : 1;
string[] optionComponents = arg.Substring(optionPrefixLength).Split(new[] { ':', '=' }, 2);
string optionName = optionComponents[0];
if (isLongOption)
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.LongName, optionName, StringComparison.Ordinal));
}
else
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.ShortName, optionName, StringComparison.Ordinal));
if (option == null)
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.SymbolName, optionName, StringComparison.Ordinal));
}
}
if (option == null)
{
if (isLongOption && string.IsNullOrEmpty(optionName) &&
!command._throwOnUnexpectedArg && AllowArgumentSeparator)
{
// a stand-alone "--" is the argument separator, so skip it and
// handle the rest of the args as unexpected args
index++;
}
HandleUnexpectedArg(command, args, index, argTypeName: "option");
result = ParseOptionResult.UnexpectedArgs;
}
else if (command.OptionHelp == option)
{
result = ParseOptionResult.ShowHelp;
}
else if (command.OptionVersion == option)
{
result = ParseOptionResult.ShowVersion;
}
else
{
if (optionComponents.Length == 2)
{
if (!option.TryParse(optionComponents[1]))
{
command.ShowHint();
throw new CommandParsingException(command,
String.Format(LocalizableStrings.UnexpectedValueForOptionError, optionComponents[1], optionName));
}
}
else
{
if (option.OptionType == CommandOptionType.NoValue ||
option.OptionType == CommandOptionType.BoolValue)
{
// No value is needed for this option
option.TryParse(null);
}
else
{
index++;
if (index < args.Length)
{
arg = args[index];
if (!option.TryParse(arg))
{
command.ShowHint();
throw new CommandParsingException(
command,
String.Format(LocalizableStrings.UnexpectedValueForOptionError, arg, optionName));
}
}
else
{
command.ShowHint();
throw new CommandParsingException(
command,
String.Format(LocalizableStrings.OptionRequiresSingleValueWhichIsMissing, arg, optionName));
}
}
}
}
return result;
}
private CommandLineApplication ParseSubCommand(string arg, CommandLineApplication command)
{
foreach (var subcommand in command.Commands)
{
if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
{
return subcommand;
}
}
return null;
}
// Helper method that adds a help option
public CommandOption HelpOption(string template)
{
// Help option is special because we stop parsing once we see it
// So we store it separately for further use
OptionHelp = Option(template, LocalizableStrings.ShowHelpInfo, CommandOptionType.NoValue);
return OptionHelp;
}
public CommandOption VersionOption(string template,
string shortFormVersion,
string longFormVersion = null)
{
if (longFormVersion == null)
{
return VersionOption(template, () => shortFormVersion);
}
else
{
return VersionOption(template, () => shortFormVersion, () => longFormVersion);
}
}
// Helper method that adds a version option
public CommandOption VersionOption(string template,
Func<string> shortFormVersionGetter,
Func<string> longFormVersionGetter = null)
{
// Version option is special because we stop parsing once we see it
// So we store it separately for further use
OptionVersion = Option(template, LocalizableStrings.ShowVersionInfo, CommandOptionType.NoValue);
ShortVersionGetter = shortFormVersionGetter;
LongVersionGetter = longFormVersionGetter ?? shortFormVersionGetter;
return OptionVersion;
}
// Show short hint that reminds users to use help option
public void ShowHint()
{
if (OptionHelp != null)
{
Console.WriteLine(string.Format(LocalizableStrings.ShowHintInfo, OptionHelp.LongName));
}
}
// Show full help
public void ShowHelp(string commandName = null)
{
var headerBuilder = new StringBuilder(LocalizableStrings.UsageHeader);
var usagePrefixLength = headerBuilder.Length;
for (var cmd = this; cmd != null; cmd = cmd.Parent)
{
cmd.IsShowingInformation = true;
if (cmd != this && cmd.Arguments.Any())
{
var args = string.Join(" ", cmd.Arguments.Select(arg => arg.Name));
headerBuilder.Insert(usagePrefixLength, string.Format(" {0} {1}", cmd.Name, args));
}
else
{
headerBuilder.Insert(usagePrefixLength, string.Format(" {0}", cmd.Name));
}
}
CommandLineApplication target;
if (commandName == null || string.Equals(Name, commandName, StringComparison.OrdinalIgnoreCase))
{
target = this;
}
else
{
target = Commands.SingleOrDefault(cmd => string.Equals(cmd.Name, commandName, StringComparison.OrdinalIgnoreCase));
if (target != null)
{
headerBuilder.AppendFormat(" {0}", commandName);
}
else
{
// The command name is invalid so don't try to show help for something that doesn't exist
target = this;
}
}
var optionsBuilder = new StringBuilder();
var commandsBuilder = new StringBuilder();
var argumentsBuilder = new StringBuilder();
var argumentSeparatorBuilder = new StringBuilder();
int maxArgLen = 0;
for (var cmd = target; cmd != null; cmd = cmd.Parent)
{
if (cmd.Arguments.Any())
{
if (cmd == target)
{
headerBuilder.Append(LocalizableStrings.UsageArgumentsToken);
}
if (argumentsBuilder.Length == 0)
{
argumentsBuilder.AppendLine();
argumentsBuilder.AppendLine(LocalizableStrings.UsageArgumentsHeader);
}
maxArgLen = Math.Max(maxArgLen, MaxArgumentLength(cmd.Arguments));
}
}
for (var cmd = target; cmd != null; cmd = cmd.Parent)
{
if (cmd.Arguments.Any())
{
foreach (var arg in cmd.Arguments)
{
argumentsBuilder.AppendFormat(
" {0}{1}",
arg.Name.PadRight(maxArgLen + 2),
arg.Description);
argumentsBuilder.AppendLine();
}
}
}
if (target.Options.Any())
{
headerBuilder.Append(LocalizableStrings.UsageOptionsToken);
optionsBuilder.AppendLine();
optionsBuilder.AppendLine(LocalizableStrings.UsageOptionsHeader);
var maxOptLen = MaxOptionTemplateLength(target.Options);
var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxOptLen + 2);
foreach (var opt in target.Options)
{
optionsBuilder.AppendFormat(outputFormat, opt.Template, opt.Description);
optionsBuilder.AppendLine();
}
}
if (target.Commands.Any())
{
headerBuilder.Append(LocalizableStrings.UsageCommandToken);
commandsBuilder.AppendLine();
commandsBuilder.AppendLine(LocalizableStrings.UsageCommandsHeader);
var maxCmdLen = MaxCommandLength(target.Commands);
var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxCmdLen + 2);
foreach (var cmd in target.Commands.OrderBy(c => c.Name))
{
commandsBuilder.AppendFormat(outputFormat, cmd.Name, cmd.Description);
commandsBuilder.AppendLine();
}
if (OptionHelp != null)
{
commandsBuilder.AppendLine();
commandsBuilder.AppendFormat(LocalizableStrings.UsageCommandsDetailHelp, Name);
commandsBuilder.AppendLine();
}
}
if (target.AllowArgumentSeparator || target.HandleRemainingArguments)
{
if (target.AllowArgumentSeparator)
{
headerBuilder.Append(LocalizableStrings.UsageCommandAdditionalArgs);
}
else
{
headerBuilder.Append(LocalizableStrings.UsageCommandArgs);
}
if (!string.IsNullOrEmpty(target.ArgumentSeparatorHelpText))
{
argumentSeparatorBuilder.AppendLine();
argumentSeparatorBuilder.AppendLine(LocalizableStrings.UsageCommandsAdditionalArgsHeader);
argumentSeparatorBuilder.AppendLine(String.Format(" {0}", target.ArgumentSeparatorHelpText));
argumentSeparatorBuilder.AppendLine();
}
}
headerBuilder.AppendLine();
var nameAndVersion = new StringBuilder();
nameAndVersion.AppendLine(GetFullNameAndVersion());
nameAndVersion.AppendLine();
Console.Write("{0}{1}{2}{3}{4}{5}", nameAndVersion, headerBuilder, argumentsBuilder, optionsBuilder, commandsBuilder, argumentSeparatorBuilder);
}
public void ShowVersion()
{
for (var cmd = this; cmd != null; cmd = cmd.Parent)
{
cmd.IsShowingInformation = true;
}
Console.WriteLine(FullName);
Console.WriteLine(LongVersionGetter());
}
public string GetFullNameAndVersion()
{
return ShortVersionGetter == null ? FullName : string.Format("{0} {1}", FullName, ShortVersionGetter());
}
public void ShowRootCommandFullNameAndVersion()
{
var rootCmd = this;
while (rootCmd.Parent != null)
{
rootCmd = rootCmd.Parent;
}
Console.WriteLine(rootCmd.GetFullNameAndVersion());
Console.WriteLine();
}
private int MaxOptionTemplateLength(IEnumerable<CommandOption> options)
{
var maxLen = 0;
foreach (var opt in options)
{
maxLen = opt.Template.Length > maxLen ? opt.Template.Length : maxLen;
}
return maxLen;
}
private int MaxCommandLength(IEnumerable<CommandLineApplication> commands)
{
var maxLen = 0;
foreach (var cmd in commands)
{
maxLen = cmd.Name.Length > maxLen ? cmd.Name.Length : maxLen;
}
return maxLen;
}
private int MaxArgumentLength(IEnumerable<CommandArgument> arguments)
{
var maxLen = 0;
foreach (var arg in arguments)
{
maxLen = arg.Name.Length > maxLen ? arg.Name.Length : maxLen;
}
return maxLen;
}
private void HandleUnexpectedArg(CommandLineApplication command, string[] args, int index, string argTypeName)
{
if (command._throwOnUnexpectedArg)
{
command.ShowHint();
throw new CommandParsingException(command, String.Format(LocalizableStrings.UnexpectedArgumentError, argTypeName, args[index]));
}
else
{
// All remaining arguments are stored for further use
command.RemainingArguments.AddRange(new ArraySegment<string>(args, index, args.Length - index));
}
}
private IEnumerable<string> ExpandResponseFiles(IEnumerable<string> args)
{
foreach (var arg in args)
{
if (!arg.StartsWith("@", StringComparison.Ordinal))
{
yield return arg;
}
else
{
var fileName = arg.Substring(1);
var responseFileArguments = ParseResponseFile(fileName);
// ParseResponseFile can suppress expanding this response file by
// returning null. In that case, we'll treat the response
// file token as a regular argument.
if (responseFileArguments == null)
{
yield return arg;
}
else
{
foreach (var responseFileArgument in responseFileArguments)
yield return responseFileArgument.Trim();
}
}
}
}
private IEnumerable<string> ParseResponseFile(string fileName)
{
if (!HandleResponseFiles)
return null;
if (!File.Exists(fileName))
{
throw new InvalidOperationException(String.Format(LocalizableStrings.ResponseFileNotFoundError, fileName));
}
return File.ReadLines(fileName);
}
private class CommandArgumentEnumerator : IEnumerator<CommandArgument>
{
private readonly IEnumerator<CommandArgument> _enumerator;
public CommandArgumentEnumerator(
IEnumerator<CommandArgument> enumerator,
string commandName)
{
CommandName = commandName;
_enumerator = enumerator;
}
public string CommandName { get; }
public CommandArgument Current
{
get
{
return _enumerator.Current;
}
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public void Dispose()
{
_enumerator.Dispose();
}
public bool MoveNext()
{
if (Current == null || !Current.MultipleValues)
{
return _enumerator.MoveNext();
}
// If current argument allows multiple values, we don't move forward and
// all later values will be added to current CommandArgument.Values
return true;
}
public void Reset()
{
_enumerator.Reset();
}
}
}
}

View File

@ -1,135 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandOption
{
public CommandOption(string template, CommandOptionType optionType)
{
Template = template;
OptionType = optionType;
Values = new List<string>();
foreach (var part in Template.Split(new[] { ' ', '|' }, StringSplitOptions.RemoveEmptyEntries))
{
if (part.StartsWith("--"))
{
LongName = part.Substring(2);
}
else if (part.StartsWith("-"))
{
var optName = part.Substring(1);
// If there is only one char and it is not an English letter, it is a symbol option (e.g. "-?")
if (optName.Length == 1 && !IsEnglishLetter(optName[0]))
{
SymbolName = optName;
}
else
{
ShortName = optName;
}
}
else if (part.StartsWith("<") && part.EndsWith(">"))
{
ValueName = part.Substring(1, part.Length - 2);
}
else if (optionType == CommandOptionType.MultipleValue && part.StartsWith("<") && part.EndsWith(">..."))
{
ValueName = part.Substring(1, part.Length - 5);
}
else
{
throw new ArgumentException(String.Format(LocalizableStrings.InvalidTemplateError, nameof(template)));
}
}
if (string.IsNullOrEmpty(LongName) && string.IsNullOrEmpty(ShortName) && string.IsNullOrEmpty(SymbolName))
{
throw new ArgumentException(LocalizableStrings.InvalidTemplateError, nameof(template));
}
}
public string Template { get; set; }
public string ShortName { get; set; }
public string LongName { get; set; }
public string SymbolName { get; set; }
public string ValueName { get; set; }
public string Description { get; set; }
public List<string> Values { get; private set; }
public bool? BoolValue { get; private set; }
public CommandOptionType OptionType { get; private set; }
public bool TryParse(string value)
{
switch (OptionType)
{
case CommandOptionType.MultipleValue:
Values.Add(value);
break;
case CommandOptionType.SingleValue:
if (Values.Any())
{
return false;
}
Values.Add(value);
break;
case CommandOptionType.BoolValue:
if (Values.Any())
{
return false;
}
if (value == null)
{
// add null to indicate that the option was present, but had no value
Values.Add(null);
BoolValue = true;
}
else
{
bool boolValue;
if (!bool.TryParse(value, out boolValue))
{
return false;
}
Values.Add(value);
BoolValue = boolValue;
}
break;
case CommandOptionType.NoValue:
if (value != null)
{
return false;
}
// Add a value to indicate that this option was specified
Values.Add("on");
break;
default:
break;
}
return true;
}
public bool HasValue()
{
return Values.Any();
}
public string Value()
{
return HasValue() ? Values[0] : null;
}
private bool IsEnglishLetter(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
}
}

View File

@ -1,14 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.Cli.CommandLine
{
internal enum CommandOptionType
{
MultipleValue,
SingleValue,
BoolValue,
NoValue
}
}

View File

@ -1,45 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using Microsoft.DotNet.Tools;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandParsingException : Exception
{
private readonly bool _isRequiredSubCommandMissing;
public CommandParsingException(
string message,
string helpText = null) : base(message)
{
HelpText = helpText ?? "";
Data.Add("CLI_User_Displayed_Exception", true);
}
public CommandParsingException(
CommandLineApplication command,
string message,
bool isRequiredSubCommandMissing = false)
: this(message)
{
Command = command;
_isRequiredSubCommandMissing = isRequiredSubCommandMissing;
}
public CommandLineApplication Command { get; }
public string HelpText { get; } = "";
public override string Message
{
get
{
return _isRequiredSubCommandMissing
? CommonLocalizableStrings.RequiredCommandNotPassed
: base.Message;
}
}
}
}

View File

@ -1,10 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class HelpMessageStrings
{
internal const string MSBuildAdditionalArgsHelpText = LocalizableStrings.MSBuildAdditionalArgsHelpText;
}
}

View File

@ -1,50 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class LocalizableStrings
{
public const string LastArgumentMultiValueError = "The last argument '{0}' accepts multiple values. No more argument can be added.";
public const string OptionRequiresSingleValueWhichIsMissing = "Required value for option '{0}' was not provided.";
public const string UnexpectedValueForOptionError = "Unexpected value '{0}' for option '{1}'";
public const string UnexpectedArgumentError = "Unrecognized {0} '{1}'";
public const string ResponseFileNotFoundError = "Response file '{0}' doesn't exist.";
public const string ShowHelpInfo = "Show help information";
public const string ShowVersionInfo = "Show version information";
public const string ShowHintInfo = "Specify --{0} for a list of available options and commands.";
public const string UsageHeader = "Usage:";
public const string UsageArgumentsToken = " [arguments]";
public const string UsageArgumentsHeader = "Arguments:";
public const string UsageOptionsToken = " [options]";
public const string UsageOptionsHeader = "Options:";
public const string UsageCommandToken = " [command]";
public const string UsageCommandsHeader = "Commands:";
public const string UsageCommandsDetailHelp = "Use \"{0} [command] --help\" for more information about a command.";
public const string UsageCommandArgs = " [args]";
public const string UsageCommandAdditionalArgs = " [[--] <additional arguments>...]]";
public const string UsageCommandsAdditionalArgsHeader = "Additional Arguments:";
public const string InvalidTemplateError = "Invalid template pattern '{0}'";
public const string MSBuildAdditionalArgsHelpText = "Any extra options that should be passed to MSBuild. See 'dotnet msbuild -h' for available options.";
}
}

View File

@ -1,189 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.Tools
{
internal class CommonLocalizableStrings
{
public const string UnsupportedProjectType = "Unsupported project type. Please check with your sdk provider.";
public const string ProjectAlreadyHasAreference = "Project already has a reference to `{0}`.";
public const string ProjectReferenceCouldNotBeFound = "Project reference `{0}` could not be found.";
public const string ProjectReferenceRemoved = "Project reference `{0}` removed.";
// Project related
public const string Project = "Project";
public const string ProjectFile = "Project file";
public const string Reference = "Reference";
public const string ProjectReference = "Project reference";
public const string ProjectReferenceOneOrMore = "Project reference(s)";
public const string PackageReference = "Package reference";
public const string P2P = "Project to Project";
public const string P2PReference = "Project to Project reference";
public const string Package = "Package";
public const string Solution = "Solution";
public const string SolutionFile = "Solution file";
public const string Executable = "Executable";
public const string Library = "Library";
public const string Program = "Program";
public const string Application = "Application";
public const string ReferenceAddedToTheProject = "Reference `{0}` added to the project.";
// Verbs
public const string Add = "Add";
public const string Remove = "Remove";
public const string Delete = "Delete";
public const string Update = "Update";
public const string New = "New";
public const string List = "List";
public const string Load = "Load";
public const string Save = "Save";
public const string Find = "Find";
// Other
public const string Error = "Error";
public const string Warning = "Warning";
public const string File = "File";
public const string Directory = "Directory";
public const string Type = "Type";
public const string Value = "Value";
public const string Group = "Group";
// General sentences";
public const string XAddedToY = "{0} added to {1}.";
public const string XRemovedFromY = "{0} removed from {1}.";
public const string XDeletedFromY = "{0} deleted from {1}.";
public const string XSuccessfullyUpdated = "{0} successfully updated.";
// General errors
/// Invalid
public const string XIsInvalid = "{0} is invalid.";
public const string XYFoundButInvalid = "{0} `{1}` found but is invalid.";
public const string XFoundButInvalid = "`{0}` found but is invalid.";
public const string OperationInvalid = "Operation is invalid.";
public const string OperationXInvalid = "Operation {0} is invalid.";
/// Not Found
public const string XNotFound = "{0} not found.";
public const string XOrYNotFound = "{0} or {1} not found.";
public const string XOrYNotFoundInZ = "{0} or {1} not found in `{2}`.";
public const string FileNotFound = "File `{0}` not found.";
/// Does not exist
public const string XDoesNotExist = "{0} does not exist.";
public const string XYDoesNotExist = "{0} `{1}` does not exist.";
/// Duplicate
public const string MoreThanOneXFound = "More than one {0} found.";
public const string XAlreadyContainsY = "{0} already contains {1}.";
public const string XAlreadyContainsYZ = "{0} already contains {1} `{2}`.";
public const string XAlreadyHasY = "{0} already has {1}.";
public const string XAlreadyHasYZ = "{0} already has {1} `{2}`.";
/// Other
public const string XWasNotExpected = "{0} was not expected.";
public const string XNotProvided = "{0} not provided.";
public const string SpecifyAtLeastOne = "Please specify at least one {0}.";
public const string CouldNotConnectWithTheServer = "Could not connect with the server.";
// Command Line Parsing
public const string RequiredArgumentIsInvalid = "Required argument {0} is invalid.";
public const string OptionIsInvalid = "Option {0} is invalid.";
public const string ArgumentIsInvalid = "Argument {0} is invalid.";
public const string RequiredArgumentNotPassed = "Required argument {0} was not provided.";
public const string RequiredCommandNotPassed = "Required command was not provided.";
// dotnet <verb>
/// Project
public const string CouldNotFindAnyProjectInDirectory = "Could not find any project in `{0}`.";
public const string CouldNotFindProjectOrDirectory = "Could not find project or directory `{0}`.";
public const string MoreThanOneProjectInDirectory = "Found more than one project in `{0}`. Please specify which one to use.";
public const string FoundInvalidProject = "Found a project `{0}` but it is invalid.";
public const string InvalidProject = "Invalid project `{0}`.";
/// Solution
public const string CouldNotFindSolutionIn = "Specified solution file {0} does not exist, or there is no solution file in the directory.";
public const string CouldNotFindSolutionOrDirectory = "Could not find solution or directory `{0}`.";
public const string MoreThanOneSolutionInDirectory = "Found more than one solution file in {0}. Please specify which one to use.";
public const string InvalidSolutionFormatString = "Invalid solution `{0}`. {1}"; // {0} is the solution path, {1} is already localized details on the failure
public const string SolutionDoesNotExist = "Specified solution file {0} does not exist, or there is no solution file in the directory.";
/// add p2p
public const string ReferenceDoesNotExist = "Reference {0} does not exist.";
public const string ReferenceIsInvalid = "Reference `{0}` is invalid.";
public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add.";
public const string ProjectAlreadyHasAReference = "Project {0} already has a reference `{1}`.";
/// add package
public const string PackageReferenceDoesNotExist = "Package reference `{0}` does not exist.";
public const string PackageReferenceIsInvalid = "Package reference `{0}` is invalid.";
public const string SpecifyAtLeastOnePackageReferenceToAdd = "You must specify at least one package to add.";
public const string PackageReferenceAddedToTheProject = "Package reference `{0}` added to the project.";
public const string ProjectAlreadyHasAPackageReference = "Project {0} already has a reference `{1}`.";
public const string PleaseSpecifyVersion = "Please specify a version of the package.";
/// add sln
public const string ProjectDoesNotExist = "Project `{0}` does not exist.";
public const string ProjectIsInvalid = "Project `{0}` is invalid.";
public const string SpecifyAtLeastOneProjectToAdd = "You must specify at least one project to add.";
public const string ProjectAddedToTheSolution = "Project `{0}` added to the solution.";
public const string SolutionAlreadyContainsProject = "Solution {0} already contains project {1}.";
/// del p2p
public const string ReferenceNotFoundInTheProject = "Specified reference {0} does not exist in project {1}.";
public const string ReferenceRemoved = "Reference `{0}` deleted from the project.";
public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to remove.";
public const string ReferenceDeleted = "Reference `{0}` deleted.";
/// del pkg
public const string PackageReferenceNotFoundInTheProject = "Package reference `{0}` could not be found in the project.";
public const string PackageReferenceRemoved = "Reference `{0}` deleted from the project.";
public const string SpecifyAtLeastOnePackageReferenceToRemove = "You must specify at least one package reference to remove.";
public const string PackageReferenceDeleted = "Package reference `{0}` deleted.";
/// del sln
public const string ProjectNotFoundInTheSolution = "Project `{0}` could not be found in the solution.";
public const string ProjectRemoved = "Project `{0}` removed from solution.";
public const string SpecifyAtLeastOneProjectToRemove = "You must specify at least one project to remove.";
public const string ProjectDeleted = "Project `{0}` deleted from solution.";
/// list
public const string NoReferencesFound = "There are no {0} references in project {1}. ;; {0} is the type of the item being requested (project, package, p2p) and {1} is the object operated on (a project file or a solution file). ";
public const string NoProjectsFound = "No projects found in the solution.";
/// arguments
public const string ArgumentsProjectOrSolutionDescription = "The project or solution to operation on. If a file is not specified, the current directory is searched.";
/// sln
public const string ArgumentsProjectDescription = "The project file to operate on. If a file is not specified, the command will search the current directory for one.";
public const string ArgumentsSolutionDescription = "Solution file to operate on. If not specified, the command will search the current directory for one.";
public const string CmdSlnFile = "SLN_FILE";
public const string CmdProjectFile = "PROJECT";
/// commands
public const string CmdFramework = "FRAMEWORK";
/// update pkg
public const string PleaseSpecifyNewVersion = "Please specify new version of the package.";
public const string PleaseSpecifyWhichPackageToUpdate = "Please specify which package to update.";
public const string NothingToUpdate = "Nothing to update.";
public const string EverythingUpToDate = "Everything is already up-to-date.";
public const string PackageVersionUpdatedTo = "Version of package `{0}` updated to `{1}`.";
public const string PackageVersionUpdated = "Version of package `{0}` updated.";
public const string CouldNotUpdateTheVersion = "Could not update the version of the package `{0}`.";
/// new
public const string TemplateCreatedSuccessfully = "The template {0} created successfully. Please run \"dotnet restore\" to get started!";
public const string TemplateInstalledSuccesfully = "The template {0} installed successfully. You can use \"dotnet new {0}\" to get started with the new template.";
public const string TemplateCreateError = "Template {0} could not be created. Error returned was: {1}.";
public const string TemplateInstallError = "Template {0} could not be installed. Error returned was: {1}.";
public const string SpecifiedNameExists = "Specified name {0} already exists. Please specify a different name.";
public const string SpecifiedAliasExists = "Specified alias {0} already exists. Please specify a different alias.";
public const string MandatoryParameterMissing = "Mandatory parameter {0} missing for template {1}. ";
public const string ProjectNotCompatibleWithFrameworks = "Project `{0}` cannot be added due to incompatible targeted frameworks between the two projects. Please review the project you are trying to add and verify that is compatible with the following targets:";
public const string ProjectDoesNotTargetFramework = "Project `{0}` does not target framework `{1}`.";
public const string ProjectCouldNotBeEvaluated = "Project `{0}` could not be evaluated. Evaluation failed with following error:\n{1}";
}
}

View File

@ -1,97 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.DotNet.Cli.CommandLine;
//using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Archive;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Microsoft.DotNet.Tools.Archive
{
public partial class ArchiveCommand
{
public static int Main(string[] args)
{
//DebugHelper.HandleDebugSwitch(ref args);
var app = new CommandLineApplication();
app.Name = "archive";
app.FullName = ".NET archiver";
app.Description = "Archives and expands sets of files";
app.HelpOption("-h|--help");
var extract = app.Option("-x|--extract <outputDirectory>", "Directory to extract to", CommandOptionType.SingleValue);
var archiveFile = app.Option("-a|--archive <file>", "Archive to operate on", CommandOptionType.SingleValue);
var externals = app.Option("--external <external>...", "External files and directories to consider for extraction", CommandOptionType.MultipleValue);
var sources = app.Argument("<sources>...", "Files & directory to include in the archive", multipleValues: true);
app.OnExecute(() =>
{
if (extract.HasValue() && sources.Values.Any())
{
Console.WriteLine("Extract '-x' can only be specified when no '<sources>' are specified to add to the archive.");
return 1;
}
else if (!extract.HasValue() && !sources.Values.Any())
{
Console.WriteLine("Either extract '-x' or '<sources>' must be specified.");
return 1;
}
if (!archiveFile.HasValue())
{
Console.WriteLine("Archive '-a' must be specified.");
return 1;
}
var progress = new ConsoleProgressReport();
var archive = new IndexedArchive();
foreach (var external in externals.Values)
{
if (Directory.Exists(external))
{
archive.AddExternalDirectory(external);
}
else
{
archive.AddExternalFile(external);
}
}
if (sources.Values.Any())
{
foreach (var source in sources.Values)
{
if (Directory.Exists(source))
{
archive.AddDirectory(source, progress);
}
else
{
archive.AddFile(source, Path.GetFileName(source));
}
}
archive.Save(archiveFile.Value(), progress);
}
else // sources not specified, extract must have been specified
{
archive.Extract(archiveFile.Value(), extract.Value(), progress);
}
return 0;
});
return app.Execute(args);
}
}
}

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<OutputType>Exe</OutputType>
<EnableApiCheck>false</EnableApiCheck>
<RuntimeIdentifiers>win7-x64;linux-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj" />
</ItemGroup>
</Project>