using System;
using System.IO;
namespace Packaging.Targets.IO
{
///
/// Represents a Tar archive.
///
public class TarFile : ArchiveFile
{
private TarHeader entryHeader;
///
/// Initializes a new instance of the class.
///
///
/// A which represents the tar file.
///
///
/// to leave the underlying open when this
/// is disposed of; otherwise, .
///
public TarFile(Stream stream, bool leaveOpen)
: base(stream, leaveOpen)
{
}
///
/// Gets the link target of this file.
///
public string LinkName
{
get;
private set;
}
///
public override bool Read()
{
this.Align(512);
this.EntryStream?.Dispose();
this.EntryStream = null;
this.entryHeader = this.Stream.ReadStruct();
this.FileHeader = this.entryHeader;
this.FileName = this.entryHeader.FileName;
this.LinkName = this.entryHeader.LinkName;
// There are two empty blocks at the end of the file.
if (string.IsNullOrEmpty(this.entryHeader.Magic))
{
return false;
}
if (this.entryHeader.Magic != "ustar")
{
throw new InvalidDataException("The magic for the file entry is invalid");
}
this.Align(512);
// TODO: Validate Checksum
this.EntryStream = new SubStream(this.Stream, this.Stream.Position, this.entryHeader.FileSize, leaveParentOpen: true);
if (this.entryHeader.TypeFlag == TarTypeFlag.LongName)
{
var longFileName = this.ReadAsUtf8String();
var read = this.Read();
this.FileName = longFileName;
return read;
}
else if (this.entryHeader.TypeFlag == TarTypeFlag.LongLink)
{
var longLinkName = this.ReadAsUtf8String();
var read = this.Read();
this.LinkName = longLinkName;
return read;
}
else
{
return true;
}
}
}
}