Fixed bug in TAR data format where the first four bytes of filename of first file got eaten
This commit is contained in:
parent
dafb4c6372
commit
0b1cb3fa30
@ -18,228 +18,227 @@ namespace UniversalEditor.DataFormats.FileSystem.TapeArchive
|
||||
_dfr = base.MakeReference();
|
||||
_dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
|
||||
_dfr.Filters.Add("Tape archive", new string[] { "*.tar", "*.tar.gz", "*.tgz", "*.tar.bz2", "*.tbz2", "*.tb2", "*.taz", "*.tar.z", "*.tlz", "*.tar.lz", "*.txz", "*.tar.xz" });
|
||||
_dfr.ExportOptions.Add(new CustomOptionBoolean("IsUnixStandardTAR", "Create a UNIX standard tape archive (ustar)", true));
|
||||
_dfr.ExportOptions.Add(new CustomOptionBoolean("IsUnixStandardTAR", "Create a UNIX standard tape archive (ustar)", true));
|
||||
}
|
||||
return _dfr;
|
||||
}
|
||||
|
||||
private bool mvarIsUnixStandardTAR = true;
|
||||
public bool IsUnixStandardTAR { get { return mvarIsUnixStandardTAR; } set { mvarIsUnixStandardTAR = value; } }
|
||||
private bool mvarIsUnixStandardTAR = true;
|
||||
public bool IsUnixStandardTAR { get { return mvarIsUnixStandardTAR; } set { mvarIsUnixStandardTAR = value; } }
|
||||
|
||||
protected override void LoadInternal(ref ObjectModel objectModel)
|
||||
{
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
if (fsom == null) throw new ObjectModelNotSupportedException();
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
if (fsom == null) throw new ObjectModelNotSupportedException();
|
||||
|
||||
IO.Reader br = base.Accessor.Reader;
|
||||
byte[] gzhead = br.ReadBytes(4);
|
||||
if (gzhead.Match(new byte[] { 31, 139, 8, 0 }))
|
||||
{
|
||||
br.Accessor.Position -= 4;
|
||||
byte[] data = br.ReadToEnd();
|
||||
data = CompressionModules.Gzip.Decompress(data);
|
||||
br = new IO.Reader(new MemoryAccessor(data));
|
||||
}
|
||||
IO.Reader br = base.Accessor.Reader;
|
||||
byte[] gzhead = br.PeekBytes(4);
|
||||
if (gzhead.Match(new byte[] { 31, 139, 8, 0 }))
|
||||
{
|
||||
byte[] data = br.ReadToEnd();
|
||||
data = CompressionModules.Gzip.Decompress(data);
|
||||
br = new IO.Reader(new MemoryAccessor(data));
|
||||
}
|
||||
|
||||
bool ustar_set = false;
|
||||
while (!br.EndOfStream)
|
||||
{
|
||||
if (br.Remaining < 263) break;
|
||||
bool ustar_set = false;
|
||||
while (!br.EndOfStream)
|
||||
{
|
||||
if (br.Remaining < 263) break;
|
||||
|
||||
string fileName = br.ReadFixedLengthString(100).TrimNull();
|
||||
if (fileName == String.Empty) break;
|
||||
string fileName = br.ReadFixedLengthString(100).TrimNull();
|
||||
if (fileName == String.Empty) break;
|
||||
|
||||
string fileMode = br.ReadFixedLengthString(8).TrimNull();
|
||||
string owner = br.ReadFixedLengthString(8).TrimNull();
|
||||
string group = br.ReadFixedLengthString(8).TrimNull();
|
||||
string fileSizeInBytesOctal = br.ReadFixedLengthString(12).TrimNull();
|
||||
string lastModificationTimeUnixOctal = br.ReadFixedLengthString(12).TrimNull();
|
||||
string headerChecksum = br.ReadFixedLengthString(8).TrimNull();
|
||||
|
||||
char c = br.ReadChar();
|
||||
TapeArchiveRecordType type = (TapeArchiveRecordType)((int)c);
|
||||
string fileMode = br.ReadFixedLengthString(8).TrimNull();
|
||||
string owner = br.ReadFixedLengthString(8).TrimNull();
|
||||
string group = br.ReadFixedLengthString(8).TrimNull();
|
||||
string fileSizeInBytesOctal = br.ReadFixedLengthString(12).TrimNull();
|
||||
string lastModificationTimeUnixOctal = br.ReadFixedLengthString(12).TrimNull();
|
||||
string headerChecksum = br.ReadFixedLengthString(8).TrimNull();
|
||||
|
||||
char c = br.ReadChar();
|
||||
TapeArchiveRecordType type = (TapeArchiveRecordType)((int)c);
|
||||
|
||||
string linkedFileName = br.ReadFixedLengthString(100).TrimNull();
|
||||
string linkedFileName = br.ReadFixedLengthString(100).TrimNull();
|
||||
|
||||
string ustar = br.ReadFixedLengthString(6);
|
||||
if (ustar == "ustar ")
|
||||
{
|
||||
if (!ustar_set)
|
||||
{
|
||||
mvarIsUnixStandardTAR = true;
|
||||
ustar_set = true;
|
||||
}
|
||||
string ustarVersion = br.ReadFixedLengthString(2).TrimNull();
|
||||
string ownerName = br.ReadFixedLengthString(32).TrimNull();
|
||||
string groupName = br.ReadFixedLengthString(32).TrimNull();
|
||||
string deviceMajor = br.ReadFixedLengthString(8).TrimNull();
|
||||
string deviceMinor = br.ReadFixedLengthString(8).TrimNull();
|
||||
string filenamePrefix = br.ReadFixedLengthString(155).TrimNull();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ustar_set)
|
||||
{
|
||||
mvarIsUnixStandardTAR = false;
|
||||
ustar_set = true;
|
||||
}
|
||||
br.Accessor.Position -= 6;
|
||||
}
|
||||
br.Align(512);
|
||||
string ustar = br.ReadFixedLengthString(6);
|
||||
if (ustar == "ustar ")
|
||||
{
|
||||
if (!ustar_set)
|
||||
{
|
||||
mvarIsUnixStandardTAR = true;
|
||||
ustar_set = true;
|
||||
}
|
||||
string ustarVersion = br.ReadFixedLengthString(2).TrimNull();
|
||||
string ownerName = br.ReadFixedLengthString(32).TrimNull();
|
||||
string groupName = br.ReadFixedLengthString(32).TrimNull();
|
||||
string deviceMajor = br.ReadFixedLengthString(8).TrimNull();
|
||||
string deviceMinor = br.ReadFixedLengthString(8).TrimNull();
|
||||
string filenamePrefix = br.ReadFixedLengthString(155).TrimNull();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ustar_set)
|
||||
{
|
||||
mvarIsUnixStandardTAR = false;
|
||||
ustar_set = true;
|
||||
}
|
||||
br.Accessor.Position -= 6;
|
||||
}
|
||||
br.Align(512);
|
||||
|
||||
if (fileName.EndsWith("/"))
|
||||
{
|
||||
fileName = fileName.Substring(0, fileName.Length - 1);
|
||||
Folder folder = fsom.AddFolder(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = fsom.AddFile(fileName);
|
||||
if (fileName.EndsWith("/"))
|
||||
{
|
||||
fileName = fileName.Substring(0, fileName.Length - 1);
|
||||
Folder folder = fsom.AddFolder(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = fsom.AddFile(fileName);
|
||||
|
||||
long fileSize = Convert.ToInt64(fileSizeInBytesOctal, 8);
|
||||
long fileOffset = (long)br.Accessor.Position;
|
||||
file.Properties.Add("reader", br);
|
||||
file.Properties.Add("offset", fileOffset);
|
||||
file.Properties.Add("length", fileSize);
|
||||
file.Size = fileSize;
|
||||
file.DataRequest += file_DataRequest;
|
||||
long fileSize = Convert.ToInt64(fileSizeInBytesOctal, 8);
|
||||
long fileOffset = (long)br.Accessor.Position;
|
||||
file.Properties.Add("reader", br);
|
||||
file.Properties.Add("offset", fileOffset);
|
||||
file.Properties.Add("length", fileSize);
|
||||
file.Size = fileSize;
|
||||
file.DataRequest += file_DataRequest;
|
||||
|
||||
br.Accessor.Position += fileSize;
|
||||
br.Align(512);
|
||||
}
|
||||
}
|
||||
br.Accessor.Position += fileSize;
|
||||
br.Align(512);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void file_DataRequest(object sender, DataRequestEventArgs e)
|
||||
{
|
||||
File file = (sender as File);
|
||||
IO.Reader br = (IO.Reader)file.Properties["reader"];
|
||||
long offset = (long)file.Properties["offset"];
|
||||
long length = (long)file.Properties["length"];
|
||||
br.Accessor.Position = offset;
|
||||
e.Data = br.ReadBytes(length);
|
||||
}
|
||||
private void file_DataRequest(object sender, DataRequestEventArgs e)
|
||||
{
|
||||
File file = (sender as File);
|
||||
IO.Reader br = (IO.Reader)file.Properties["reader"];
|
||||
long offset = (long)file.Properties["offset"];
|
||||
long length = (long)file.Properties["length"];
|
||||
br.Accessor.Position = offset;
|
||||
e.Data = br.ReadBytes(length);
|
||||
}
|
||||
|
||||
private long OctalToBase10(long octal)
|
||||
{
|
||||
long value = 0;
|
||||
while (octal > 0)
|
||||
{
|
||||
value += (octal % 8);
|
||||
octal /= 8;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
private long OctalToBase10(long octal)
|
||||
{
|
||||
long value = 0;
|
||||
while (octal > 0)
|
||||
{
|
||||
value += (octal % 8);
|
||||
octal /= 8;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected override void SaveInternal(ObjectModel objectModel)
|
||||
{
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
if (fsom == null) throw new ObjectModelNotSupportedException();
|
||||
{
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
if (fsom == null) throw new ObjectModelNotSupportedException();
|
||||
|
||||
IO.Writer bw = base.Accessor.Writer;
|
||||
foreach (Folder folder in fsom.Folders)
|
||||
{
|
||||
RecursiveWriteFolder(bw, folder);
|
||||
}
|
||||
foreach (File file in fsom.Files)
|
||||
{
|
||||
RecursiveWriteFile(bw, file, String.Empty);
|
||||
}
|
||||
}
|
||||
IO.Writer bw = base.Accessor.Writer;
|
||||
foreach (Folder folder in fsom.Folders)
|
||||
{
|
||||
RecursiveWriteFolder(bw, folder);
|
||||
}
|
||||
foreach (File file in fsom.Files)
|
||||
{
|
||||
RecursiveWriteFile(bw, file, String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void RecursiveWriteFolder(IO.Writer bw, Folder folder)
|
||||
{
|
||||
bw.WriteFixedLengthString(folder.Name + "/", 100);
|
||||
private void RecursiveWriteFolder(IO.Writer bw, Folder folder)
|
||||
{
|
||||
bw.WriteFixedLengthString(folder.Name + "/", 100);
|
||||
|
||||
string fileMode = " \0";
|
||||
bw.WriteFixedLengthString(fileMode, 8);
|
||||
string owner = " \0";
|
||||
bw.WriteFixedLengthString(owner, 8);
|
||||
string group = " \0";
|
||||
bw.WriteFixedLengthString(group, 8);
|
||||
string fileSizeInBytesOctal = " \0";
|
||||
bw.WriteFixedLengthString(fileSizeInBytesOctal, 12);
|
||||
string lastModificationTimeUnixOctal = " \0";
|
||||
bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12);
|
||||
string headerChecksum = " \0";
|
||||
bw.WriteFixedLengthString(headerChecksum, 12);
|
||||
string fileMode = " \0";
|
||||
bw.WriteFixedLengthString(fileMode, 8);
|
||||
string owner = " \0";
|
||||
bw.WriteFixedLengthString(owner, 8);
|
||||
string group = " \0";
|
||||
bw.WriteFixedLengthString(group, 8);
|
||||
string fileSizeInBytesOctal = " \0";
|
||||
bw.WriteFixedLengthString(fileSizeInBytesOctal, 12);
|
||||
string lastModificationTimeUnixOctal = " \0";
|
||||
bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12);
|
||||
string headerChecksum = " \0";
|
||||
bw.WriteFixedLengthString(headerChecksum, 12);
|
||||
|
||||
char c = (char)(int)TapeArchiveRecordType.Directory;
|
||||
char c = (char)(int)TapeArchiveRecordType.Directory;
|
||||
|
||||
string linkedFileName = String.Empty;
|
||||
bw.WriteFixedLengthString(linkedFileName, 100);
|
||||
string linkedFileName = String.Empty;
|
||||
bw.WriteFixedLengthString(linkedFileName, 100);
|
||||
|
||||
if (mvarIsUnixStandardTAR)
|
||||
{
|
||||
bw.WriteFixedLengthString("ustar ", 6);
|
||||
if (mvarIsUnixStandardTAR)
|
||||
{
|
||||
bw.WriteFixedLengthString("ustar ", 6);
|
||||
|
||||
string ustarVersion = String.Empty;
|
||||
bw.WriteFixedLengthString(ustarVersion, 2);
|
||||
string ownerName = String.Empty;
|
||||
bw.WriteFixedLengthString(ownerName, 32);
|
||||
string groupName = String.Empty;
|
||||
bw.WriteFixedLengthString(groupName, 32);
|
||||
string deviceMajor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMajor, 8);
|
||||
string deviceMinor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMinor, 8);
|
||||
string filenamePrefix = String.Empty;
|
||||
bw.WriteFixedLengthString(filenamePrefix, 155);
|
||||
}
|
||||
bw.Align(512);
|
||||
string ustarVersion = String.Empty;
|
||||
bw.WriteFixedLengthString(ustarVersion, 2);
|
||||
string ownerName = String.Empty;
|
||||
bw.WriteFixedLengthString(ownerName, 32);
|
||||
string groupName = String.Empty;
|
||||
bw.WriteFixedLengthString(groupName, 32);
|
||||
string deviceMajor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMajor, 8);
|
||||
string deviceMinor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMinor, 8);
|
||||
string filenamePrefix = String.Empty;
|
||||
bw.WriteFixedLengthString(filenamePrefix, 155);
|
||||
}
|
||||
bw.Align(512);
|
||||
|
||||
foreach (Folder folder1 in folder.Folders)
|
||||
{
|
||||
RecursiveWriteFolder(bw, folder1);
|
||||
}
|
||||
foreach (File file1 in folder.Files)
|
||||
{
|
||||
RecursiveWriteFile(bw, file1, folder.Name + "/");
|
||||
}
|
||||
}
|
||||
private void RecursiveWriteFile(IO.Writer bw, File file, string parentPath)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(parentPath)) parentPath = parentPath + "/";
|
||||
parentPath = parentPath + file.Name;
|
||||
foreach (Folder folder1 in folder.Folders)
|
||||
{
|
||||
RecursiveWriteFolder(bw, folder1);
|
||||
}
|
||||
foreach (File file1 in folder.Files)
|
||||
{
|
||||
RecursiveWriteFile(bw, file1, folder.Name + "/");
|
||||
}
|
||||
}
|
||||
private void RecursiveWriteFile(IO.Writer bw, File file, string parentPath)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(parentPath)) parentPath = parentPath + "/";
|
||||
parentPath = parentPath + file.Name;
|
||||
|
||||
bw.WriteFixedLengthString(parentPath, 100);
|
||||
bw.WriteFixedLengthString(parentPath, 100);
|
||||
|
||||
string fileMode = " \0";
|
||||
bw.WriteFixedLengthString(fileMode, 8);
|
||||
string owner = " \0";
|
||||
bw.WriteFixedLengthString(owner, 8);
|
||||
string group = " \0";
|
||||
bw.WriteFixedLengthString(group, 8);
|
||||
string fileSizeInBytesOctal = Convert.ToString(file.Size, 8).PadLeft(11, ' ') + "\0";
|
||||
bw.WriteFixedLengthString(fileSizeInBytesOctal, 12);
|
||||
string lastModificationTimeUnixOctal = " \0";
|
||||
bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12);
|
||||
string headerChecksum = " \0";
|
||||
bw.WriteFixedLengthString(headerChecksum, 12);
|
||||
string fileMode = " \0";
|
||||
bw.WriteFixedLengthString(fileMode, 8);
|
||||
string owner = " \0";
|
||||
bw.WriteFixedLengthString(owner, 8);
|
||||
string group = " \0";
|
||||
bw.WriteFixedLengthString(group, 8);
|
||||
string fileSizeInBytesOctal = Convert.ToString(file.Size, 8).PadLeft(11, ' ') + "\0";
|
||||
bw.WriteFixedLengthString(fileSizeInBytesOctal, 12);
|
||||
string lastModificationTimeUnixOctal = " \0";
|
||||
bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12);
|
||||
string headerChecksum = " \0";
|
||||
bw.WriteFixedLengthString(headerChecksum, 12);
|
||||
|
||||
char c = (char)(int)TapeArchiveRecordType.Directory;
|
||||
char c = (char)(int)TapeArchiveRecordType.Directory;
|
||||
|
||||
string linkedFileName = String.Empty;
|
||||
bw.WriteFixedLengthString(linkedFileName, 100);
|
||||
string linkedFileName = String.Empty;
|
||||
bw.WriteFixedLengthString(linkedFileName, 100);
|
||||
|
||||
if (mvarIsUnixStandardTAR)
|
||||
{
|
||||
bw.WriteFixedLengthString("ustar ", 6);
|
||||
if (mvarIsUnixStandardTAR)
|
||||
{
|
||||
bw.WriteFixedLengthString("ustar ", 6);
|
||||
|
||||
string ustarVersion = String.Empty;
|
||||
bw.WriteFixedLengthString(ustarVersion, 2);
|
||||
string ownerName = String.Empty;
|
||||
bw.WriteFixedLengthString(ownerName, 32);
|
||||
string groupName = String.Empty;
|
||||
bw.WriteFixedLengthString(groupName, 32);
|
||||
string deviceMajor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMajor, 8);
|
||||
string deviceMinor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMinor, 8);
|
||||
string filenamePrefix = String.Empty;
|
||||
bw.WriteFixedLengthString(filenamePrefix, 155);
|
||||
}
|
||||
bw.Align(512);
|
||||
}
|
||||
string ustarVersion = String.Empty;
|
||||
bw.WriteFixedLengthString(ustarVersion, 2);
|
||||
string ownerName = String.Empty;
|
||||
bw.WriteFixedLengthString(ownerName, 32);
|
||||
string groupName = String.Empty;
|
||||
bw.WriteFixedLengthString(groupName, 32);
|
||||
string deviceMajor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMajor, 8);
|
||||
string deviceMinor = String.Empty;
|
||||
bw.WriteFixedLengthString(deviceMinor, 8);
|
||||
string filenamePrefix = String.Empty;
|
||||
bw.WriteFixedLengthString(filenamePrefix, 155);
|
||||
}
|
||||
bw.Align(512);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user