Skip to content

Commit

Permalink
Remove code duplication in TarHeader class (dotnet#72501)
Browse files Browse the repository at this point in the history
* Missing ConfigureAwait(false) in await using.

* Remove argument from TarSizeFieldNegative exception resource string.

* TarHeader.TryGetNextHeaderAsync: Reduce duplication.

* TarHeader.ReadExtendedAttributesBlockAsync: reduce duplication.

* TarHeader.ReadGnuLongPathDataBlockAsync: reduce duplication.

* TarHeader.ReadExtendedAttributesFromBuffer: reduce duplication.

* TarHeader.WriteAsV7Async: Reduce duplication.

* TarHeader.WriteAsUstarAsync: reduce duplication.

* TarHeader.*Pax*Async: reduce duplication.

* TarHeader.WriteAsGnuAsync: reduce duplication.

* Use pretty switch for async writing. Move the sync version to its own method, to keep similar logic close by.

* checksum => tmpChecksum for consistency with other similar methods.

* Add ExtendedAttributes non-nullable property that initializes private nullable property if needed.

* Remove unnecessary buffer cleaning call.

Co-authored-by: carlossanlop <carlossanlop@users.noreply.github.com>
  • Loading branch information
carlossanlop and carlossanlop committed Jul 21, 2022
1 parent b5904da commit f379bfb
Show file tree
Hide file tree
Showing 10 changed files with 362 additions and 445 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
<value>A POSIX format was expected (Ustar or PAX), but could not be reliably determined for entry '{0}'.</value>
</data>
<data name="TarSizeFieldNegative" xml:space="preserve">
<value>The size field is negative in the tar entry '{0}'.</value>
<value>The size field is negative in a tar entry.</value>
</data>
<data name="TarSizeFieldTooLargeForEntryType" xml:space="preserve">
<value>The value of the size field for the current entry of type '{0}' is beyond the expected length.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ public GnuTarEntry(TarEntry other)

if (other is PaxTarEntry paxOther)
{
changedATime = TarHelpers.TryGetDateTimeOffsetFromTimestampString(paxOther._header._extendedAttributes, TarHeader.PaxEaATime, out DateTimeOffset aTime);
changedATime = TarHelpers.TryGetDateTimeOffsetFromTimestampString(paxOther._header.ExtendedAttributes, TarHeader.PaxEaATime, out DateTimeOffset aTime);
if (changedATime)
{
_header._aTime = aTime;
}

changedCTime = TarHelpers.TryGetDateTimeOffsetFromTimestampString(paxOther._header._extendedAttributes, TarHeader.PaxEaCTime, out DateTimeOffset cTime);
changedCTime = TarHelpers.TryGetDateTimeOffsetFromTimestampString(paxOther._header.ExtendedAttributes, TarHeader.PaxEaCTime, out DateTimeOffset cTime);
if (changedCTime)
{
_header._cTime = cTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,13 @@ public PaxGlobalExtendedAttributesTarEntry(IEnumerable<KeyValuePair<string, stri
: base(TarEntryType.GlobalExtendedAttributes, TarHeader.GlobalHeadFormatPrefix, TarEntryFormat.Pax, isGea: true)
{
ArgumentNullException.ThrowIfNull(globalExtendedAttributes);
_header._extendedAttributes = new Dictionary<string, string>(globalExtendedAttributes);
_header.InitializeExtendedAttributesWithExisting(globalExtendedAttributes);
}

/// <summary>
/// Returns the global extended attributes stored in this entry.
/// </summary>
public IReadOnlyDictionary<string, string> GlobalExtendedAttributes
{
get
{
_header._extendedAttributes ??= new Dictionary<string, string>();
return _readOnlyGlobalExtendedAttributes ??= _header._extendedAttributes.AsReadOnly();
}
}
public IReadOnlyDictionary<string, string> GlobalExtendedAttributes => _readOnlyGlobalExtendedAttributes ??= _header.ExtendedAttributes.AsReadOnly();

// Determines if the current instance's entry type supports setting a data stream.
internal override bool IsDataStreamSetterSupported() => false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public PaxTarEntry(TarEntryType entryType, string entryName)
: base(entryType, entryName, TarEntryFormat.Pax, isGea: false)
{
_header._prefix = string.Empty;
_header._extendedAttributes = new Dictionary<string, string>();

Debug.Assert(_header._mTime != default);
AddNewAccessAndChangeTimestampsIfNotExist(useMTime: true);
Expand Down Expand Up @@ -92,7 +91,7 @@ public PaxTarEntry(TarEntryType entryType, string entryName, IEnumerable<KeyValu
ArgumentNullException.ThrowIfNull(extendedAttributes);

_header._prefix = string.Empty;
_header._extendedAttributes = new Dictionary<string, string>(extendedAttributes);
_header.InitializeExtendedAttributesWithExisting(extendedAttributes);

Debug.Assert(_header._mTime != default);
AddNewAccessAndChangeTimestampsIfNotExist(useMTime: true);
Expand All @@ -111,15 +110,14 @@ public PaxTarEntry(TarEntry other)

if (other is PaxTarEntry paxOther)
{
_header._extendedAttributes = new Dictionary<string, string>(paxOther.ExtendedAttributes);
_header.InitializeExtendedAttributesWithExisting(paxOther.ExtendedAttributes);
}
else
{
_header._extendedAttributes = new Dictionary<string, string>();
if (other is GnuTarEntry gnuOther)
{
_header._extendedAttributes[TarHeader.PaxEaATime] = TarHelpers.GetTimestampStringFromDateTimeOffset(gnuOther.AccessTime);
_header._extendedAttributes[TarHeader.PaxEaCTime] = TarHelpers.GetTimestampStringFromDateTimeOffset(gnuOther.ChangeTime);
_header.ExtendedAttributes[TarHeader.PaxEaATime] = TarHelpers.GetTimestampStringFromDateTimeOffset(gnuOther.AccessTime);
_header.ExtendedAttributes[TarHeader.PaxEaCTime] = TarHelpers.GetTimestampStringFromDateTimeOffset(gnuOther.ChangeTime);
}
}

Expand All @@ -144,14 +142,7 @@ public PaxTarEntry(TarEntry other)
/// <item>File length, under the name <c>size</c>, as an <see cref="int"/>, if the string representation of the number is larger than 12 bytes.</item>
/// </list>
/// </remarks>
public IReadOnlyDictionary<string, string> ExtendedAttributes
{
get
{
_header._extendedAttributes ??= new Dictionary<string, string>();
return _readOnlyExtendedAttributes ??= _header._extendedAttributes.AsReadOnly();
}
}
public IReadOnlyDictionary<string, string> ExtendedAttributes => _readOnlyExtendedAttributes ??= _header.ExtendedAttributes.AsReadOnly();

// Determines if the current instance's entry type supports setting a data stream.
internal override bool IsDataStreamSetterSupported() => EntryType == TarEntryType.RegularFile;
Expand All @@ -162,22 +153,21 @@ public IReadOnlyDictionary<string, string> ExtendedAttributes
private void AddNewAccessAndChangeTimestampsIfNotExist(bool useMTime)
{
Debug.Assert(!useMTime || (useMTime && _header._mTime != default));
Debug.Assert(_header._extendedAttributes != null);
bool containsATime = _header._extendedAttributes.ContainsKey(TarHeader.PaxEaATime);
bool containsCTime = _header._extendedAttributes.ContainsKey(TarHeader.PaxEaCTime);
bool containsATime = _header.ExtendedAttributes.ContainsKey(TarHeader.PaxEaATime);
bool containsCTime = _header.ExtendedAttributes.ContainsKey(TarHeader.PaxEaCTime);

if (!containsATime || !containsCTime)
{
string secondsFromEpochString = TarHelpers.GetTimestampStringFromDateTimeOffset(useMTime ? _header._mTime : DateTimeOffset.UtcNow);

if (!containsATime)
{
_header._extendedAttributes[TarHeader.PaxEaATime] = secondsFromEpochString;
_header.ExtendedAttributes[TarHeader.PaxEaATime] = secondsFromEpochString;
}

if (!containsCTime)
{
_header._extendedAttributes[TarHeader.PaxEaCTime] = secondsFromEpochString;
_header.ExtendedAttributes[TarHeader.PaxEaCTime] = secondsFromEpochString;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ private async Task ExtractAsRegularFileAsync(string destinationFileName, Cancell

// Rely on FileStream's ctor for further checking destinationFileName parameter
FileStream fs = new FileStream(destinationFileName, CreateFileStreamOptions(isAsync: true));
await using (fs)
await using (fs.ConfigureAwait(false))
{
if (DataStream != null)
{
Expand Down
Loading

0 comments on commit f379bfb

Please sign in to comment.