Merge pull request #7645 from livarcocc/remove_archiver_code
Removing Microsoft.DotNet.Archive from the CLI
This commit is contained in:
commit
0a482954ae
39 changed files with 3 additions and 4647 deletions
|
@ -32,6 +32,7 @@
|
||||||
<MicroBuildVersion>0.2.0</MicroBuildVersion>
|
<MicroBuildVersion>0.2.0</MicroBuildVersion>
|
||||||
<SpaTemplateVersion>1.0.417</SpaTemplateVersion>
|
<SpaTemplateVersion>1.0.417</SpaTemplateVersion>
|
||||||
<XliffTasksVersion>0.2.0-beta-000042</XliffTasksVersion>
|
<XliffTasksVersion>0.2.0-beta-000042</XliffTasksVersion>
|
||||||
|
<DotNetCliArchiverVersion>0.2.0-beta-000059</DotNetCliArchiverVersion>
|
||||||
<AspNetCoreRuntimePackageBrandName>aspnetcore-store</AspNetCoreRuntimePackageBrandName>
|
<AspNetCoreRuntimePackageBrandName>aspnetcore-store</AspNetCoreRuntimePackageBrandName>
|
||||||
<AspNetCoreRuntimePackageFolderName>dev-26623</AspNetCoreRuntimePackageFolderName>
|
<AspNetCoreRuntimePackageFolderName>dev-26623</AspNetCoreRuntimePackageFolderName>
|
||||||
<AspNetCoreRuntimePackageVersion>2.1.0-preview1-26623</AspNetCoreRuntimePackageVersion>
|
<AspNetCoreRuntimePackageVersion>2.1.0-preview1-26623</AspNetCoreRuntimePackageVersion>
|
||||||
|
|
|
@ -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, LocalizableStrings.Decompressing, outSize, MeasureBy.Output);
|
|
||||||
lzmaProgress.SetProgress(0, 0);
|
|
||||||
decoder.Code(inStream, outStream, compressedSize, outSize, lzmaProgress);
|
|
||||||
lzmaProgress.SetProgress(inStream.Length, outSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,538 +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)
|
|
||||||
{
|
|
||||||
DestinationPath = destinationPath;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
SourceArchive = sourceArchive;
|
|
||||||
SourceFile = sourceFile;
|
|
||||||
ArchivePath = archivePath;
|
|
||||||
Hash = hash;
|
|
||||||
Size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 archive 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(LocalizableStrings.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 current 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
@ -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(); }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 cycles.
|
|
||||||
/// </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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.
|
|
|
@ -1,126 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<data name="Expanding" xml:space="preserve">
|
|
||||||
<value>Expanding</value>
|
|
||||||
</data>
|
|
||||||
<data name="Decompressing" xml:space="preserve">
|
|
||||||
<value>Decompressing</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
|
@ -1,21 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<Description>Archive and compression types.</Description>
|
|
||||||
<VersionPrefix>$(CliVersionPrefix)</VersionPrefix>
|
|
||||||
<TargetFramework>netstandard1.3</TargetFramework>
|
|
||||||
<AssemblyOriginatorKeyFile>../../tools/Key.snk</AssemblyOriginatorKeyFile>
|
|
||||||
<SignAssembly>true</SignAssembly>
|
|
||||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Update="**\*.resx" GenerateSource="true" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="NETStandard.Library" Version="1.6.0" />
|
|
||||||
<PackageReference Include="System.Linq.Parallel" Version="4.0.1" />
|
|
||||||
<PackageReference Include="XliffTasks" Version="$(XliffTasksVersion)" PrivateAssets="All" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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")]
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="cs" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Rozbalení</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Dekomprese</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="de" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Aufklappen</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Dekomprimieren</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="es" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Expandiendo</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Descomprimiendo</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="fr" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Développement</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Décompression</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="it" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Espansione</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Decompressione</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="ja" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">展開中</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">圧縮解除中</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="ko" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">확장하는 중</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">압축을 푸는 중</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="pl" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Rozwijanie</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Dekompresja</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="pt-BR" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Expandindo</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Descompactando</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="ru" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Идет расширение</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Идет извлечение</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="tr" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">Genişletme</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">Daraltma</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="zh-Hans" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">正在扩展</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">正在解压缩</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
|
||||||
<file datatype="xml" source-language="en" target-language="zh-Hant" original="../LocalizableStrings.resx">
|
|
||||||
<body>
|
|
||||||
<trans-unit id="Expanding">
|
|
||||||
<source>Expanding</source>
|
|
||||||
<target state="translated">正在展開</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="Decompressing">
|
|
||||||
<source>Decompressing</source>
|
|
||||||
<target state="translated">正在解壓縮</target>
|
|
||||||
<note />
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
|
||||||
</file>
|
|
||||||
</xliff>
|
|
|
@ -18,12 +18,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="NuGet.Common" Version="$(CLI_NuGet_Version)" />
|
<PackageReference Include="NuGet.Common" Version="$(CLI_NuGet_Version)" />
|
||||||
<PackageReference Include="NuGet.Configuration" Version="$(CLI_NuGet_Version)" />
|
<PackageReference Include="NuGet.Configuration" Version="$(CLI_NuGet_Version)" />
|
||||||
|
<PackageReference Include="Microsoft.DotNet.Archive" Version="$(DotNetCliArchiverVersion)" />
|
||||||
<PackageReference Include="XliffTasks" Version="$(XliffTasksVersion)" PrivateAssets="All" />
|
<PackageReference Include="XliffTasks" Version="$(XliffTasksVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
|
<ProjectReference Include="..\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
|
||||||
<ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
|
<ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
|
||||||
<ProjectReference Include="..\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -43,7 +43,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj" />
|
<ProjectReference Include="../Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj" />
|
||||||
<ProjectReference Include="../Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj" />
|
<ProjectReference Include="../Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj" />
|
||||||
<ProjectReference Include="../Microsoft.DotNet.Archive/Microsoft.DotNet.Archive.csproj" />
|
|
||||||
<ProjectReference Include="../Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj" />
|
<ProjectReference Include="../Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj" />
|
||||||
<ProjectReference Include="../Microsoft.DotNet.Cli.Sln.Internal/Microsoft.DotNet.Cli.Sln.Internal.csproj" />
|
<ProjectReference Include="../Microsoft.DotNet.Cli.Sln.Internal/Microsoft.DotNet.Cli.Sln.Internal.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -67,6 +66,7 @@
|
||||||
<PackageReference Include="Microsoft.TemplateEngine.Cli.Localization" Version="$(TemplateEngineVersion)" />
|
<PackageReference Include="Microsoft.TemplateEngine.Cli.Localization" Version="$(TemplateEngineVersion)" />
|
||||||
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="$(TemplateEngineVersion)" />
|
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="$(TemplateEngineVersion)" />
|
||||||
<PackageReference Include="Microsoft.TemplateEngine.Utils" Version="$(TemplateEngineVersion)" />
|
<PackageReference Include="Microsoft.TemplateEngine.Utils" Version="$(TemplateEngineVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.DotNet.Archive" Version="$(DotNetCliArchiverVersion)" />
|
||||||
<PackageReference Include="XliffTasks" Version="$(XliffTasksVersion)" PrivateAssets="All" />
|
<PackageReference Include="XliffTasks" Version="$(XliffTasksVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue