14 Commits

Author SHA1 Message Date
Matt Nadareski
5565fa2fc3 Bump version 2024-10-31 11:08:14 -04:00
Matt Nadareski
e088e203ea Tags are tags, use them 2024-10-31 00:26:46 -04:00
Matt Nadareski
acc8d95930 Correctly redefine const as enum 2024-10-31 00:15:43 -04:00
Matt Nadareski
1a76c59827 Port significantly more CHD info 2024-10-31 00:05:19 -04:00
Matt Nadareski
8725ec0337 Port more CHD info from SabreTools 2024-10-19 23:58:56 -04:00
Matt Nadareski
8991cc460d Correct info for IS-CAB components 2024-10-03 02:49:47 -04:00
Matt Nadareski
98ce8b65ec Correct info for IS-CAB file groups 2024-10-03 02:35:15 -04:00
Matt Nadareski
ca58343c30 Bump version 2024-10-01 12:32:33 -04:00
Matt Nadareski
2f637e0012 Remove ValueTuple requirement 2024-10-01 01:41:43 -04:00
Matt Nadareski
80172942fd Mark extended TAR header info 2024-09-26 14:08:55 -04:00
Matt Nadareski
aa0960b42f Separate entry from archive in TAR 2024-09-26 13:45:49 -04:00
Matt Nadareski
2554f64277 Add layout for TAR header 2024-09-26 12:15:59 -04:00
Matt Nadareski
4c5c960915 Slight tweak to TAR header (nw) 2024-09-26 12:03:20 -04:00
Matt Nadareski
1cb49163dd Upate MinValueTupleBridge to 0.2.1 2024-09-25 10:46:16 -04:00
15 changed files with 617 additions and 117 deletions

View File

@@ -0,0 +1,23 @@
namespace SabreTools.Models.CHD
{
public static class Constants
{
public const string SignatureString = "MComprHD";
#region Header Sizes
public const int HeaderV1Size = 76;
public const int HeaderV2Size = 80;
public const int HeaderV3Size = 120;
public const int HeaderV4Size = 108;
public const int HeaderV5Size = 124;
#endregion
#region Metadata Parameters
public const uint CHDMETAINDEX_APPEND = uint.MaxValue;
#endregion
}
}

View File

@@ -2,6 +2,79 @@ using System;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chdcodec.h"/>
public enum AVHuffCodec
{
DECOMPRESS_CONFIG = 1,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chdcodec.h"/>
public enum CodecType : uint
{
CHD_CODEC_NONE = 0,
#region General Codecs
/// <remarks>"zlib"</remarks>
ZLIB = 0x7a6c6962,
/// <remarks>"zstd"</remarks>
ZSTD = 0x7a737464,
/// <remarks>"lzma"</remarks>
LZMA = 0x6c7a6d61,
/// <remarks>"huff"</remarks>
HUFFMAN = 0x68756666,
/// <remarks>"flac"</remarks>
FLAC = 0x666c6163,
#endregion
#region General Codecs with CD Frontend
/// <remarks>"cdzl"</remarks>
CD_ZLIB = 0x63647a6c,
/// <remarks>"cdzs"</remarks>
CD_ZSTD = 0x63647a73,
/// <remarks>"cdlz"</remarks>
CD_LZMA = 0x63646c7a,
/// <remarks>"cdfl"</remarks>
CD_FLAC = 0x6364666c,
#endregion
#region A/V Codecs
/// <remarks>"avhu"</remarks>
AVHUFF = 0x61766875,
#endregion
#region Pseudo-Codecs Returned by hunk_info
/// <summary>
/// Copy of another hunk
/// </summary>
CHD_CODEC_SELF = 1,
/// <summary>
/// Copy of a parent's hunk
/// </summary>
CHD_CODEC_PARENT = 2,
/// <summary>
/// Legacy "mini" 8-byte repeat
/// </summary>
CHD_CODEC_MINI = 3,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum CompressionType : uint
{
@@ -25,6 +98,35 @@ namespace SabreTools.Models.CHD
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum Error : uint
{
NO_INTERFACE = 1,
NOT_OPEN,
ALREADY_OPEN,
INVALID_FILE,
INVALID_DATA,
REQUIRES_PARENT,
FILE_NOT_WRITEABLE,
CODEC_ERROR,
INVALID_PARENT,
HUNK_OUT_OF_RANGE,
DECOMPRESSION_ERROR,
COMPRESSION_ERROR,
CANT_VERIFY,
METADATA_NOT_FOUND,
INVALID_METADATA_SIZE,
UNSUPPORTED_VERSION,
VERIFY_INCOMPLETE,
INVALID_METADATA,
INVALID_STATE,
OPERATION_PENDING,
UNSUPPORTED_FORMAT,
UNKNOWN_COMPRESSION,
WALKING_PARENT,
COMPRESSING
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[Flags]
public enum Flags : uint
@@ -39,4 +141,218 @@ namespace SabreTools.Models.CHD
/// </summary>
DriveAllowsWrites = 0x00000002,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[Flags]
public enum MetadataFlags : byte
{
/// <summary>
/// Indicates data is checksummed
/// </summary>
CHD_MDFLAGS_CHECKSUM = 0x01,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum MetadataTag : uint
{
CHDMETATAG_WILDCARD = 0,
#region Hard Disk
/// <summary>
/// Standard hard disk metadata
/// </summary>
/// <remarks>"GDDD"</remarks>
HARD_DISK_METADATA_TAG = 0x47444444,
/// <summary>
/// Hard disk identify information
/// </summary>
/// <remarks>"IDNT"</remarks>
HARD_DISK_IDENT_METADATA_TAG = 0x49444e54,
/// <summary>
/// Hard disk key information
/// </summary>
/// <remarks>"KEY "</remarks>
HARD_DISK_KEY_METADATA_TAG = 0x4b455920,
#endregion
#region PCMCIA
/// <summary>
/// PCMCIA CIS information
/// </summary>
/// <remarks>"CIS "</remarks>
PCMCIA_CIS_METADATA_TAG = 0x43495320,
#endregion
#region CD-ROM
/// <remarks>"CHCD"</remarks>
CDROM_OLD_METADATA_TAG = 0x43484344,
/// <remarks>"CHTR"</remarks>
CDROM_TRACK_METADATA_TAG = 0x43485452,
/// <remarks>"CHT2"</remarks>
CDROM_TRACK_METADATA2_TAG = 0x43485432,
#endregion
#region GD-ROM
/// <remarks>"CHGT"</remarks>
GDROM_OLD_METADATA_TAG = 0x43484754,
/// <remarks>"CHGD"</remarks>
GDROM_TRACK_METADATA_TAG = 0x43484744,
#endregion
#region DVD
/// <summary>
/// Standard DVD metadata
/// </summary>
/// <remarks>"DVD "</remarks>
DVD_METADATA_TAG = 0x44564420,
#endregion
#region A/V
/// <summary>
/// Standard A/V metadata
/// </summary>
/// <remarks>"AVAV"</remarks>
AV_METADATA_TAG = 0x41564156,
/// <summary>
/// A/V laserdisc frame metadata
/// </summary>
/// <remarks>"AVLD"</remarks>
AV_LD_METADATA_TAG = 0x41564c44,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
public enum V34EntryType : uint
{
/// <summary>
/// Invalid type
/// </summary>
V34_MAP_ENTRY_TYPE_INVALID = 0,
/// <summary>
/// Standard compression
/// </summary>
V34_MAP_ENTRY_TYPE_COMPRESSED = 1,
/// <summary>
/// Uncompressed data
/// </summary>
V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2,
/// <summary>
/// Mini: use offset as raw data
/// </summary>
V34_MAP_ENTRY_TYPE_MINI = 3,
/// <summary>
/// Same as another hunk in this file
/// </summary>
V34_MAP_ENTRY_TYPE_SELF_HUNK = 4,
/// <summary>
/// Same as a hunk in the parent file
/// </summary>
V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5,
/// <summary>
/// Compressed with secondary algorithm (usually FLAC CDDA)
/// </summary>
V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
public enum V5CompressionType : uint
{
// These types are live when running
/// <summary>
/// Codec #0
/// </summary>
COMPRESSION_TYPE_0 = 0,
/// <summary>
/// Codec #1
/// </summary>
COMPRESSION_TYPE_1 = 1,
/// <summary>
/// Codec #2
/// </summary>
COMPRESSION_TYPE_2 = 2,
/// <summary>
/// Codec #3
/// </summary>
COMPRESSION_TYPE_3 = 3,
/// <summary>
/// No compression; implicit length = hunkbytes
/// </summary>
COMPRESSION_NONE = 4,
/// <summary>
/// Same as another block in this CHD
/// </summary>
COMPRESSION_SELF = 5,
/// <summary>
/// Same as a hunk's worth of units in the parent CHD
/// </summary>
COMPRESSION_PARENT = 6,
// These additional pseudo-types are used for compressed encodings
/// <summary>
/// Start of small RLE run (4-bit length)
/// </summary>
COMPRESSION_RLE_SMALL,
/// <summary>
/// Start of large RLE run (8-bit length)
/// </summary>
COMPRESSION_RLE_LARGE,
/// <summary>
/// Same as the last COMPRESSION_SELF block
/// </summary>
COMPRESSION_SELF_0,
/// <summary>
/// Same as the last COMPRESSION_SELF block + 1
/// </summary>
COMPRESSION_SELF_1,
/// <summary>
/// Same block in the parent
/// </summary>
COMPRESSION_PARENT_SELF,
/// <summary>
/// Same as the last COMPRESSION_PARENT block
/// </summary>
COMPRESSION_PARENT_0,
/// <summary>
/// Same as the last COMPRESSION_PARENT block + 1
/// </summary>
COMPRESSION_PARENT_1
}
}

View File

@@ -0,0 +1,39 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MetadataEntry
{
/// <summary>
/// Offset within the file of the header
/// </summary>
public ulong Offset;
/// <summary>
/// Offset within the file of the next header
/// </summary>
public ulong Next;
/// <summary>
/// Offset within the file of the previous header
/// </summary>
public ulong Prev;
/// <summary>
/// Length of the metadata
/// </summary>
public uint Length;
/// <summary>
/// Metadata tag
/// </summary>
public MetadataTag Metatag;
/// <summary>
/// Flag bits
/// </summary>
public MetadataFlags Flags;
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MetadataHash
{
/// <summary>
/// Tag of the metadata in big-endian
/// </summary>
public MetadataTag Tag;
/// <summary>
/// Hash data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? SHA1;
}
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/tree/main/doc/FileFormats/song.ini"/>
/// <remarks>[song]/[Song]</remarks>
internal class SongIni
public class SongIni
{
#region Song/Chart Metadata

View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/blob/main/doc/FileFormats/Other/Frets%20on%20Fire%20X/Careers.md"/>
public class Tier
{
/// <summary>
/// Display name of the tier.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Name used for associating a song with this tier, and for checking unlock requirements.
/// </summary>
public string? UnlockId { get; set; }
}
}

View File

@@ -1,10 +1,8 @@
using System.Collections.Generic;
namespace SabreTools.Models.Charts
{
/// <see href="https://github.com/TheNathannator/GuitarGame_ChartFormats/blob/main/doc/FileFormats/Other/Frets%20on%20Fire%20X/Careers.md"/>
/// <remarks>[titles]</remarks>
internal class TitlesIni
public class TitlesIni
{
/// <summary>
/// A space-separated list of .ini sections to include in the career.
@@ -13,9 +11,8 @@ namespace SabreTools.Models.Charts
public string[]? SectionList { get; set; }
/// <summary>
/// `name` - Display name of the tier.
/// `unlock_id` - Name used for associating a song with this tier, and for checking unlock requirements.
/// This entry points to other sections that should be used as part of the career.
/// </summary>
public Dictionary<string, (string? Name, string? UnlockId)>? Sections { get; set; }
public Tier[]? Sections { get; set; }
}
}

View File

@@ -31,19 +31,19 @@ namespace SabreTools.Models.InstallShieldCabinet
public string? DisplayName { get; set; }
/// <summary>
/// Reserved
/// Component status
/// </summary>
public ushort Reserved0 { get; set; }
public ComponentStatus Status { get; set; }
/// <summary>
/// Reserved offset
/// Offset to the password
/// </summary>
public uint ReservedOffset0 { get; set; }
public uint PasswordOffset { get; set; }
/// <summary>
/// Reserved offset
/// Misc offset
/// </summary>
public uint ReservedOffset1 { get; set; }
public uint MiscOffset { get; set; }
/// <summary>
/// Component index
@@ -61,25 +61,24 @@ namespace SabreTools.Models.InstallShieldCabinet
public string? Name { get; set; }
/// <summary>
/// Reserved offset
/// Offset to the CD-ROM folder
/// </summary>
public uint ReservedOffset2 { get; set; }
public uint CDRomFolderOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to the HTTP location
/// </summary>
public uint ReservedOffset3 { get; set; }
public uint HTTPLocationOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to the FTP location
/// </summary>
public uint ReservedOffset4 { get; set; }
public uint FTPLocationOffset { get; set; }
/// <summary>
/// Reserved
/// Unknown GUIDs
/// </summary>
/// <remarks>32 bytes</remarks>
public byte[]? Reserved1 { get; set; }
public Guid[]? Guid { get; set; } = new Guid[2];
/// <summary>
/// Offset to the component CLSID
@@ -94,7 +93,7 @@ namespace SabreTools.Models.InstallShieldCabinet
/// <summary>
/// Reserved
/// </summary>
/// <remarks>28 bytes</remarks>
/// <remarks>28 bytes, see CompAttrs</remarks>
public byte[]? Reserved2 { get; set; }
/// <summary>
@@ -154,23 +153,23 @@ namespace SabreTools.Models.InstallShieldCabinet
public uint NextComponentOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to on installing text
/// </summary>
public uint ReservedOffset5 { get; set; }
public uint OnInstallingOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to on installed text
/// </summary>
public uint ReservedOffset6 { get; set; }
public uint OnInstalledOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to on uninstalling text
/// </summary>
public uint ReservedOffset7 { get; set; }
public uint OnUninstallingOffset { get; set; }
/// <summary>
/// Reserved offset
/// Offset to on uninstalled text
/// </summary>
public uint ReservedOffset8 { get; set; }
public uint OnUninstalledOffset { get; set; }
}
}

View File

@@ -2,6 +2,26 @@ using System;
namespace SabreTools.Models.InstallShieldCabinet
{
/// <remarks>i6comp02</remarks>
[Flags]
public enum ComponentStatus : ushort
{
/// <summary>
/// Critical
/// </summary>
COMP_STAT_CRITICAL = 0x01,
/// <summary>
/// Recommended
/// </summary>
COMP_STAT_RECOMMEND = 0x02,
/// <summary>
/// Standard
/// </summary>
COMP_STAT_STANDARD = 0x04,
}
/// <see href="https://github.com/twogood/unshield/blob/main/lib/cabfile.h"/>
[Flags]
public enum FileFlags : ushort
@@ -12,6 +32,66 @@ namespace SabreTools.Models.InstallShieldCabinet
FILE_INVALID = 8,
}
/// <remarks>i6comp02</remarks>
[Flags]
public enum FileGroupAttributes : ushort
{
/// <summary>
/// Shared
/// </summary>
FGATTR_SHARED = 0x01,
/// <summary>
/// Encrypted
/// </summary>
FGATTR_ENCRYPTED = 0x02,
/// <summary>
/// Compressed
/// </summary>
FGATTR_COMPRESSED = 0x04,
/// <summary>
/// Self-Registering
/// </summary>
FGATTR_SELFREGISTER = 0x10,
/// <summary>
/// Potentially locked
/// </summary>
FGATTR_LOCKED = 0x20,
/// <summary>
/// Uninstall
/// </summary>
FGATTR_UNINSTALL = 0x40,
}
/// <remarks>i6comp02</remarks>
[Flags]
public enum FileGroupFlags : uint
{
/// <summary>
/// Always overwrite
/// </summary>
FGDESC_ALWAYS_OVERWRITE = 0x001,
/// <summary>
/// Never overwrite
/// </summary>
FGDESC_NEVER_OVERWRITE = 0x002,
/// <summary>
/// Overwrite if newer date
/// </summary>
FGDESC_NEWER_DATE = 0x020,
/// <summary>
/// Overwrite if newer version
/// </summary>
FGDESC_NEWER_VERSION = 0x200,
}
/// <see href="https://github.com/twogood/unshield/blob/main/lib/cabfile.h"/>
public enum LinkFlags : byte
{

View File

@@ -1,6 +1,7 @@
namespace SabreTools.Models.InstallShieldCabinet
{
/// <see href="https://github.com/twogood/unshield/blob/main/lib/libunshield.h"/>
/// <remarks>Additional info from i6comp02</remarks>
public sealed class FileGroup
{
/// <summary>
@@ -18,35 +19,15 @@ namespace SabreTools.Models.InstallShieldCabinet
/// </summary>
public uint ExpandedSize { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved0 { get; set; }
/// <summary>
/// Size of the compressed data
/// </summary>
public uint CompressedSize { get; set; }
/// <summary>
/// Reserved
/// Attributes (junk2)
/// </summary>
public byte[]? Reserved1 { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved2 { get; set; }
/// <summary>
/// Attribute(?)
/// </summary>
public ushort Attribute1 { get; set; }
/// <summary>
/// Attribute(?)
/// </summary>
public ushort Attribute2 { get; set; }
public FileGroupAttributes Attributes { get; set; }
/// <summary>
/// Index of the first file
@@ -59,19 +40,19 @@ namespace SabreTools.Models.InstallShieldCabinet
public uint LastFile { get; set; }
/// <summary>
/// Unknown offset(?)
/// Unknown string offset
/// </summary>
public uint UnknownOffset { get; set; }
public uint UnknownStringOffset { get; set; }
/// <summary>
/// Var 4 offset(?)
/// Offset to the operating system (Var4)
/// </summary>
public uint Var4Offset { get; set; }
public uint OperatingSystemOffset { get; set; }
/// <summary>
/// Var 1 offset(?)
/// Offset to the language (Var1)
/// </summary>
public uint Var1Offset { get; set; }
public uint LanguageOffset { get; set; }
/// <summary>
/// Offset to the HTTP location
@@ -84,43 +65,23 @@ namespace SabreTools.Models.InstallShieldCabinet
public uint FTPLocationOffset { get; set; }
/// <summary>
/// Misc offset(?)
/// Misc offset
/// </summary>
public uint MiscOffset { get; set; }
/// <summary>
/// Var 2 offset(?)
/// </summary>
public uint Var2Offset { get; set; }
/// <summary>
/// Offset to the target directory
/// </summary>
public uint TargetDirectoryOffset { get; set; }
/// <summary>
/// Reserved
/// Overwrite setting flags
/// </summary>
public byte[]? Reserved3 { get; set; }
public FileGroupFlags OverwriteFlags { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved4 { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved5 { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved6 { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved7 { get; set; }
public uint[]? Reserved { get; set; } = new uint[4];
}
}

View File

@@ -6,7 +6,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.4.9</Version>
<Version>1.4.11</Version>
<WarningsNotAsErrors>CS0618</WarningsNotAsErrors>
<!-- Package Properties -->
@@ -39,15 +39,6 @@
<None Include="../README.md" Pack="true" PackagePath="" />
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup
Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="MinValueTupleBridge" Version="0.2.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@@ -1,10 +1,12 @@
using System.Collections.Generic;
namespace SabreTools.Models.TAR
{
public sealed class Archive
{
/// <summary>
/// File header
/// 1 or more entries
/// </summary>
public Header? Header { get; set; }
public List<Entry>? Entries { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Models.TAR
{
public sealed class Block
{
public readonly byte[] Data = new byte[512];
}
}

View File

@@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace SabreTools.Models.TAR
{
public sealed class Entry
{
/// <summary>
/// Entry header
/// </summary>
public Header? Header { get; set; }
/// <summary>
/// 0 or more blocks representing the content
/// </summary>
public List<Block>? Blocks { get; set; }
}
}

View File

@@ -1,85 +1,117 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.TAR
{
/// <see href="https://www.ibm.com/docs/en/aix/7.3?topic=files-tarh-file"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Header
{
/// <summary>
/// File name
/// File name without a forward slash
/// </summary>
public string? FileName { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string? FileName;
/// <summary>
/// File mode
/// </summary>
public Mode Mode { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public byte[]? Mode;
/// <summary>
/// <summary>
/// Owner's numeric user ID
/// </summary>
public uint UID { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public byte[]? UID;
/// <summary>
/// Owner's numeric user ID
/// <summary>
/// Owner's numeric group ID
/// </summary>
public uint GID { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public byte[]? GID;
/// <summary>
/// File size in bytes
/// </summary>
public ulong Size { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public byte[]? Size;
/// <summary>
/// Last modification time in numeric Unix time format
/// </summary>
public ulong ModifiedTime { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public byte[]? ModifiedTime;
/// <summary>
/// Checksum for header record
/// </summary>
public ushort Checksum { get; set; }
/// <remarks>Octal string representation</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public byte[]? Checksum;
/// <summary>
/// Link indicator (file type) / Type flag
/// </summary>
public TypeFlag TypeFlag { get; set; }
public TypeFlag TypeFlag;
/// <summary>
/// Name of linked file
/// Linked path name or file name
/// </summary>
public string? LinkName { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string? LinkName;
#region USTAR Extension
/// <summary>
/// UStar indicator, "ustar", then NUL
/// </summary>
public string? Magic { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string? Magic;
/// <summary>
/// UStar version, "00"
/// </summary>
public string? Version { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
public string? Version;
/// <summary>
/// Owner user name
/// </summary>
public string? UserName { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? UserName;
/// <summary>
/// Owner group name
/// </summary>
public string? GroupName { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? GroupName;
/// <summary>
/// Device major number
/// </summary>
public string? DevMajor { get; set; }
/// <remarks>Octal string representation(?)</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? DevMajor;
/// <summary>
/// Device minor number
/// </summary>
public string? DevMinor { get; set; }
/// <remarks>Octal string representation(?)</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? DevMinor;
/// <summary>
/// Filename prefix
/// Path name without trailing slashes
/// </summary>
public string? Prefix { get; set; }
/// <remarks>155 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 155)]
public string? Prefix;
#endregion
}
}