Fixed naming conventions
This commit is contained in:
@@ -5,39 +5,39 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
{
|
||||
internal class DataWriter : IArchiveDataWriter
|
||||
{
|
||||
private readonly long size;
|
||||
private long remainingBytes;
|
||||
private readonly Stream stream;
|
||||
private readonly long _size;
|
||||
private long _remainingBytes;
|
||||
private readonly Stream _stream;
|
||||
|
||||
public DataWriter(Stream data, long dataSizeInBytes)
|
||||
{
|
||||
size = dataSizeInBytes;
|
||||
remainingBytes = size;
|
||||
stream = data;
|
||||
_size = dataSizeInBytes;
|
||||
_remainingBytes = _size;
|
||||
_stream = data;
|
||||
}
|
||||
|
||||
public bool CanWrite { get; private set; } = true;
|
||||
|
||||
public int Write(byte[] buffer, int count)
|
||||
{
|
||||
if (remainingBytes == 0)
|
||||
if (_remainingBytes == 0)
|
||||
{
|
||||
CanWrite = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bytesToWrite;
|
||||
if (remainingBytes - count < 0)
|
||||
if (_remainingBytes - count < 0)
|
||||
{
|
||||
bytesToWrite = (int)remainingBytes;
|
||||
bytesToWrite = (int)_remainingBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesToWrite = count;
|
||||
}
|
||||
|
||||
stream.Write(buffer, 0, bytesToWrite);
|
||||
remainingBytes -= bytesToWrite;
|
||||
_stream.Write(buffer, 0, bytesToWrite);
|
||||
_remainingBytes -= bytesToWrite;
|
||||
|
||||
return bytesToWrite;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,13 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
/// </remarks>
|
||||
public class LegacyTarWriter : IDisposable
|
||||
{
|
||||
private readonly Stream outStream;
|
||||
private readonly Stream _outStream;
|
||||
private bool _isClosed;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer for writing.
|
||||
/// </summary>
|
||||
protected byte[] buffer = new byte[1024];
|
||||
private bool isClosed;
|
||||
public bool ReadOnZero = true;
|
||||
|
||||
/// <summary>
|
||||
/// Writes tar (see GNU tar) archive to a stream
|
||||
@@ -25,16 +28,25 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
/// <param name="outStream">stream to write archive to</param>
|
||||
public LegacyTarWriter(Stream outStream)
|
||||
{
|
||||
this.outStream = outStream;
|
||||
_outStream = outStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to read on zero.
|
||||
/// </summary>
|
||||
public bool ReadOnZero { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output stream.
|
||||
/// </summary>
|
||||
protected virtual Stream OutStream
|
||||
{
|
||||
get { return outStream; }
|
||||
get { return _outStream; }
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
@@ -85,13 +97,13 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
WriteDirectoryEntry(directory, 0, 0, 0755);
|
||||
|
||||
string[] files = Directory.GetFiles(directory);
|
||||
foreach (var fileName in files)
|
||||
foreach (string fileName in files)
|
||||
{
|
||||
Write(fileName);
|
||||
}
|
||||
|
||||
string[] directories = Directory.GetDirectories(directory);
|
||||
foreach (var dirName in directories)
|
||||
foreach (string dirName in directories)
|
||||
{
|
||||
WriteDirectoryEntry(dirName, 0, 0, 0755);
|
||||
if (doRecursive)
|
||||
@@ -134,10 +146,9 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
AlignTo512(dataSizeInBytes, false);
|
||||
}
|
||||
|
||||
public virtual void Write(Stream data, long dataSizeInBytes, string name, int userId, int groupId, int mode,
|
||||
DateTime lastModificationTime)
|
||||
public virtual void Write(Stream data, long dataSizeInBytes, string name, int userId, int groupId, int mode, DateTime lastModificationTime)
|
||||
{
|
||||
if (isClosed)
|
||||
if (_isClosed)
|
||||
throw new TarException("Can not write to the closed writer");
|
||||
|
||||
// handle long file names (> 99 characters)
|
||||
@@ -172,7 +183,7 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
private void WriteLongName(string name, int userId, int groupId, int mode, DateTime lastModificationTime)
|
||||
{
|
||||
// must include a trailing \0
|
||||
var nameLength = Encoding.UTF8.GetByteCount(name);
|
||||
int nameLength = Encoding.UTF8.GetByteCount(name);
|
||||
byte[] entryName = new byte[nameLength + 1];
|
||||
|
||||
Encoding.UTF8.GetBytes(name, 0, name.Length, entryName, 0);
|
||||
@@ -238,7 +249,7 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
|
||||
public void AlignTo512(long size, bool acceptZero)
|
||||
{
|
||||
size = size % 512;
|
||||
size %= 512;
|
||||
if (size == 0 && !acceptZero) return;
|
||||
while (size < 512)
|
||||
{
|
||||
@@ -249,10 +260,13 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
if (isClosed) return;
|
||||
if (_isClosed)
|
||||
return;
|
||||
|
||||
AlignTo512(0, true);
|
||||
AlignTo512(0, true);
|
||||
isClosed = true;
|
||||
|
||||
_isClosed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AMWD.Common.Packing.Tar.Utils
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using AMWD.Common.Packing.Tar.Interfaces;
|
||||
@@ -7,8 +8,11 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
{
|
||||
internal class TarHeader : ITarHeader
|
||||
{
|
||||
private readonly byte[] buffer = new byte[512];
|
||||
private long headerChecksum;
|
||||
private static readonly byte[] _spaces = Encoding.ASCII.GetBytes(" ");
|
||||
private readonly byte[] _buffer = new byte[512];
|
||||
|
||||
private string _fileName;
|
||||
private long _headerChecksum;
|
||||
|
||||
public TarHeader()
|
||||
{
|
||||
@@ -18,63 +22,51 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
GroupId = 61; // 101 dec
|
||||
}
|
||||
|
||||
private string fileName;
|
||||
protected readonly DateTime TheEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
public EntryType EntryType { get; set; }
|
||||
private static byte[] spaces = Encoding.ASCII.GetBytes(" ");
|
||||
|
||||
public virtual string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return fileName.Replace("\0", string.Empty);
|
||||
}
|
||||
get => _fileName.Replace("\0", string.Empty);
|
||||
set
|
||||
{
|
||||
if (value.Length > 100)
|
||||
{
|
||||
throw new TarException("A file name can not be more than 100 chars long");
|
||||
}
|
||||
fileName = value;
|
||||
|
||||
_fileName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Mode { get; set; }
|
||||
|
||||
public string ModeString
|
||||
{
|
||||
get { return Convert.ToString(Mode, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
=> Convert.ToString(Mode, 8).PadLeft(7, '0');
|
||||
|
||||
public int UserId { get; set; }
|
||||
|
||||
public virtual string UserName
|
||||
{
|
||||
get { return UserId.ToString(); }
|
||||
set { UserId = Int32.Parse(value); }
|
||||
get => UserId.ToString();
|
||||
set => UserId = int.Parse(value);
|
||||
}
|
||||
|
||||
public string UserIdString
|
||||
{
|
||||
get { return Convert.ToString(UserId, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
=> Convert.ToString(UserId, 8).PadLeft(7, '0');
|
||||
|
||||
public int GroupId { get; set; }
|
||||
|
||||
public virtual string GroupName
|
||||
{
|
||||
get { return GroupId.ToString(); }
|
||||
set { GroupId = Int32.Parse(value); }
|
||||
get => GroupId.ToString();
|
||||
set => GroupId = int.Parse(value);
|
||||
}
|
||||
|
||||
public string GroupIdString
|
||||
{
|
||||
get { return Convert.ToString(GroupId, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
=> Convert.ToString(GroupId, 8).PadLeft(7, '0');
|
||||
|
||||
public long SizeInBytes { get; set; }
|
||||
|
||||
public string SizeString
|
||||
{
|
||||
get { return Convert.ToString(SizeInBytes, 8).PadLeft(11, '0'); }
|
||||
}
|
||||
=> Convert.ToString(SizeInBytes, 8).PadLeft(11, '0');
|
||||
|
||||
public DateTime LastModification { get; set; }
|
||||
|
||||
@@ -82,71 +74,63 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToString((long)(LastModification - TheEpoch).TotalSeconds, 8).PadLeft(11, '0');
|
||||
long unixTime = ((DateTimeOffset)DateTime.SpecifyKind(LastModification, DateTimeKind.Utc)).ToUnixTimeSeconds();
|
||||
return Convert.ToString(unixTime, 8).PadLeft(11, '0');
|
||||
}
|
||||
}
|
||||
|
||||
public string HeaderChecksumString
|
||||
{
|
||||
get { return Convert.ToString(headerChecksum, 8).PadLeft(6, '0'); }
|
||||
}
|
||||
=> Convert.ToString(_headerChecksum, 8).PadLeft(6, '0');
|
||||
|
||||
public virtual int HeaderSize
|
||||
{
|
||||
get { return 512; }
|
||||
}
|
||||
public virtual int HeaderSize => 512;
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
public byte[] GetBytes() => _buffer.ToArray();
|
||||
|
||||
public virtual bool UpdateHeaderFromBytes()
|
||||
{
|
||||
FileName = Encoding.ASCII.GetString(buffer, 0, 100);
|
||||
// thanks to Shasha Alperocivh. Trimming nulls.
|
||||
Mode = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 100, 7).Trim(), 8);
|
||||
UserId = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 108, 7).Trim(), 8);
|
||||
GroupId = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 116, 7).Trim(), 8);
|
||||
FileName = Encoding.ASCII.GetString(_buffer, 0, 100);
|
||||
|
||||
EntryType = (EntryType)buffer[156];
|
||||
// Thanks to Shasha Alperocivh. Trimming nulls.
|
||||
Mode = Convert.ToInt32(Encoding.ASCII.GetString(_buffer, 100, 7).Trim(), 8);
|
||||
UserId = Convert.ToInt32(Encoding.ASCII.GetString(_buffer, 108, 7).Trim(), 8);
|
||||
GroupId = Convert.ToInt32(Encoding.ASCII.GetString(_buffer, 116, 7).Trim(), 8);
|
||||
|
||||
if ((buffer[124] & 0x80) == 0x80) // if size in binary
|
||||
EntryType = (EntryType)_buffer[156];
|
||||
|
||||
if ((_buffer[124] & 0x80) == 0x80) // if size in binary
|
||||
{
|
||||
long sizeBigEndian = BitConverter.ToInt64(buffer, 0x80);
|
||||
long sizeBigEndian = BitConverter.ToInt64(_buffer, 0x80);
|
||||
SizeInBytes = IPAddress.NetworkToHostOrder(sizeBigEndian);
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeInBytes = Convert.ToInt64(Encoding.ASCII.GetString(buffer, 124, 11), 8);
|
||||
SizeInBytes = Convert.ToInt64(Encoding.ASCII.GetString(_buffer, 124, 11), 8);
|
||||
}
|
||||
long unixTimeStamp = Convert.ToInt64(Encoding.ASCII.GetString(buffer, 136, 11), 8);
|
||||
LastModification = TheEpoch.AddSeconds(unixTimeStamp);
|
||||
long unixTimeStamp = Convert.ToInt64(Encoding.ASCII.GetString(_buffer, 136, 11), 8);
|
||||
LastModification = DateTimeOffset.FromUnixTimeSeconds(unixTimeStamp).DateTime;
|
||||
|
||||
var storedChecksum = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 148, 6));
|
||||
RecalculateChecksum(buffer);
|
||||
if (storedChecksum == headerChecksum)
|
||||
{
|
||||
int storedChecksum = Convert.ToInt32(Encoding.ASCII.GetString(_buffer, 148, 6));
|
||||
RecalculateChecksum(_buffer);
|
||||
if (storedChecksum == _headerChecksum)
|
||||
return true;
|
||||
}
|
||||
|
||||
RecalculateAltChecksum(buffer);
|
||||
return storedChecksum == headerChecksum;
|
||||
RecalculateAltChecksum(_buffer);
|
||||
return storedChecksum == _headerChecksum;
|
||||
}
|
||||
|
||||
private void RecalculateAltChecksum(byte[] buf)
|
||||
{
|
||||
spaces.CopyTo(buf, 148);
|
||||
headerChecksum = 0;
|
||||
_spaces.CopyTo(buf, 148);
|
||||
_headerChecksum = 0;
|
||||
foreach (byte b in buf)
|
||||
{
|
||||
if ((b & 0x80) == 0x80)
|
||||
{
|
||||
headerChecksum -= b ^ 0x80;
|
||||
_headerChecksum -= b ^ 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
headerChecksum += b;
|
||||
_headerChecksum += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,41 +138,42 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
public virtual byte[] GetHeaderValue()
|
||||
{
|
||||
// Clean old values
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
Array.Clear(_buffer, 0, _buffer.Length);
|
||||
|
||||
if (string.IsNullOrEmpty(FileName)) throw new TarException("FileName can not be empty.");
|
||||
if (FileName.Length >= 100) throw new TarException("FileName is too long. It must be less than 100 bytes.");
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
throw new TarException("FileName can not be empty.");
|
||||
|
||||
if (FileName.Length >= 100)
|
||||
throw new TarException("FileName is too long. It must be less than 100 bytes.");
|
||||
|
||||
// Fill header
|
||||
Encoding.ASCII.GetBytes(FileName.PadRight(100, '\0')).CopyTo(buffer, 0);
|
||||
Encoding.ASCII.GetBytes(ModeString).CopyTo(buffer, 100);
|
||||
Encoding.ASCII.GetBytes(UserIdString).CopyTo(buffer, 108);
|
||||
Encoding.ASCII.GetBytes(GroupIdString).CopyTo(buffer, 116);
|
||||
Encoding.ASCII.GetBytes(SizeString).CopyTo(buffer, 124);
|
||||
Encoding.ASCII.GetBytes(LastModificationString).CopyTo(buffer, 136);
|
||||
Encoding.ASCII.GetBytes(FileName.PadRight(100, '\0')).CopyTo(_buffer, 0);
|
||||
Encoding.ASCII.GetBytes(ModeString).CopyTo(_buffer, 100);
|
||||
Encoding.ASCII.GetBytes(UserIdString).CopyTo(_buffer, 108);
|
||||
Encoding.ASCII.GetBytes(GroupIdString).CopyTo(_buffer, 116);
|
||||
Encoding.ASCII.GetBytes(SizeString).CopyTo(_buffer, 124);
|
||||
Encoding.ASCII.GetBytes(LastModificationString).CopyTo(_buffer, 136);
|
||||
|
||||
// buffer[156] = 20;
|
||||
buffer[156] = ((byte)EntryType);
|
||||
_buffer[156] = ((byte)EntryType);
|
||||
|
||||
RecalculateChecksum(buffer);
|
||||
RecalculateChecksum(_buffer);
|
||||
|
||||
// Write checksum
|
||||
Encoding.ASCII.GetBytes(HeaderChecksumString).CopyTo(buffer, 148);
|
||||
Encoding.ASCII.GetBytes(HeaderChecksumString).CopyTo(_buffer, 148);
|
||||
|
||||
return buffer;
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
protected virtual void RecalculateChecksum(byte[] buf)
|
||||
{
|
||||
// Set default value for checksum. That is 8 spaces.
|
||||
spaces.CopyTo(buf, 148);
|
||||
_spaces.CopyTo(buf, 148);
|
||||
|
||||
// Calculate checksum
|
||||
headerChecksum = 0;
|
||||
_headerChecksum = 0;
|
||||
foreach (byte b in buf)
|
||||
{
|
||||
headerChecksum += b;
|
||||
}
|
||||
_headerChecksum += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,59 +9,48 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
/// </summary>
|
||||
internal class UsTarHeader : TarHeader
|
||||
{
|
||||
private const string magic = "ustar";
|
||||
private const string version = " ";
|
||||
private string groupName;
|
||||
private const string Magic = "ustar";
|
||||
private const string Version = " ";
|
||||
|
||||
private string namePrefix = string.Empty;
|
||||
private string userName;
|
||||
private string _groupName;
|
||||
|
||||
private string _namePrefix = string.Empty;
|
||||
private string _userName;
|
||||
|
||||
public override string UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return userName.Replace("\0", string.Empty);
|
||||
}
|
||||
get => _userName.Replace("\0", string.Empty);
|
||||
set
|
||||
{
|
||||
if (value.Length > 32)
|
||||
{
|
||||
throw new TarException("user name can not be longer than 32 chars");
|
||||
}
|
||||
userName = value;
|
||||
|
||||
_userName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GroupName
|
||||
{
|
||||
get
|
||||
{
|
||||
return groupName.Replace("\0", string.Empty);
|
||||
}
|
||||
get => _groupName.Replace("\0", string.Empty);
|
||||
set
|
||||
{
|
||||
if (value.Length > 32)
|
||||
{
|
||||
throw new TarException("group name can not be longer than 32 chars");
|
||||
}
|
||||
groupName = value;
|
||||
|
||||
_groupName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return namePrefix.Replace("\0", string.Empty) + base.FileName.Replace("\0", string.Empty);
|
||||
}
|
||||
get => _namePrefix.Replace("\0", string.Empty) + base.FileName.Replace("\0", string.Empty);
|
||||
set
|
||||
{
|
||||
if (value.Length > 100)
|
||||
{
|
||||
if (value.Length > 255)
|
||||
{
|
||||
throw new TarException("UsTar fileName can not be longer thatn 255 chars");
|
||||
}
|
||||
|
||||
int position = value.Length - 100;
|
||||
|
||||
// Find first path separator in the remaining 100 chars of the file name
|
||||
@@ -75,7 +64,8 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
}
|
||||
if (position == value.Length)
|
||||
position = value.Length - 100;
|
||||
namePrefix = value.Substring(0, position);
|
||||
_namePrefix = value.Substring(0, position);
|
||||
|
||||
base.FileName = value.Substring(position, value.Length - position);
|
||||
}
|
||||
else
|
||||
@@ -88,26 +78,26 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
public override bool UpdateHeaderFromBytes()
|
||||
{
|
||||
byte[] bytes = GetBytes();
|
||||
|
||||
UserName = Encoding.ASCII.GetString(bytes, 0x109, 32);
|
||||
GroupName = Encoding.ASCII.GetString(bytes, 0x129, 32);
|
||||
namePrefix = Encoding.ASCII.GetString(bytes, 347, 157);
|
||||
_namePrefix = Encoding.ASCII.GetString(bytes, 347, 157);
|
||||
|
||||
return base.UpdateHeaderFromBytes();
|
||||
}
|
||||
|
||||
internal static bool IsPathSeparator(char ch)
|
||||
{
|
||||
return (ch == '\\' || ch == '/' || ch == '|'); // All the path separators I ever met.
|
||||
}
|
||||
=> ch == '\\' || ch == '/' || ch == '|'; // All the path separators I ever met.
|
||||
|
||||
public override byte[] GetHeaderValue()
|
||||
{
|
||||
byte[] header = base.GetHeaderValue();
|
||||
|
||||
Encoding.ASCII.GetBytes(magic).CopyTo(header, 0x101); // Mark header as ustar
|
||||
Encoding.ASCII.GetBytes(version).CopyTo(header, 0x106);
|
||||
Encoding.ASCII.GetBytes(Magic).CopyTo(header, 0x101); // Mark header as ustar
|
||||
Encoding.ASCII.GetBytes(Version).CopyTo(header, 0x106);
|
||||
Encoding.ASCII.GetBytes(UserName).CopyTo(header, 0x109);
|
||||
Encoding.ASCII.GetBytes(GroupName).CopyTo(header, 0x129);
|
||||
Encoding.ASCII.GetBytes(namePrefix).CopyTo(header, 347);
|
||||
Encoding.ASCII.GetBytes(_namePrefix).CopyTo(header, 347);
|
||||
|
||||
if (SizeInBytes >= 0x1FFFFFFFF)
|
||||
{
|
||||
@@ -117,6 +107,7 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
|
||||
RecalculateChecksum(header);
|
||||
Encoding.ASCII.GetBytes(HeaderChecksumString).CopyTo(header, 148);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -128,7 +119,7 @@ namespace AMWD.Common.Packing.Tar.Utils
|
||||
|
||||
private static byte[] AlignTo12(byte[] bytes)
|
||||
{
|
||||
var retVal = new byte[12];
|
||||
byte[] retVal = new byte[12];
|
||||
bytes.CopyTo(retVal, 12 - bytes.Length);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user