|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
namespace System.Formats.Tar
{
/// <summary>
/// Abstract class that represents a tar entry from an archive of a format that is based on the POSIX IEEE P1003.1 standard from 1988. This includes the formats <see cref="TarEntryFormat.Ustar"/> (represented by the <see cref="UstarTarEntry"/> class), <see cref="TarEntryFormat.Pax"/> (represented by the <see cref="PaxTarEntry"/> class) and <see cref="TarEntryFormat.Gnu"/> (represented by the <see cref="GnuTarEntry"/> class).
/// </summary>
/// <remarks>Formats that implement the POSIX IEEE P1003.1 standard from 1988, support the following header fields: <c>devmajor</c>, <c>devminor</c>, <c>gname</c> and <c>uname</c>.
/// Even though the <see cref="TarEntryFormat.Gnu"/> format is not POSIX compatible, it implements and supports the Unix-specific fields that were defined in that POSIX standard.</remarks>
public abstract partial class PosixTarEntry : TarEntry
{
// Constructor called when reading a TarEntry from a TarReader.
internal PosixTarEntry(TarHeader header, TarReader readerOfOrigin, TarEntryFormat format)
: base(header, readerOfOrigin, format)
{
}
// Constructor called when the user creates a TarEntry instance from scratch.
internal PosixTarEntry(TarEntryType entryType, string entryName, TarEntryFormat format, bool isGea)
: base(entryType, entryName, format, isGea)
{
_header._uName = string.Empty;
_header._gName = string.Empty;
_header._devMajor = 0;
_header._devMinor = 0;
}
// Constructor called when converting an entry to the selected format.
internal PosixTarEntry(TarEntry other, TarEntryFormat format)
: base(other, format)
{
if (other is PosixTarEntry)
{
Debug.Assert(other._header._uName != null);
Debug.Assert(other._header._gName != null);
_header._uName = other._header._uName;
_header._gName = other._header._gName;
_header._devMajor = other._header._devMajor;
_header._devMinor = other._header._devMinor;
}
_header._uName ??= string.Empty;
_header._gName ??= string.Empty;
}
/// <summary>
/// When the current entry represents a character device or a block device, the major number identifies the driver associated with the device.
/// </summary>
/// <remarks>Character and block devices are Unix-specific entry types.</remarks>
/// <exception cref="InvalidOperationException">The entry does not represent a block device or a character device.</exception>
/// <exception cref="ArgumentOutOfRangeException">The value is negative, or larger than 2097151 when using <see cref="TarEntryFormat.V7"/> or <see cref="TarEntryFormat.Ustar"/>.</exception>
public int DeviceMajor
{
get => _header._devMajor;
set
{
if (_header._typeFlag is not TarEntryType.BlockDevice and not TarEntryType.CharacterDevice)
{
throw new InvalidOperationException(SR.TarEntryBlockOrCharacterExpected);
}
ArgumentOutOfRangeException.ThrowIfNegative(value);
if (FormatIsOctalOnly)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan(value, 0x1FFFFF); // 7777777 in octal
}
_header._devMajor = value;
}
}
/// <summary>
/// When the current entry represents a character device or a block device, the minor number is used by the driver to distinguish individual devices it controls.
/// </summary>
/// <remarks>Character and block devices are Unix-specific entry types.</remarks>
/// <exception cref="InvalidOperationException">The entry does not represent a block device or a character device.</exception>
/// <exception cref="ArgumentOutOfRangeException">The value is negative, or larger than 2097151 when using <see cref="TarEntryFormat.V7"/> or <see cref="TarEntryFormat.Ustar"/>.</exception>
public int DeviceMinor
{
get => _header._devMinor;
set
{
if (_header._typeFlag is not TarEntryType.BlockDevice and not TarEntryType.CharacterDevice)
{
throw new InvalidOperationException(SR.TarEntryBlockOrCharacterExpected);
}
ArgumentOutOfRangeException.ThrowIfNegative(value);
if (FormatIsOctalOnly)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan(value, 0x1FFFFF); // 7777777 in octal
}
_header._devMinor = value;
}
}
/// <summary>
/// Represents the name of the group that owns this entry.
/// </summary>
/// <exception cref="ArgumentNullException">Cannot set a null group name.</exception>
/// <remarks><see cref="GroupName"/> is only used in Unix platforms.</remarks>
public string GroupName
{
get => _header._gName ?? string.Empty;
set
{
ArgumentNullException.ThrowIfNull(value);
_header._gName = value;
}
}
/// <summary>
/// Represents the name of the user that owns this entry.
/// </summary>
/// <remarks><see cref="UserName"/> is only used in Unix platforms.</remarks>
/// <exception cref="ArgumentNullException">Cannot set a null user name.</exception>
public string UserName
{
get => _header._uName ?? string.Empty;
set
{
ArgumentNullException.ThrowIfNull(value);
_header._uName = value;
}
}
}
}
|