Support ZIP Extra Data Fields (needs a lot of work)

This commit is contained in:
Michael Becker 2019-08-18 02:37:10 -04:00
parent 93284f71d6
commit 52cb8ad28e
5 changed files with 151 additions and 16 deletions

View File

@ -0,0 +1,61 @@
using System;
using UniversalEditor.Accessors;
namespace UniversalEditor.DataFormats.FileSystem.ZIP.ExtraDataFields
{
public class ZIPExtraDataFieldExtendedTimestamp : ZIPExtraDataField
{
public ZIPExtraDataFieldExtendedTimestamp (DateTime modificationTimestamp = default(DateTime), DateTime accessTimestamp = default (DateTime), DateTime creationTimestamp = default (DateTime))
{
base.Type = ZIPExtraDataFieldType.ExtendedTimestamp;
ModificationTimestamp = modificationTimestamp;
AccessTimestamp = accessTimestamp;
CreationTimestamp = creationTimestamp;
}
public DateTime ModificationTimestamp { get; set; } = DateTime.Now;
public DateTime AccessTimestamp { get; set; } = DateTime.Now;
public DateTime CreationTimestamp { get; set; } = DateTime.Now;
protected override byte [] GetLocalDataInternal ()
{
/*
* Local-header version:
Value Size Description
----- ---- -----------
(time) 0x5455 Short tag for this extra block type ("UT")
TSize Short total data size for this block
Flags Byte info bits
(ModTime) Long time of last modification (UTC/GMT)
(AcTime) Long time of last access (UTC/GMT)
(CrTime) Long time of original creation (UTC/GMT)
*/
MemoryAccessor ma = new MemoryAccessor ();
ma.Writer.WriteByte (7);
ma.Writer.WriteDOSFileTime (ModificationTimestamp);
ma.Writer.WriteDOSFileTime (AccessTimestamp);
ma.Writer.WriteDOSFileTime (CreationTimestamp);
return ma.ToArray ();
}
protected override byte[] GetCentralDataInternal ()
{
/*
* Central-header version:
Value Size Description
----- ---- -----------
(time) 0x5455 Short tag for this extra block type ("UT")
TSize Short total data size for this block
Flags Byte info bits (refers to local header!)
(ModTime) Long time of last modification (UTC/GMT)
*/
MemoryAccessor ma = new MemoryAccessor ();
ma.Writer.WriteByte (7);
ma.Writer.WriteDOSFileTime (ModificationTimestamp);
return ma.ToArray ();
}
}
}

View File

@ -11,6 +11,7 @@ using UniversalEditor.IO;
using UniversalEditor.UserInterface;
using UniversalEditor.ObjectModels.FileSystem.FileSources;
using UniversalEditor.DataFormats.FileSystem.ZIP.ExtraDataFields;
namespace UniversalEditor.DataFormats.FileSystem.ZIP
{
@ -395,11 +396,7 @@ namespace UniversalEditor.DataFormats.FileSystem.ZIP
}
bw.WriteInt16 (compressionMethod);
short iFileLastModificationTime = (short)(DateTime.Now.ToFileTime ());
bw.WriteInt16 (iFileLastModificationTime);
short iFileLastModificationDate = (short)(DateTime.Now.ToFileTime () >> 2);
bw.WriteInt16 (iFileLastModificationDate);
bw.WriteDOSFileTime (DateTime.Now);
bool isEncrypted = false;
byte [] uncompressedData = file.GetData ();
@ -412,10 +409,19 @@ namespace UniversalEditor.DataFormats.FileSystem.ZIP
short fileNameLength = (short)file.Name.Length;
byte [] extraField = new byte [0];
ZIPExtraDataField [] edfs = new ZIPExtraDataField []
{
new ZIPExtraDataFieldExtendedTimestamp(DateTime.Now, DateTime.Now, DateTime.Now)
};
short extraFieldLength = 0;
foreach (ZIPExtraDataField edf in edfs)
{
extraFieldLength += (short)(4 + edf.CentralData.Length);
}
bw.WriteInt16 (fileNameLength);
bw.WriteInt16 ((short)extraField.Length);
bw.WriteInt16 (extraFieldLength);
string fileComment = String.Empty;
@ -432,7 +438,12 @@ namespace UniversalEditor.DataFormats.FileSystem.ZIP
bw.WriteFixedLengthString (file.Name.Replace ("\\", "/"), fileNameLength);
bw.WriteBytes (extraField);
foreach (ZIPExtraDataField edf in edfs)
{
bw.WriteInt16 (edf.TypeCode);
bw.WriteInt16 ((short) edf.CentralData.Length);
bw.WriteBytes (edf.CentralData);
}
bw.WriteFixedLengthString (fileComment);
}
@ -467,7 +478,7 @@ namespace UniversalEditor.DataFormats.FileSystem.ZIP
}
bw.WriteInt16 ((short)compressionMethod);
WriteDate (bw, DateTime.Now);
bw.WriteDOSFileTime (DateTime.Now);
bool isEncrypted = false;
@ -494,20 +505,28 @@ namespace UniversalEditor.DataFormats.FileSystem.ZIP
bw.WriteInt32 (0);
}
ZIPExtraDataField [] edfs = new ZIPExtraDataField []
{
new ZIPExtraDataFieldExtendedTimestamp(DateTime.Now, DateTime.Now, DateTime.Now)
};
short fileNameLength = (short)item.Name.Length;
short extraFieldLength = 0;
foreach (ZIPExtraDataField edf in edfs)
{
extraFieldLength += (short)(4 + edf.LocalData.Length);
}
bw.WriteInt16 (fileNameLength);
bw.WriteInt16 (extraFieldLength);
bw.WriteFixedLengthString (item.Name, fileNameLength);
/*
long pos = br.Accessor.Position;
while (br.Accessor.Position < (pos + extraFieldLength))
foreach (ZIPExtraDataField edf in edfs)
{
short chunkIDCode = br.ReadInt16();
short chunkLength = br.ReadInt16();
byte[] data = br.ReadBytes(chunkLength);
bw.WriteInt16 (edf.TypeCode);
bw.WriteInt16 ((short) edf.LocalData.Length);
bw.WriteBytes (edf.LocalData);
}
*/
if (item is File)
{

View File

@ -0,0 +1,43 @@
using System;
namespace UniversalEditor.DataFormats.FileSystem.ZIP
{
public class ZIPExtraDataField
{
public class ZIPExtraDataFieldCollection
: System.Collections.ObjectModel.Collection<ZIPExtraDataField>
{
}
public byte [] LocalData {
get { return GetLocalDataInternal (); }
set { SetLocalDataInternal (value); }
}
public byte [] CentralData {
get { return GetCentralDataInternal (); }
set { SetCentralDataInternal (value); }
}
private byte [] _LocalData = new byte [0];
protected virtual byte [] GetLocalDataInternal ()
{
return _LocalData;
}
protected virtual void SetLocalDataInternal (byte[] value)
{
_LocalData = value;
}
private byte [] _CentralData = new byte [0];
protected virtual byte [] GetCentralDataInternal ()
{
return _CentralData;
}
protected virtual void SetCentralDataInternal (byte [] value)
{
_CentralData = value;
}
public short TypeCode { get; set; }
public ZIPExtraDataFieldType Type { get { return (ZIPExtraDataFieldType)TypeCode; } set { TypeCode = (short)value; } }
}
}

View File

@ -0,0 +1,8 @@
using System;
namespace UniversalEditor.DataFormats.FileSystem.ZIP
{
public enum ZIPExtraDataFieldType : short
{
ExtendedTimestamp = 0x5455
}
}

View File

@ -215,6 +215,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataFormats\FileSystem\VirtualBox\VDIDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\ZIP\ZIPCompressionMethod.cs" />
<Compile Include="DataFormats\FileSystem\ZIP\ZIPExtraDataField.cs" />
<Compile Include="DataFormats\FileSystem\ZIP\ExtraDataFields\ZIPExtraDataFieldExtendedTimestamp.cs" />
<Compile Include="DataFormats\FileSystem\ZIP\ZIPExtraDataFieldType.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
@ -241,6 +244,7 @@
<ItemGroup>
<Folder Include="DataFormats\FileSystem\Box\Internal\" />
<Folder Include="DataFormats\FileSystem\VirtualBox\" />
<Folder Include="DataFormats\FileSystem\ZIP\ExtraDataFields\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.