Skip to content

Commit 50b5600

Browse files
committed
fixed issue with smartflush, improved software crc32c, added nodecoding option for list modes
1 parent b33b630 commit 50b5600

File tree

7 files changed

+62
-32
lines changed

7 files changed

+62
-32
lines changed

Blazer.Exe/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ private static int ProcessList(CommandLineParser<BlazerCommandLineOptions> optio
443443

444444
Stream inStreamSource = opt.Stdin ? Console.OpenStandardInput() : File.OpenRead(fileOptions.ArchiveName);
445445

446-
var decOptions = new BlazerDecompressionOptions(opt.Password) { EncyptFull = opt.EncryptFull };
446+
var decOptions = new BlazerDecompressionOptions(opt.Password) { EncyptFull = opt.EncryptFull, DoNotPerformDecoding = true };
447447
StringBuilder header = new StringBuilder();
448448
header.AppendLine(" Date Time Attr Size Name");
449449
header.AppendLine("------------------- ----- ------------ ------------------------");

Blazer.Net.Tests/StreamEncoderTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,12 @@ public void Test_Text()
101101
Артем нехотя поднялся со своего места у костра и, перетягивая со спины на грудь автомат, двинулся во тьму. Стоя на самом краю освещенного пространства, он демонстративно, как можно громче и внушительней, щелкнул затвором и хрипло крикнул: — Стоять! Пароль!");
102102
IntegrityHelper.StreamEncoderCheckCompressDecompress(buf);
103103
}
104+
105+
[Test]
106+
public void Test_Zero_Bytes()
107+
{
108+
var len = IntegrityHelper.StreamEncoderCheckCompressDecompress(new byte[0]);
109+
Assert.That(len, Is.EqualTo(0));
110+
}
104111
}
105112
}

Blazer.Net/Algorithms/Crc32C/Crc32CSoftware.cs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,43 @@ static Crc32CSoftware()
2121
}
2222
}
2323

24-
uint ICrc32CCalculator.Calculate(uint crc, byte[] buffer, int offset, int count)
24+
uint ICrc32CCalculator.Calculate(uint crc, byte[] input, int offset, int length)
2525
{
26-
uint crcLocal = crc ^ uint.MaxValue;
26+
uint crcLocal = uint.MaxValue ^ crc;
2727

2828
uint[] table = _table;
29-
while (count >= 16)
29+
while (length >= 16)
3030
{
31-
crcLocal = table[(15 * 256) + ((crcLocal ^ buffer[offset]) & 0xff)]
32-
^ table[(14 * 256) + (((crcLocal >> 8) ^ buffer[offset + 1]) & 0xff)]
33-
^ table[(13 * 256) + (((crcLocal >> 16) ^ buffer[offset + 2]) & 0xff)]
34-
^ table[(12 * 256) + (((crcLocal >> 24) ^ buffer[offset + 3]) & 0xff)]
35-
^ table[(11 * 256) + buffer[offset + 4]]
36-
^ table[(10 * 256) + buffer[offset + 5]]
37-
^ table[(9 * 256) + buffer[offset + 6]]
38-
^ table[(8 * 256) + buffer[offset + 7]]
39-
^ table[(7 * 256) + buffer[offset + 8]]
40-
^ table[(6 * 256) + buffer[offset + 9]]
41-
^ table[(5 * 256) + buffer[offset + 10]]
42-
^ table[(4 * 256) + buffer[offset + 11]]
43-
^ table[(3 * 256) + buffer[offset + 12]]
44-
^ table[(2 * 256) + buffer[offset + 13]]
45-
^ table[(1 * 256) + buffer[offset + 14]]
46-
^ table[(0 * 256) + buffer[offset + 15]];
31+
var a = table[(3 * 256) + input[offset + 12]]
32+
^ table[(2 * 256) + input[offset + 13]]
33+
^ table[(1 * 256) + input[offset + 14]]
34+
^ table[(0 * 256) + input[offset + 15]];
35+
36+
var b = table[(7 * 256) + input[offset + 8]]
37+
^ table[(6 * 256) + input[offset + 9]]
38+
^ table[(5 * 256) + input[offset + 10]]
39+
^ table[(4 * 256) + input[offset + 11]];
40+
41+
var c = table[(11 * 256) + input[offset + 4]]
42+
^ table[(10 * 256) + input[offset + 5]]
43+
^ table[(9 * 256) + input[offset + 6]]
44+
^ table[(8 * 256) + input[offset + 7]];
45+
46+
var d = table[(15 * 256) + ((crcLocal ^ input[offset]) & 0xff)]
47+
^ table[(14 * 256) + (((crcLocal >> 8) ^ input[offset + 1]) & 0xff)]
48+
^ table[(13 * 256) + (((crcLocal >> 16) ^ input[offset + 2]) & 0xff)]
49+
^ table[(12 * 256) + (((crcLocal >> 24) ^ input[offset + 3]) & 0xff)];
50+
51+
crcLocal = d ^ c ^ b ^ a;
4752
offset += 16;
48-
count -= 16;
53+
length -= 16;
4954
}
5055

51-
while (--count >= 0)
52-
crcLocal = table[(crcLocal ^ buffer[offset++]) & 0xff] ^ crcLocal >> 8;
56+
while (--length >= 0)
57+
crcLocal = table[(crcLocal ^ input[offset++]) & 0xff] ^ crcLocal >> 8;
58+
5359
return crcLocal ^ uint.MaxValue;
60+
5461
}
5562
}
5663
}

Blazer.Net/BlazerCompressionOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public string Password
4141
/// <summary>
4242
/// Encrypt full flag. Fully encypted streams does not reveal any information about inner data (blazer header is also encypted)
4343
/// </summary>
44+
/// <remarks>Flush can be unsupported with this mode</remarks>
4445
public bool EncryptFull { get; set; }
4546

4647
/// <summary>

Blazer.Net/BlazerDecompressionOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ public string Password
8080
/// </summary>
8181
public bool DoNotFireInfoCallbackOnOneFile { get; set; }
8282

83+
/// <summary>
84+
/// Skip real decoding. This option can be useful for 'list' or 'test' modes, when it required to get some info (e.g. files list) without real decoding
85+
/// </summary>
86+
public bool DoNotPerformDecoding { get; set; }
87+
8388
/// <summary>
8489
/// Create default options
8590
/// </summary>

Blazer.Net/BlazerInputStream.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ public override void Write(byte[] buffer, int offset, int count)
297297

298298
if (_flushMode == BlazerFlushMode.AutoFlush)
299299
Flush();
300-
else if (_flushMode == BlazerFlushMode.RespectFlush && buffer.Length < offset + count) // smart flush will flush data, if it smaller than buffer size. otherwise we use large binary data and it not required to be flushed
300+
else if (_flushMode == BlazerFlushMode.SmartFlush && buffer.Length < offset + count) // smart flush will flush data, if it smaller than buffer size. otherwise we use large binary data and it not required to be flushed
301301
Flush();
302302
}
303303

Blazer.Net/BlazerOutputStream.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ public override long Position
146146

147147
private BlazerFileInfo _fileInfo;
148148

149+
private bool _doNotPerformDecoding;
150+
149151
/// <summary>
150152
/// Returns information about compressed file, if exists (and only one file in archive)
151153
/// </summary>
@@ -175,7 +177,7 @@ public BlazerAlgorithm Algorithm
175177
{
176178
get
177179
{
178-
return _decoder.GetAlgorithmId();
180+
return (BlazerAlgorithm)_algorithmId;
179181
}
180182
}
181183

@@ -236,6 +238,7 @@ public BlazerOutputStream(Stream innerStream, BlazerDecompressionOptions options
236238
_fileInfoCallback = options.FileInfoCallback ?? (f => { });
237239
_doNotFireInfoCallbackOnOneFile = options.DoNotFireInfoCallbackOnOneFile;
238240
_noSeek = options.NoSeek;
241+
_doNotPerformDecoding = options.DoNotPerformDecoding;
239242

240243
if (options.EncyptFull)
241244
{
@@ -251,10 +254,14 @@ public BlazerOutputStream(Stream innerStream, BlazerDecompressionOptions options
251254
var decoder = options.Decoder;
252255
if (decoder == null)
253256
{
254-
if (options.CompressionOptions.Encoder == null)
255-
throw new InvalidOperationException("Missing decoder information");
256-
options.SetDecoderByAlgorithm(options.CompressionOptions.Encoder.GetAlgorithmId());
257-
decoder = options.Decoder;
257+
if (_doNotPerformDecoding) decoder = new NoCompressionDecoder();
258+
else
259+
{
260+
if (options.CompressionOptions.Encoder == null)
261+
throw new InvalidOperationException("Missing decoder information");
262+
options.SetDecoderByAlgorithm(options.CompressionOptions.Encoder.GetAlgorithmId());
263+
decoder = options.Decoder;
264+
}
258265
}
259266

260267
InitByFlags(options.CompressionOptions.GetFlags(), decoder, password);
@@ -389,7 +396,10 @@ public override int Read(byte[] buffer, int offset, int count)
389396
goto start;
390397
}
391398
else
392-
throw new InvalidOperationException("Invalid header");
399+
{
400+
if (!_doNotPerformDecoding)
401+
throw new InvalidOperationException("Invalid header");
402+
}
393403
}
394404

395405
var decoded = _decoder.Decode(info.Buffer, info.Offset, info.Length, _encodingType != 0);
@@ -424,10 +434,10 @@ private void ReadAndValidateHeader()
424434
if ((flags & (~BlazerFlags.AllKnownFlags)) != 0)
425435
throw new InvalidOperationException("Invalid flag combination. Try to use newer version of Blazer");
426436

427-
_decoder = EncoderDecoderFactory.GetDecoder((BlazerAlgorithm)((((uint)flags) >> 4) & 15));
437+
_algorithmId = (byte)((((uint)flags) >> 4) & 15);
438+
_decoder = _doNotPerformDecoding ? new NoCompressionDecoder() : EncoderDecoderFactory.GetDecoder((BlazerAlgorithm)_algorithmId);
428439
_maxUncompressedBlockSize = 1 << ((((int)flags) & 15) + 9);
429440
_maxUncompressedBlockSizeOrig = _maxUncompressedBlockSize;
430-
_algorithmId = (byte)_decoder.GetAlgorithmId();
431441
_includeCrc = (flags & BlazerFlags.IncludeCrc) != 0;
432442
_includeFooter = (flags & BlazerFlags.IncludeFooter) != 0;
433443
_shouldHaveFileInfo = (flags & BlazerFlags.OnlyOneFile) != 0;

0 commit comments

Comments
 (0)