ICSharpCode.SharpZipLib.Tar.TarHeader - Coverage Report

# Summary

Class: | ICSharpCode.SharpZipLib.Tar.TarHeader
Assembly: | ICSharpCode.SharpZipLib
File(s): | C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Tar\TarHeader.cs
Covered lines: | 209
Uncovered lines: | 63
Coverable lines: | 272
Total lines: | 1077
Line coverage: | 76.8%
Branch coverage: | 66.9%

# Metrics

Method | Cyclomatic Complexity | Sequence Coverage | Branch Coverage
--- | --- | --- | ---
.ctor() | 1 | 100 | 100
GetName() | 1 | 0 | 0
Clone() | 1 | 100 | 100
ParseBuffer(...) | 4 | 63.16 | 42.86
WriteHeader(...) | 6 | 89.66 | 72.73
GetHashCode() | 1 | 0 | 0
Equals(...) | 16 | 83.33 | 66.67
SetValueDefaults(...) | 1 | 0 | 0
RestoreSetValues() | 1 | 0 | 0
ParseBinaryOrOctal(...) | 3 | 25 | 40
ParseOctal(...) | 8 | 93.33 | 73.33
ParseName(...) | 7 | 73.33 | 69.23
GetNameBytes(...) | 3 | 0 | 0
GetNameBytes(...) | 6 | 83.33 | 72.73
GetNameBytes(...) | 3 | 0 | 0
GetNameBytes(...) | 3 | 60 | 60
GetAsciiBytes(...) | 5 | 77.78 | 77.78
GetOctalBytes(...) | 6 | 93.33 | 90.91
GetBinaryOrOctalBytes(...) | 3 | 22.22 | 40
GetCheckSumOctalBytes(...) | 1 | 100 | 100
ComputeCheckSum(...) | 2 | 100 | 100
MakeCheckSum(...) | 4 | 100 | 100
GetCTime(...) | 1 | 100 | 100
GetDateTimeFromCTime(...) | 1 | 50 | 100
.cctor() | 1 | 100 | 100

# File(s)

## C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Tar\TarHeader.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | `using System.Text;`
|  | `3` |  | ``
|  | `4` |  | `namespace ICSharpCode.SharpZipLib.Tar`
|  | `5` |  | `{`
|  | `6` |  | `/// <summary>`
|  | `7` |  | `/// This class encapsulates the Tar Entry Header used in Tar Archives.`
|  | `8` |  | `/// The class also holds a number of tar constants, used mostly in headers.`
|  | `9` |  | `/// </summary>`
|  | `10` |  | `/// <remarks>`
|  | `11` |  | `/// The tar format and its POSIX successor PAX have a long history which makes for compatability`
|  | `12` |  | `/// issues when creating and reading files.`
|  | `13` |  | `///`
|  | `14` |  | `/// This is further complicated by a large number of programs with variations on formats`
|  | `15` |  | `/// One common issue is the handling of names longer than 100 characters.`
|  | `16` |  | `/// GNU style long names are currently supported.`
|  | `17` |  | `///`
|  | `18` |  | `/// This is the ustar (Posix 1003.1) header.`
|  | `19` |  | `///`
|  | `20` |  | `/// struct header`
|  | `21` |  | `/// {`
|  | `22` |  | `/// char t_name[100]; // 0 Filename`
|  | `23` |  | `/// char t_mode[8]; // 100 Permissions`
|  | `24` |  | `/// char t_uid[8]; // 108 Numerical User ID`
|  | `25` |  | `/// char t_gid[8]; // 116 Numerical Group ID`
|  | `26` |  | `/// char t_size[12]; // 124 Filesize`
|  | `27` |  | `/// char t_mtime[12]; // 136 st_mtime`
|  | `28` |  | `/// char t_chksum[8]; // 148 Checksum`
|  | `29` |  | `/// char t_typeflag; // 156 Type of File`
|  | `30` |  | `/// char t_linkname[100]; // 157 Target of Links`
|  | `31` |  | `/// char t_magic[6]; // 257 "ustar" or other...`
|  | `32` |  | `/// char t_version[2]; // 263 Version fixed to 00`
|  | `33` |  | `/// char t_uname[32]; // 265 User Name`
|  | `34` |  | `/// char t_gname[32]; // 297 Group Name`
|  | `35` |  | `/// char t_devmajor[8]; // 329 Major for devices`
|  | `36` |  | `/// char t_devminor[8]; // 337 Minor for devices`
|  | `37` |  | `/// char t_prefix[155]; // 345 Prefix for t_name`
|  | `38` |  | `/// char t_mfill[12]; // 500 Filler up to 512`
|  | `39` |  | `/// };`
|  | `40` |  | `/// </remarks>`
|  | `41` |  | `public class TarHeader : ICloneable`
|  | `42` |  | `{`
|  | `43` |  | `#region Constants`
|  | `44` |  | `/// <summary>`
|  | `45` |  | `/// The length of the name field in a header buffer.`
|  | `46` |  | `/// </summary>`
|  | `47` |  | `public const int NAMELEN = 100;`
|  | `48` |  | ``
|  | `49` |  | `/// <summary>`
|  | `50` |  | `/// The length of the mode field in a header buffer.`
|  | `51` |  | `/// </summary>`
|  | `52` |  | `public const int MODELEN = 8;`
|  | `53` |  | ``
|  | `54` |  | `/// <summary>`
|  | `55` |  | `/// The length of the user id field in a header buffer.`
|  | `56` |  | `/// </summary>`
|  | `57` |  | `public const int UIDLEN = 8;`
|  | `58` |  | ``
|  | `59` |  | `/// <summary>`
|  | `60` |  | `/// The length of the group id field in a header buffer.`
|  | `61` |  | `/// </summary>`
|  | `62` |  | `public const int GIDLEN = 8;`
|  | `63` |  | ``
|  | `64` |  | `/// <summary>`
|  | `65` |  | `/// The length of the checksum field in a header buffer.`
|  | `66` |  | `/// </summary>`
|  | `67` |  | `public const int CHKSUMLEN = 8;`
|  | `68` |  | ``
|  | `69` |  | `/// <summary>`
|  | `70` |  | `/// Offset of checksum in a header buffer.`
|  | `71` |  | `/// </summary>`
|  | `72` |  | `public const int CHKSUMOFS = 148;`
|  | `73` |  | ``
|  | `74` |  | `/// <summary>`
|  | `75` |  | `/// The length of the size field in a header buffer.`
|  | `76` |  | `/// </summary>`
|  | `77` |  | `public const int SIZELEN = 12;`
|  | `78` |  | ``
|  | `79` |  | `/// <summary>`
|  | `80` |  | `/// The length of the magic field in a header buffer.`
|  | `81` |  | `/// </summary>`
|  | `82` |  | `public const int MAGICLEN = 6;`
|  | `83` |  | ``
|  | `84` |  | `/// <summary>`
|  | `85` |  | `/// The length of the version field in a header buffer.`
|  | `86` |  | `/// </summary>`
|  | `87` |  | `public const int VERSIONLEN = 2;`
|  | `88` |  | ``
|  | `89` |  | `/// <summary>`
|  | `90` |  | `/// The length of the modification time field in a header buffer.`
|  | `91` |  | `/// </summary>`
|  | `92` |  | `public const int MODTIMELEN = 12;`
|  | `93` |  | ``
|  | `94` |  | `/// <summary>`
|  | `95` |  | `/// The length of the user name field in a header buffer.`
|  | `96` |  | `/// </summary>`
|  | `97` |  | `public const int UNAMELEN = 32;`
|  | `98` |  | ``
|  | `99` |  | `/// <summary>`
|  | `100` |  | `/// The length of the group name field in a header buffer.`
|  | `101` |  | `/// </summary>`
|  | `102` |  | `public const int GNAMELEN = 32;`
|  | `103` |  | ``
|  | `104` |  | `/// <summary>`
|  | `105` |  | `/// The length of the devices field in a header buffer.`
|  | `106` |  | `/// </summary>`
|  | `107` |  | `public const int DEVLEN = 8;`
|  | `108` |  | ``
|  | `109` |  | `/// <summary>`
|  | `110` |  | `/// The length of the name prefix field in a header buffer.`
|  | `111` |  | `/// </summary>`
|  | `112` |  | `public const int PREFIXLEN = 155;`
|  | `113` |  | ``
|  | `114` |  | `//`
|  | `115` |  | `// LF_ constants represent the "type" of an entry`
|  | `116` |  | `//`
|  | `117` |  | ``
|  | `118` |  | `/// <summary>`
|  | `119` |  | `/// The "old way" of indicating a normal file.`
|  | `120` |  | `/// </summary>`
|  | `121` |  | `public const byte LF_OLDNORM = 0;`
|  | `122` |  | ``
|  | `123` |  | `/// <summary>`
|  | `124` |  | `/// Normal file type.`
|  | `125` |  | `/// </summary>`
|  | `126` |  | `public const byte LF_NORMAL = (byte)'0';`
|  | `127` |  | ``
|  | `128` |  | `/// <summary>`
|  | `129` |  | `/// Link file type.`
|  | `130` |  | `/// </summary>`
|  | `131` |  | `public const byte LF_LINK = (byte)'1';`
|  | `132` |  | ``
|  | `133` |  | `/// <summary>`
|  | `134` |  | `/// Symbolic link file type.`
|  | `135` |  | `/// </summary>`
|  | `136` |  | `public const byte LF_SYMLINK = (byte)'2';`
|  | `137` |  | ``
|  | `138` |  | `/// <summary>`
|  | `139` |  | `/// Character device file type.`
|  | `140` |  | `/// </summary>`
|  | `141` |  | `public const byte LF_CHR = (byte)'3';`
|  | `142` |  | ``
|  | `143` |  | `/// <summary>`
|  | `144` |  | `/// Block device file type.`
|  | `145` |  | `/// </summary>`
|  | `146` |  | `public const byte LF_BLK = (byte)'4';`
|  | `147` |  | ``
|  | `148` |  | `/// <summary>`
|  | `149` |  | `/// Directory file type.`
|  | `150` |  | `/// </summary>`
|  | `151` |  | `public const byte LF_DIR = (byte)'5';`
|  | `152` |  | ``
|  | `153` |  | `/// <summary>`
|  | `154` |  | `/// FIFO (pipe) file type.`
|  | `155` |  | `/// </summary>`
|  | `156` |  | `public const byte LF_FIFO = (byte)'6';`
|  | `157` |  | ``
|  | `158` |  | `/// <summary>`
|  | `159` |  | `/// Contiguous file type.`
|  | `160` |  | `/// </summary>`
|  | `161` |  | `public const byte LF_CONTIG = (byte)'7';`
|  | `162` |  | ``
|  | `163` |  | `/// <summary>`
|  | `164` |  | `/// Posix.1 2001 global extended header`
|  | `165` |  | `/// </summary>`
|  | `166` |  | `public const byte LF_GHDR = (byte)'g';`
|  | `167` |  | ``
|  | `168` |  | `/// <summary>`
|  | `169` |  | `/// Posix.1 2001 extended header`
|  | `170` |  | `/// </summary>`
|  | `171` |  | `public const byte LF_XHDR = (byte)'x';`
|  | `172` |  | ``
|  | `173` |  | `// POSIX allows for upper case ascii type as extensions`
|  | `174` |  | ``
|  | `175` |  | `/// <summary>`
|  | `176` |  | `/// Solaris access control list file type`
|  | `177` |  | `/// </summary>`
|  | `178` |  | `public const byte LF_ACL = (byte)'A';`
|  | `179` |  | ``
|  | `180` |  | `/// <summary>`
|  | `181` |  | `/// GNU dir dump file type`
|  | `182` |  | `/// This is a dir entry that contains the names of files that were in the`
|  | `183` |  | `/// dir at the time the dump was made`
|  | `184` |  | `/// </summary>`
|  | `185` |  | `public const byte LF_GNU_DUMPDIR = (byte)'D';`
|  | `186` |  | ``
|  | `187` |  | `/// <summary>`
|  | `188` |  | `/// Solaris Extended Attribute File`
|  | `189` |  | `/// </summary>`
|  | `190` |  | `public const byte LF_EXTATTR = (byte)'E';`
|  | `191` |  | ``
|  | `192` |  | `/// <summary>`
|  | `193` |  | `/// Inode (metadata only) no file content`
|  | `194` |  | `/// </summary>`
|  | `195` |  | `public const byte LF_META = (byte)'I';`
|  | `196` |  | ``
|  | `197` |  | `/// <summary>`
|  | `198` |  | `/// Identifies the next file on the tape as having a long link name`
|  | `199` |  | `/// </summary>`
|  | `200` |  | `public const byte LF_GNU_LONGLINK = (byte)'K';`
|  | `201` |  | ``
|  | `202` |  | `/// <summary>`
|  | `203` |  | `/// Identifies the next file on the tape as having a long name`
|  | `204` |  | `/// </summary>`
|  | `205` |  | `public const byte LF_GNU_LONGNAME = (byte)'L';`
|  | `206` |  | ``
|  | `207` |  | `/// <summary>`
|  | `208` |  | `/// Continuation of a file that began on another volume`
|  | `209` |  | `/// </summary>`
|  | `210` |  | `public const byte LF_GNU_MULTIVOL = (byte)'M';`
|  | `211` |  | ``
|  | `212` |  | `/// <summary>`
|  | `213` |  | `/// For storing filenames that dont fit in the main header (old GNU)`
|  | `214` |  | `/// </summary>`
|  | `215` |  | `public const byte LF_GNU_NAMES = (byte)'N';`
|  | `216` |  | ``
|  | `217` |  | `/// <summary>`
|  | `218` |  | `/// GNU Sparse file`
|  | `219` |  | `/// </summary>`
|  | `220` |  | `public const byte LF_GNU_SPARSE = (byte)'S';`
|  | `221` |  | ``
|  | `222` |  | `/// <summary>`
|  | `223` |  | `/// GNU Tape/volume header ignore on extraction`
|  | `224` |  | `/// </summary>`
|  | `225` |  | `public const byte LF_GNU_VOLHDR = (byte)'V';`
|  | `226` |  | ``
|  | `227` |  | `/// <summary>`
|  | `228` |  | `/// The magic tag representing a POSIX tar archive. (includes trailing NULL)`
|  | `229` |  | `/// </summary>`
|  | `230` |  | `public const string TMAGIC = "ustar ";`
|  | `231` |  | ``
|  | `232` |  | `/// <summary>`
|  | `233` |  | `/// The magic tag representing an old GNU tar archive where version is included in magic and overwrites it`
|  | `234` |  | `/// </summary>`
|  | `235` |  | `public const string GNU_TMAGIC = "ustar ";`
|  | `236` |  | ``
|  | `237` |  | `const long timeConversionFactor = 10000000L; // 1 tick == 100 nanoseconds`
| 1 | `238` |  | `readonly static DateTime dateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);`
|  | `239` |  | `#endregion`
|  | `240` |  | ``
|  | `241` |  | `#region Constructors`
|  | `242` |  | ``
|  | `243` |  | `/// <summary>`
|  | `244` |  | `/// Initialise a default TarHeader instance`
|  | `245` |  | `/// </summary>`
| 84 | `246` |  | `public TarHeader()`
|  | `247` |  | `{`
| 84 | `248` |  | `Magic = TMAGIC;`
| 84 | `249` |  | `Version = " ";`
|  | `250` |  | ``
| 84 | `251` |  | `Name = "";`
| 84 | `252` |  | `LinkName = "";`
|  | `253` |  | ``
| 84 | `254` |  | `UserId = defaultUserId;`
| 84 | `255` |  | `GroupId = defaultGroupId;`
| 84 | `256` |  | `UserName = defaultUser;`
| 84 | `257` |  | `GroupName = defaultGroupName;`
| 84 | `258` |  | `Size = 0;`
| 84 | `259` |  | `}`
|  | `260` |  | ``
|  | `261` |  | `#endregion`
|  | `262` |  | ``
|  | `263` |  | `#region Properties`
|  | `264` |  | `/// <summary>`
|  | `265` |  | `/// Get/set the name for this tar entry.`
|  | `266` |  | `/// </summary>`
|  | `267` |  | `/// <exception cref="ArgumentNullException">Thrown when attempting to set the property to null.</exception>`
|  | `268` |  | `public string Name {`
| 214 | `269` |  | `get { return name; }`
|  | `270` |  | `set {`
| 166 | `271` |  | `if (value == null) {`
| 1 | `272` |  | `throw new ArgumentNullException(nameof(value));`
|  | `273` |  | `}`
| 165 | `274` |  | `name = value;`
| 165 | `275` |  | `}`
|  | `276` |  | `}`
|  | `277` |  | ``
|  | `278` |  | `/// <summary>`
|  | `279` |  | `/// Get the name of this entry.`
|  | `280` |  | `/// </summary>`
|  | `281` |  | `/// <returns>The entry's name.</returns>`
|  | `282` |  | `[Obsolete("Use the Name property instead", true)]`
|  | `283` |  | `public string GetName()`
|  | `284` |  | `{`
| 0 | `285` |  | `return name;`
|  | `286` |  | `}`
|  | `287` |  | ``
|  | `288` |  | `/// <summary>`
|  | `289` |  | `/// Get/set the entry's Unix style permission mode.`
|  | `290` |  | `/// </summary>`
|  | `291` |  | `public int Mode {`
| 1 | `292` |  | `get { return mode; }`
| 162 | `293` |  | `set { mode = value; }`
|  | `294` |  | `}`
|  | `295` |  | ``
|  | `296` |  | ``
|  | `297` |  | `/// <summary>`
|  | `298` |  | `/// The entry's user id.`
|  | `299` |  | `/// </summary>`
|  | `300` |  | `/// <remarks>`
|  | `301` |  | `/// This is only directly relevant to unix systems.`
|  | `302` |  | `/// The default is zero.`
|  | `303` |  | `/// </remarks>`
|  | `304` |  | `public int UserId {`
| 125 | `305` |  | `get { return userId; }`
| 334 | `306` |  | `set { userId = value; }`
|  | `307` |  | `}`
|  | `308` |  | ``
|  | `309` |  | ``
|  | `310` |  | `/// <summary>`
|  | `311` |  | `/// Get/set the entry's group id.`
|  | `312` |  | `/// </summary>`
|  | `313` |  | `/// <remarks>`
|  | `314` |  | `/// This is only directly relevant to linux/unix systems.`
|  | `315` |  | `/// The default value is zero.`
|  | `316` |  | `/// </remarks>`
|  | `317` |  | `public int GroupId {`
| 125 | `318` |  | `get { return groupId; }`
| 336 | `319` |  | `set { groupId = value; }`
|  | `320` |  | `}`
|  | `321` |  | ``
|  | `322` |  | ``
|  | `323` |  | `/// <summary>`
|  | `324` |  | `/// Get/set the entry's size.`
|  | `325` |  | `/// </summary>`
|  | `326` |  | `/// <exception cref="ArgumentOutOfRangeException">Thrown when setting the size to less than zero.</exception>`
|  | `327` |  | `public long Size {`
| 195 | `328` |  | `get { return size; }`
|  | `329` |  | `set {`
| 237 | `330` |  | `if (value < 0) {`
| 1 | `331` |  | `throw new ArgumentOutOfRangeException(nameof(value), "Cannot be less than zero");`
|  | `332` |  | `}`
| 236 | `333` |  | `size = value;`
| 236 | `334` |  | `}`
|  | `335` |  | `}`
|  | `336` |  | ``
|  | `337` |  | ``
|  | `338` |  | `/// <summary>`
|  | `339` |  | `/// Get/set the entry's modification time.`
|  | `340` |  | `/// </summary>`
|  | `341` |  | `/// <remarks>`
|  | `342` |  | `/// The modification time is only accurate to within a second.`
|  | `343` |  | `/// </remarks>`
|  | `344` |  | `/// <exception cref="ArgumentOutOfRangeException">Thrown when setting the date time to less than 1/1/1970.</exceptio`
|  | `345` |  | `public DateTime ModTime {`
| 121 | `346` |  | `get { return modTime; }`
|  | `347` |  | `set {`
| 85 | `348` |  | `if (value < dateTime1970) {`
| 1 | `349` |  | `throw new ArgumentOutOfRangeException(nameof(value), "ModTime cannot be before Jan 1st 1970");`
|  | `350` |  | `}`
| 84 | `351` |  | `modTime = new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second);`
| 84 | `352` |  | `}`
|  | `353` |  | `}`
|  | `354` |  | ``
|  | `355` |  | ``
|  | `356` |  | `/// <summary>`
|  | `357` |  | `/// Get the entry's checksum. This is only valid/updated after writing or reading an entry.`
|  | `358` |  | `/// </summary>`
|  | `359` |  | `public int Checksum {`
| 51 | `360` |  | `get { return checksum; }`
|  | `361` |  | `}`
|  | `362` |  | ``
|  | `363` |  | ``
|  | `364` |  | `/// <summary>`
|  | `365` |  | `/// Get value of true if the header checksum is valid, false otherwise.`
|  | `366` |  | `/// </summary>`
|  | `367` |  | `public bool IsChecksumValid {`
| 3 | `368` |  | `get { return isChecksumValid; }`
|  | `369` |  | `}`
|  | `370` |  | ``
|  | `371` |  | ``
|  | `372` |  | `/// <summary>`
|  | `373` |  | `/// Get/set the entry's type flag.`
|  | `374` |  | `/// </summary>`
|  | `375` |  | `public byte TypeFlag {`
| 334 | `376` |  | `get { return typeFlag; }`
| 166 | `377` |  | `set { typeFlag = value; }`
|  | `378` |  | `}`
|  | `379` |  | ``
|  | `380` |  | ``
|  | `381` |  | `/// <summary>`
|  | `382` |  | `/// The entry's link name.`
|  | `383` |  | `/// </summary>`
|  | `384` |  | `/// <exception cref="ArgumentNullException">Thrown when attempting to set LinkName to null.</exception>`
|  | `385` |  | `public string LinkName {`
| 120 | `386` |  | `get { return linkName; }`
|  | `387` |  | `set {`
| 170 | `388` |  | `if (value == null) {`
| 1 | `389` |  | `throw new ArgumentNullException(nameof(value));`
|  | `390` |  | `}`
| 169 | `391` |  | `linkName = value;`
| 169 | `392` |  | `}`
|  | `393` |  | `}`
|  | `394` |  | ``
|  | `395` |  | ``
|  | `396` |  | `/// <summary>`
|  | `397` |  | `/// Get/set the entry's magic tag.`
|  | `398` |  | `/// </summary>`
|  | `399` |  | `/// <exception cref="ArgumentNullException">Thrown when attempting to set Magic to null.</exception>`
|  | `400` |  | `public string Magic {`
| 116 | `401` |  | `get { return magic; }`
|  | `402` |  | `set {`
| 90 | `403` |  | `if (value == null) {`
| 1 | `404` |  | `throw new ArgumentNullException(nameof(value));`
|  | `405` |  | `}`
| 89 | `406` |  | `magic = value;`
| 89 | `407` |  | `}`
|  | `408` |  | `}`
|  | `409` |  | ``
|  | `410` |  | ``
|  | `411` |  | `/// <summary>`
|  | `412` |  | `/// The entry's version.`
|  | `413` |  | `/// </summary>`
|  | `414` |  | `/// <exception cref="ArgumentNullException">Thrown when attempting to set Version to null.</exception>`
|  | `415` |  | `public string Version {`
|  | `416` |  | `get {`
| 111 | `417` |  | `return version;`
|  | `418` |  | `}`
|  | `419` |  | ``
|  | `420` |  | `set {`
| 87 | `421` |  | `if (value == null) {`
| 1 | `422` |  | `throw new ArgumentNullException(nameof(value));`
|  | `423` |  | `}`
| 86 | `424` |  | `version = value;`
| 86 | `425` |  | `}`
|  | `426` |  | `}`
|  | `427` |  | ``
|  | `428` |  | ``
|  | `429` |  | `/// <summary>`
|  | `430` |  | `/// The entry's user name.`
|  | `431` |  | `/// </summary>`
|  | `432` |  | `public string UserName {`
| 111 | `433` |  | `get { return userName; }`
|  | `434` |  | `set {`
| 166 | `435` |  | `if (value != null) {`
| 81 | `436` |  | `userName = value.Substring(0, Math.Min(UNAMELEN, value.Length));`
| 81 | `437` |  | `} else {`
| 85 | `438` |  | `string currentUser = Environment.UserName;`
| 85 | `439` |  | `if (currentUser.Length > UNAMELEN) {`
| 0 | `440` |  | `currentUser = currentUser.Substring(0, UNAMELEN);`
|  | `441` |  | `}`
| 85 | `442` |  | `userName = currentUser;`
|  | `443` |  | `}`
| 85 | `444` |  | `}`
|  | `445` |  | `}`
|  | `446` |  | ``
|  | `447` |  | ``
|  | `448` |  | `/// <summary>`
|  | `449` |  | `/// Get/set the entry's group name.`
|  | `450` |  | `/// </summary>`
|  | `451` |  | `/// <remarks>`
|  | `452` |  | `/// This is only directly relevant to unix systems.`
|  | `453` |  | `/// </remarks>`
|  | `454` |  | `public string GroupName {`
| 110 | `455` |  | `get { return groupName; }`
|  | `456` |  | `set {`
| 166 | `457` |  | `if (value == null) {`
| 1 | `458` |  | `groupName = "None";`
| 1 | `459` |  | `} else {`
| 165 | `460` |  | `groupName = value;`
|  | `461` |  | `}`
| 165 | `462` |  | `}`
|  | `463` |  | `}`
|  | `464` |  | ``
|  | `465` |  | ``
|  | `466` |  | `/// <summary>`
|  | `467` |  | `/// Get/set the entry's major device number.`
|  | `468` |  | `/// </summary>`
|  | `469` |  | `public int DevMajor {`
| 36 | `470` |  | `get { return devMajor; }`
| 162 | `471` |  | `set { devMajor = value; }`
|  | `472` |  | `}`
|  | `473` |  | ``
|  | `474` |  | ``
|  | `475` |  | `/// <summary>`
|  | `476` |  | `/// Get/set the entry's minor device number.`
|  | `477` |  | `/// </summary>`
|  | `478` |  | `public int DevMinor {`
| 34 | `479` |  | `get { return devMinor; }`
| 162 | `480` |  | `set { devMinor = value; }`
|  | `481` |  | `}`
|  | `482` |  | ``
|  | `483` |  | `#endregion`
|  | `484` |  | ``
|  | `485` |  | `#region ICloneable Members`
|  | `486` |  | `/// <summary>`
|  | `487` |  | `/// Create a new <see cref="TarHeader"/> that is a copy of the current instance.`
|  | `488` |  | `/// </summary>`
|  | `489` |  | `/// <returns>A new <see cref="Object"/> that is a copy of the current instance.</returns>`
|  | `490` |  | `public object Clone()`
|  | `491` |  | `{`
| 2 | `492` |  | `return MemberwiseClone();`
|  | `493` |  | `}`
|  | `494` |  | `#endregion`
|  | `495` |  | ``
|  | `496` |  | `/// <summary>`
|  | `497` |  | `/// Parse TarHeader information from a header buffer.`
|  | `498` |  | `/// </summary>`
|  | `499` |  | `/// <param name = "header">`
|  | `500` |  | `/// The tar entry header buffer to get information from.`
|  | `501` |  | `/// </param>`
|  | `502` |  | `public void ParseBuffer(byte[] header)`
|  | `503` |  | `{`
| 3 | `504` |  | `if (header == null) {`
| 0 | `505` |  | `throw new ArgumentNullException(nameof(header));`
|  | `506` |  | `}`
|  | `507` |  | ``
| 3 | `508` |  | `int offset = 0;`
|  | `509` |  | ``
| 3 | `510` |  | `name = ParseName(header, offset, NAMELEN).ToString();`
| 3 | `511` |  | `offset += NAMELEN;`
|  | `512` |  | ``
| 3 | `513` |  | `mode = (int)ParseOctal(header, offset, MODELEN);`
| 3 | `514` |  | `offset += MODELEN;`
|  | `515` |  | ``
| 3 | `516` |  | `UserId = (int)ParseOctal(header, offset, UIDLEN);`
| 3 | `517` |  | `offset += UIDLEN;`
|  | `518` |  | ``
| 3 | `519` |  | `GroupId = (int)ParseOctal(header, offset, GIDLEN);`
| 3 | `520` |  | `offset += GIDLEN;`
|  | `521` |  | ``
| 3 | `522` |  | `Size = ParseBinaryOrOctal(header, offset, SIZELEN);`
| 3 | `523` |  | `offset += SIZELEN;`
|  | `524` |  | ``
| 3 | `525` |  | `ModTime = GetDateTimeFromCTime(ParseOctal(header, offset, MODTIMELEN));`
| 3 | `526` |  | `offset += MODTIMELEN;`
|  | `527` |  | ``
| 3 | `528` |  | `checksum = (int)ParseOctal(header, offset, CHKSUMLEN);`
| 3 | `529` |  | `offset += CHKSUMLEN;`
|  | `530` |  | ``
| 3 | `531` |  | `TypeFlag = header[offset++];`
|  | `532` |  | ``
| 3 | `533` |  | `LinkName = ParseName(header, offset, NAMELEN).ToString();`
| 3 | `534` |  | `offset += NAMELEN;`
|  | `535` |  | ``
| 3 | `536` |  | `Magic = ParseName(header, offset, MAGICLEN).ToString();`
| 3 | `537` |  | `offset += MAGICLEN;`
|  | `538` |  | ``
| 3 | `539` |  | `if (Magic == "ustar")`
|  | `540` |  | `{`
| 0 | `541` |  | `Version = ParseName(header, offset, VERSIONLEN).ToString();`
| 0 | `542` |  | `offset += VERSIONLEN;`
|  | `543` |  | ``
| 0 | `544` |  | `UserName = ParseName(header, offset, UNAMELEN).ToString();`
| 0 | `545` |  | `offset += UNAMELEN;`
|  | `546` |  | ``
| 0 | `547` |  | `GroupName = ParseName(header, offset, GNAMELEN).ToString();`
| 0 | `548` |  | `offset += GNAMELEN;`
|  | `549` |  | ``
| 0 | `550` |  | `DevMajor = (int) ParseOctal(header, offset, DEVLEN);`
| 0 | `551` |  | `offset += DEVLEN;`
|  | `552` |  | ``
| 0 | `553` |  | `DevMinor = (int) ParseOctal(header, offset, DEVLEN);`
| 0 | `554` |  | `offset += DEVLEN;`
|  | `555` |  | ``
| 0 | `556` |  | `string prefix = ParseName(header, offset, PREFIXLEN).ToString();`
| 0 | `557` |  | `if (!string.IsNullOrEmpty(prefix)) Name = prefix + '/' + Name;`
|  | `558` |  | `}`
|  | `559` |  | ``
| 3 | `560` |  | `isChecksumValid = Checksum == TarHeader.MakeCheckSum(header);`
| 3 | `561` |  | `}`
|  | `562` |  | ``
|  | `563` |  | `/// <summary>`
|  | `564` |  | `/// 'Write' header information to buffer provided, updating the <see cref="Checksum">check sum</see>.`
|  | `565` |  | `/// </summary>`
|  | `566` |  | `/// <param name="outBuffer">output buffer for header information</param>`
|  | `567` |  | `public void WriteHeader(byte[] outBuffer)`
|  | `568` |  | `{`
| 70 | `569` |  | `if (outBuffer == null) {`
| 0 | `570` |  | `throw new ArgumentNullException(nameof(outBuffer));`
|  | `571` |  | `}`
|  | `572` |  | ``
| 70 | `573` |  | `int offset = 0;`
|  | `574` |  | ``
| 70 | `575` |  | `offset = GetNameBytes(Name, outBuffer, offset, NAMELEN);`
| 70 | `576` |  | `offset = GetOctalBytes(mode, outBuffer, offset, MODELEN);`
| 70 | `577` |  | `offset = GetOctalBytes(UserId, outBuffer, offset, UIDLEN);`
| 70 | `578` |  | `offset = GetOctalBytes(GroupId, outBuffer, offset, GIDLEN);`
|  | `579` |  | ``
| 70 | `580` |  | `offset = GetBinaryOrOctalBytes(Size, outBuffer, offset, SIZELEN);`
| 70 | `581` |  | `offset = GetOctalBytes(GetCTime(ModTime), outBuffer, offset, MODTIMELEN);`
|  | `582` |  | ``
| 70 | `583` |  | `int csOffset = offset;`
| 1260 | `584` |  | `for (int c = 0; c < CHKSUMLEN; ++c) {`
| 560 | `585` |  | `outBuffer[offset++] = (byte)' ';`
|  | `586` |  | `}`
|  | `587` |  | ``
| 70 | `588` |  | `outBuffer[offset++] = TypeFlag;`
|  | `589` |  | ``
| 70 | `590` |  | `offset = GetNameBytes(LinkName, outBuffer, offset, NAMELEN);`
| 70 | `591` |  | `offset = GetAsciiBytes(Magic, 0, outBuffer, offset, MAGICLEN);`
| 70 | `592` |  | `offset = GetNameBytes(Version, outBuffer, offset, VERSIONLEN);`
| 70 | `593` |  | `offset = GetNameBytes(UserName, outBuffer, offset, UNAMELEN);`
| 70 | `594` |  | `offset = GetNameBytes(GroupName, outBuffer, offset, GNAMELEN);`
|  | `595` |  | ``
| 70 | `596` |  | `if ((TypeFlag == LF_CHR) || (TypeFlag == LF_BLK)) {`
| 0 | `597` |  | `offset = GetOctalBytes(DevMajor, outBuffer, offset, DEVLEN);`
| 0 | `598` |  | `offset = GetOctalBytes(DevMinor, outBuffer, offset, DEVLEN);`
|  | `599` |  | `}`
|  | `600` |  | ``
| 12880 | `601` |  | `for (; offset < outBuffer.Length;) {`
| 12810 | `602` |  | `outBuffer[offset++] = 0;`
|  | `603` |  | `}`
|  | `604` |  | ``
| 70 | `605` |  | `checksum = ComputeCheckSum(outBuffer);`
|  | `606` |  | ``
| 70 | `607` |  | `GetCheckSumOctalBytes(checksum, outBuffer, csOffset, CHKSUMLEN);`
| 70 | `608` |  | `isChecksumValid = true;`
| 70 | `609` |  | `}`
|  | `610` |  | ``
|  | `611` |  | `/// <summary>`
|  | `612` |  | `/// Get a hash code for the current object.`
|  | `613` |  | `/// </summary>`
|  | `614` |  | `/// <returns>A hash code for the current object.</returns>`
|  | `615` |  | `public override int GetHashCode()`
|  | `616` |  | `{`
| 0 | `617` |  | `return Name.GetHashCode();`
|  | `618` |  | `}`
|  | `619` |  | ``
|  | `620` |  | `/// <summary>`
|  | `621` |  | `/// Determines if this instance is equal to the specified object.`
|  | `622` |  | `/// </summary>`
|  | `623` |  | `/// <param name="obj">The object to compare with.</param>`
|  | `624` |  | `/// <returns>true if the objects are equal, false otherwise.</returns>`
|  | `625` |  | `public override bool Equals(object obj)`
|  | `626` |  | `{`
| 29 | `627` |  | `var localHeader = obj as TarHeader;`
|  | `628` |  | ``
|  | `629` |  | `bool result;`
| 29 | `630` |  | `if (localHeader != null) {`
| 29 | `631` |  | `result = (name == localHeader.name)`
| 29 | `632` |  | `&& (mode == localHeader.mode)`
| 29 | `633` |  | `&& (UserId == localHeader.UserId)`
| 29 | `634` |  | `&& (GroupId == localHeader.GroupId)`
| 29 | `635` |  | `&& (Size == localHeader.Size)`
| 29 | `636` |  | `&& (ModTime == localHeader.ModTime)`
| 29 | `637` |  | `&& (Checksum == localHeader.Checksum)`
| 29 | `638` |  | `&& (TypeFlag == localHeader.TypeFlag)`
| 29 | `639` |  | `&& (LinkName == localHeader.LinkName)`
| 29 | `640` |  | `&& (Magic == localHeader.Magic)`
| 29 | `641` |  | `&& (Version == localHeader.Version)`
| 29 | `642` |  | `&& (UserName == localHeader.UserName)`
| 29 | `643` |  | `&& (GroupName == localHeader.GroupName)`
| 29 | `644` |  | `&& (DevMajor == localHeader.DevMajor)`
| 29 | `645` |  | `&& (DevMinor == localHeader.DevMinor);`
| 29 | `646` |  | `} else {`
| 0 | `647` |  | `result = false;`
|  | `648` |  | `}`
| 29 | `649` |  | `return result;`
|  | `650` |  | `}`
|  | `651` |  | ``
|  | `652` |  | `/// <summary>`
|  | `653` |  | `/// Set defaults for values used when constructing a TarHeader instance.`
|  | `654` |  | `/// </summary>`
|  | `655` |  | `/// <param name="userId">Value to apply as a default for userId.</param>`
|  | `656` |  | `/// <param name="userName">Value to apply as a default for userName.</param>`
|  | `657` |  | `/// <param name="groupId">Value to apply as a default for groupId.</param>`
|  | `658` |  | `/// <param name="groupName">Value to apply as a default for groupName.</param>`
|  | `659` |  | `static internal void SetValueDefaults(int userId, string userName, int groupId, string groupName)`
|  | `660` |  | `{`
| 0 | `661` |  | `defaultUserId = userIdAsSet = userId;`
| 0 | `662` |  | `defaultUser = userNameAsSet = userName;`
| 0 | `663` |  | `defaultGroupId = groupIdAsSet = groupId;`
| 0 | `664` |  | `defaultGroupName = groupNameAsSet = groupName;`
| 0 | `665` |  | `}`
|  | `666` |  | ``
|  | `667` |  | `static internal void RestoreSetValues()`
|  | `668` |  | `{`
| 0 | `669` |  | `defaultUserId = userIdAsSet;`
| 0 | `670` |  | `defaultUser = userNameAsSet;`
| 0 | `671` |  | `defaultGroupId = groupIdAsSet;`
| 0 | `672` |  | `defaultGroupName = groupNameAsSet;`
| 0 | `673` |  | `}`
|  | `674` |  | ``
|  | `675` |  | `// Return value that may be stored in octal or binary. Length must exceed 8.`
|  | `676` |  | `//`
|  | `677` |  | `static private long ParseBinaryOrOctal(byte[] header, int offset, int length)`
|  | `678` |  | `{`
| 3 | `679` |  | `if (header[offset] >= 0x80) {`
|  | `680` |  | `// File sizes over 8GB are stored in 8 right-justified bytes of binary indicated by setting the high-order bit o`
| 0 | `681` |  | `long result = 0;`
| 0 | `682` |  | `for (int pos = length - 8; pos < length; pos++) {`
| 0 | `683` |  | `result = result << 8 | header[offset + pos];`
|  | `684` |  | `}`
| 0 | `685` |  | `return result;`
|  | `686` |  | `}`
| 3 | `687` |  | `return ParseOctal(header, offset, length);`
|  | `688` |  | `}`
|  | `689` |  | ``
|  | `690` |  | `/// <summary>`
|  | `691` |  | `/// Parse an octal string from a header buffer.`
|  | `692` |  | `/// </summary>`
|  | `693` |  | `/// <param name = "header">The header buffer from which to parse.</param>`
|  | `694` |  | `/// <param name = "offset">The offset into the buffer from which to parse.</param>`
|  | `695` |  | `/// <param name = "length">The number of header bytes to parse.</param>`
|  | `696` |  | `/// <returns>The long equivalent of the octal string.</returns>`
|  | `697` |  | `static public long ParseOctal(byte[] header, int offset, int length)`
|  | `698` |  | `{`
| 18 | `699` |  | `if (header == null) {`
| 0 | `700` |  | `throw new ArgumentNullException(nameof(header));`
|  | `701` |  | `}`
|  | `702` |  | ``
| 18 | `703` |  | `long result = 0;`
| 18 | `704` |  | `bool stillPadding = true;`
|  | `705` |  | ``
| 18 | `706` |  | `int end = offset + length;`
| 330 | `707` |  | `for (int i = offset; i < end; ++i) {`
| 165 | `708` |  | `if (header[i] == 0) {`
|  | `709` |  | `break;`
|  | `710` |  | `}`
|  | `711` |  | ``
| 147 | `712` |  | `if (header[i] == (byte)' ' || header[i] == '0') {`
| 102 | `713` |  | `if (stillPadding) {`
|  | `714` |  | `continue;`
|  | `715` |  | `}`
|  | `716` |  | ``
| 15 | `717` |  | `if (header[i] == (byte)' ') {`
|  | `718` |  | `break;`
|  | `719` |  | `}`
|  | `720` |  | `}`
|  | `721` |  | ``
| 60 | `722` |  | `stillPadding = false;`
|  | `723` |  | ``
| 60 | `724` |  | `result = (result << 3) + (header[i] - '0');`
|  | `725` |  | `}`
|  | `726` |  | ``
| 18 | `727` |  | `return result;`
|  | `728` |  | `}`
|  | `729` |  | ``
|  | `730` |  | `/// <summary>`
|  | `731` |  | `/// Parse a name from a header buffer.`
|  | `732` |  | `/// </summary>`
|  | `733` |  | `/// <param name="header">`
|  | `734` |  | `/// The header buffer from which to parse.`
|  | `735` |  | `/// </param>`
|  | `736` |  | `/// <param name="offset">`
|  | `737` |  | `/// The offset into the buffer from which to parse.`
|  | `738` |  | `/// </param>`
|  | `739` |  | `/// <param name="length">`
|  | `740` |  | `/// The number of header bytes to parse.`
|  | `741` |  | `/// </param>`
|  | `742` |  | `/// <returns>`
|  | `743` |  | `/// The name parsed.`
|  | `744` |  | `/// </returns>`
|  | `745` |  | `static public StringBuilder ParseName(byte[] header, int offset, int length)`
|  | `746` |  | `{`
| 9 | `747` |  | `if (header == null) {`
| 0 | `748` |  | `throw new ArgumentNullException(nameof(header));`
|  | `749` |  | `}`
|  | `750` |  | ``
| 9 | `751` |  | `if (offset < 0) {`
| 0 | `752` |  | `throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be less than zero");`
|  | `753` |  | `}`
|  | `754` |  | ``
| 9 | `755` |  | `if (length < 0) {`
| 0 | `756` |  | `throw new ArgumentOutOfRangeException(nameof(length), "Cannot be less than zero");`
|  | `757` |  | `}`
|  | `758` |  | ``
| 9 | `759` |  | `if (offset + length > header.Length) {`
| 0 | `760` |  | `throw new ArgumentException("Exceeds header size", nameof(length));`
|  | `761` |  | `}`
|  | `762` |  | ``
| 9 | `763` |  | `var result = new StringBuilder(length);`
|  | `764` |  | ``
| 108 | `765` |  | `for (int i = offset; i < offset + length; ++i) {`
| 51 | `766` |  | `if (header[i] == 0) {`
|  | `767` |  | `break;`
|  | `768` |  | `}`
| 45 | `769` |  | `result.Append((char)header[i]);`
|  | `770` |  | `}`
|  | `771` |  | ``
| 9 | `772` |  | `return result;`
|  | `773` |  | `}`
|  | `774` |  | ``
|  | `775` |  | `/// <summary>`
|  | `776` |  | `/// Add <paramref name="name">name</paramref> to the buffer as a collection of bytes`
|  | `777` |  | `/// </summary>`
|  | `778` |  | `/// <param name="name">The name to add</param>`
|  | `779` |  | `/// <param name="nameOffset">The offset of the first character</param>`
|  | `780` |  | `/// <param name="buffer">The buffer to add to</param>`
|  | `781` |  | `/// <param name="bufferOffset">The index of the first byte to add</param>`
|  | `782` |  | `/// <param name="length">The number of characters/bytes to add</param>`
|  | `783` |  | `/// <returns>The next free index in the <paramref name="buffer"/></returns>`
|  | `784` |  | `public static int GetNameBytes(StringBuilder name, int nameOffset, byte[] buffer, int bufferOffset, int length)`
|  | `785` |  | `{`
| 0 | `786` |  | `if (name == null) {`
| 0 | `787` |  | `throw new ArgumentNullException(nameof(name));`
|  | `788` |  | `}`
|  | `789` |  | ``
| 0 | `790` |  | `if (buffer == null) {`
| 0 | `791` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `792` |  | `}`
|  | `793` |  | ``
| 0 | `794` |  | `return GetNameBytes(name.ToString(), nameOffset, buffer, bufferOffset, length);`
|  | `795` |  | `}`
|  | `796` |  | ``
|  | `797` |  | `/// <summary>`
|  | `798` |  | `/// Add <paramref name="name">name</paramref> to the buffer as a collection of bytes`
|  | `799` |  | `/// </summary>`
|  | `800` |  | `/// <param name="name">The name to add</param>`
|  | `801` |  | `/// <param name="nameOffset">The offset of the first character</param>`
|  | `802` |  | `/// <param name="buffer">The buffer to add to</param>`
|  | `803` |  | `/// <param name="bufferOffset">The index of the first byte to add</param>`
|  | `804` |  | `/// <param name="length">The number of characters/bytes to add</param>`
|  | `805` |  | `/// <returns>The next free index in the <paramref name="buffer"/></returns>`
|  | `806` |  | `public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length)`
|  | `807` |  | `{`
| 350 | `808` |  | `if (name == null) {`
| 0 | `809` |  | `throw new ArgumentNullException(nameof(name));`
|  | `810` |  | `}`
|  | `811` |  | ``
| 350 | `812` |  | `if (buffer == null) {`
| 0 | `813` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `814` |  | `}`
|  | `815` |  | ``
|  | `816` |  | `int i;`
|  | `817` |  | ``
| 2100 | `818` |  | `for (i = 0 ; i < length && nameOffset + i < name.Length; ++i) {`
| 700 | `819` |  | `buffer[bufferOffset + i] = (byte)name[nameOffset + i];`
|  | `820` |  | `}`
|  | `821` |  | ``
| 36190 | `822` |  | `for (; i < length; ++i) {`
| 17920 | `823` |  | `buffer[bufferOffset + i] = 0;`
|  | `824` |  | `}`
|  | `825` |  | ``
| 350 | `826` |  | `return bufferOffset + length;`
|  | `827` |  | `}`
|  | `828` |  | ``
|  | `829` |  | `/// <summary>`
|  | `830` |  | `/// Add an entry name to the buffer`
|  | `831` |  | `/// </summary>`
|  | `832` |  | `/// <param name="name">`
|  | `833` |  | `/// The name to add`
|  | `834` |  | `/// </param>`
|  | `835` |  | `/// <param name="buffer">`
|  | `836` |  | `/// The buffer to add to`
|  | `837` |  | `/// </param>`
|  | `838` |  | `/// <param name="offset">`
|  | `839` |  | `/// The offset into the buffer from which to start adding`
|  | `840` |  | `/// </param>`
|  | `841` |  | `/// <param name="length">`
|  | `842` |  | `/// The number of header bytes to add`
|  | `843` |  | `/// </param>`
|  | `844` |  | `/// <returns>`
|  | `845` |  | `/// The index of the next free byte in the buffer`
|  | `846` |  | `/// </returns>`
|  | `847` |  | `public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, int length)`
|  | `848` |  | `{`
|  | `849` |  | ``
| 0 | `850` |  | `if (name == null) {`
| 0 | `851` |  | `throw new ArgumentNullException(nameof(name));`
|  | `852` |  | `}`
|  | `853` |  | ``
| 0 | `854` |  | `if (buffer == null) {`
| 0 | `855` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `856` |  | `}`
|  | `857` |  | ``
| 0 | `858` |  | `return GetNameBytes(name.ToString(), 0, buffer, offset, length);`
|  | `859` |  | `}`
|  | `860` |  | ``
|  | `861` |  | `/// <summary>`
|  | `862` |  | `/// Add an entry name to the buffer`
|  | `863` |  | `/// </summary>`
|  | `864` |  | `/// <param name="name">The name to add</param>`
|  | `865` |  | `/// <param name="buffer">The buffer to add to</param>`
|  | `866` |  | `/// <param name="offset">The offset into the buffer from which to start adding</param>`
|  | `867` |  | `/// <param name="length">The number of header bytes to add</param>`
|  | `868` |  | `/// <returns>The index of the next free byte in the buffer</returns>`
|  | `869` |  | `public static int GetNameBytes(string name, byte[] buffer, int offset, int length)`
|  | `870` |  | `{`
|  | `871` |  | ``
| 350 | `872` |  | `if (name == null) {`
| 0 | `873` |  | `throw new ArgumentNullException(nameof(name));`
|  | `874` |  | `}`
|  | `875` |  | ``
| 350 | `876` |  | `if (buffer == null) {`
| 0 | `877` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `878` |  | `}`
|  | `879` |  | ``
| 350 | `880` |  | `return GetNameBytes(name, 0, buffer, offset, length);`
|  | `881` |  | `}`
|  | `882` |  | ``
|  | `883` |  | `/// <summary>`
|  | `884` |  | `/// Add a string to a buffer as a collection of ascii bytes.`
|  | `885` |  | `/// </summary>`
|  | `886` |  | `/// <param name="toAdd">The string to add</param>`
|  | `887` |  | `/// <param name="nameOffset">The offset of the first character to add.</param>`
|  | `888` |  | `/// <param name="buffer">The buffer to add to.</param>`
|  | `889` |  | `/// <param name="bufferOffset">The offset to start adding at.</param>`
|  | `890` |  | `/// <param name="length">The number of ascii characters to add.</param>`
|  | `891` |  | `/// <returns>The next free index in the buffer.</returns>`
|  | `892` |  | `public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int bufferOffset, int length)`
|  | `893` |  | `{`
| 70 | `894` |  | `if (toAdd == null) {`
| 0 | `895` |  | `throw new ArgumentNullException(nameof(toAdd));`
|  | `896` |  | `}`
|  | `897` |  | ``
| 70 | `898` |  | `if (buffer == null) {`
| 0 | `899` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `900` |  | `}`
|  | `901` |  | ``
| 980 | `902` |  | `for (int i = 0; i < length && nameOffset + i < toAdd.Length; ++i) {`
| 420 | `903` |  | `buffer[bufferOffset + i] = (byte)toAdd[nameOffset + i];`
|  | `904` |  | `}`
| 70 | `905` |  | `return bufferOffset + length;`
|  | `906` |  | `}`
|  | `907` |  | ``
|  | `908` |  | `/// <summary>`
|  | `909` |  | `/// Put an octal representation of a value into a buffer`
|  | `910` |  | `/// </summary>`
|  | `911` |  | `/// <param name = "value">`
|  | `912` |  | `/// the value to be converted to octal`
|  | `913` |  | `/// </param>`
|  | `914` |  | `/// <param name = "buffer">`
|  | `915` |  | `/// buffer to store the octal string`
|  | `916` |  | `/// </param>`
|  | `917` |  | `/// <param name = "offset">`
|  | `918` |  | `/// The offset into the buffer where the value starts`
|  | `919` |  | `/// </param>`
|  | `920` |  | `/// <param name = "length">`
|  | `921` |  | `/// The length of the octal string to create`
|  | `922` |  | `/// </param>`
|  | `923` |  | `/// <returns>`
|  | `924` |  | `/// The offset of the character next byte after the octal string`
|  | `925` |  | `/// </returns>`
|  | `926` |  | `public static int GetOctalBytes(long value, byte[] buffer, int offset, int length)`
|  | `927` |  | `{`
| 420 | `928` |  | `if (buffer == null) {`
| 0 | `929` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `930` |  | `}`
|  | `931` |  | ``
| 420 | `932` |  | `int localIndex = length - 1;`
|  | `933` |  | ``
|  | `934` |  | `// Either a space or null is valid here. We use NULL as per GNUTar`
| 420 | `935` |  | `buffer[offset + localIndex] = 0;`
| 420 | `936` |  | `--localIndex;`
|  | `937` |  | ``
| 420 | `938` |  | `if (value > 0) {`
| 4218 | `939` |  | `for (long v = value; (localIndex >= 0) && (v > 0); --localIndex) {`
| 1831 | `940` |  | `buffer[offset + localIndex] = (byte)((byte)'0' + (byte)(v & 7));`
| 1831 | `941` |  | `v >>= 3;`
|  | `942` |  | `}`
|  | `943` |  | `}`
|  | `944` |  | ``
| 3618 | `945` |  | `for (; localIndex >= 0; --localIndex) {`
| 1599 | `946` |  | `buffer[offset + localIndex] = (byte)'0';`
|  | `947` |  | `}`
|  | `948` |  | ``
| 420 | `949` |  | `return offset + length;`
|  | `950` |  | `}`
|  | `951` |  | ``
|  | `952` |  | `/// <summary>`
|  | `953` |  | `/// Put an octal or binary representation of a value into a buffer`
|  | `954` |  | `/// </summary>`
|  | `955` |  | `/// <param name = "value">Value to be convert to octal</param>`
|  | `956` |  | `/// <param name = "buffer">The buffer to update</param>`
|  | `957` |  | `/// <param name = "offset">The offset into the buffer to store the value</param>`
|  | `958` |  | `/// <param name = "length">The length of the octal string. Must be 12.</param>`
|  | `959` |  | `/// <returns>Index of next byte</returns>`
|  | `960` |  | `private static int GetBinaryOrOctalBytes(long value, byte[] buffer, int offset, int length)`
|  | `961` |  | `{`
| 70 | `962` |  | `if (value > 0x1FFFFFFFF) { // Octal 77777777777 (11 digits)`
|  | `963` |  | `// Put value as binary, right-justified into the buffer. Set high order bit of left-most byte.`
| 0 | `964` |  | `for (int pos = length - 1; pos > 0; pos--) {`
| 0 | `965` |  | `buffer[offset + pos] = (byte)value;`
| 0 | `966` |  | `value = value >> 8;`
|  | `967` |  | `}`
| 0 | `968` |  | `buffer[offset] = 0x80;`
| 0 | `969` |  | `return offset + length;`
|  | `970` |  | `}`
| 70 | `971` |  | `return GetOctalBytes(value, buffer, offset, length);`
|  | `972` |  | `}`
|  | `973` |  | ``
|  | `974` |  | `/// <summary>`
|  | `975` |  | `/// Add the checksum integer to header buffer.`
|  | `976` |  | `/// </summary>`
|  | `977` |  | `/// <param name = "value"></param>`
|  | `978` |  | `/// <param name = "buffer">The header buffer to set the checksum for</param>`
|  | `979` |  | `/// <param name = "offset">The offset into the buffer for the checksum</param>`
|  | `980` |  | `/// <param name = "length">The number of header bytes to update.`
|  | `981` |  | `/// It's formatted differently from the other fields: it has 6 digits, a`
|  | `982` |  | `/// null, then a space -- rather than digits, a space, then a null.`
|  | `983` |  | `/// The final space is already there, from checksumming`
|  | `984` |  | `/// </param>`
|  | `985` |  | `/// <returns>The modified buffer offset</returns>`
|  | `986` |  | `static void GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length)`
|  | `987` |  | `{`
| 70 | `988` |  | `GetOctalBytes(value, buffer, offset, length - 1);`
| 70 | `989` |  | `}`
|  | `990` |  | ``
|  | `991` |  | `/// <summary>`
|  | `992` |  | `/// Compute the checksum for a tar entry header.`
|  | `993` |  | `/// The checksum field must be all spaces prior to this happening`
|  | `994` |  | `/// </summary>`
|  | `995` |  | `/// <param name = "buffer">The tar entry's header buffer.</param>`
|  | `996` |  | `/// <returns>The computed checksum.</returns>`
|  | `997` |  | `static int ComputeCheckSum(byte[] buffer)`
|  | `998` |  | `{`
| 70 | `999` |  | `int sum = 0;`
| 71820 | `1000` |  | `for (int i = 0; i < buffer.Length; ++i) {`
| 35840 | `1001` |  | `sum += buffer[i];`
|  | `1002` |  | `}`
| 70 | `1003` |  | `return sum;`
|  | `1004` |  | `}`
|  | `1005` |  | ``
|  | `1006` |  | `/// <summary>`
|  | `1007` |  | `/// Make a checksum for a tar entry ignoring the checksum contents.`
|  | `1008` |  | `/// </summary>`
|  | `1009` |  | `/// <param name = "buffer">The tar entry's header buffer.</param>`
|  | `1010` |  | `/// <returns>The checksum for the buffer</returns>`
|  | `1011` |  | `static int MakeCheckSum(byte[] buffer)`
|  | `1012` |  | `{`
| 3 | `1013` |  | `int sum = 0;`
| 894 | `1014` |  | `for (int i = 0; i < CHKSUMOFS; ++i) {`
| 444 | `1015` |  | `sum += buffer[i];`
|  | `1016` |  | `}`
|  | `1017` |  | ``
| 54 | `1018` |  | `for (int i = 0; i < CHKSUMLEN; ++i) {`
| 24 | `1019` |  | `sum += (byte)' ';`
|  | `1020` |  | `}`
|  | `1021` |  | ``
| 2142 | `1022` |  | `for (int i = CHKSUMOFS + CHKSUMLEN; i < buffer.Length; ++i) {`
| 1068 | `1023` |  | `sum += buffer[i];`
|  | `1024` |  | `}`
| 3 | `1025` |  | `return sum;`
|  | `1026` |  | `}`
|  | `1027` |  | ``
|  | `1028` |  | `static int GetCTime(DateTime dateTime)`
|  | `1029` |  | `{`
| 70 | `1030` |  | `return unchecked((int)((dateTime.Ticks - dateTime1970.Ticks) / timeConversionFactor));`
|  | `1031` |  | `}`
|  | `1032` |  | ``
|  | `1033` |  | `static DateTime GetDateTimeFromCTime(long ticks)`
|  | `1034` |  | `{`
|  | `1035` |  | `DateTime result;`
|  | `1036` |  | ``
|  | `1037` |  | `try {`
| 3 | `1038` |  | `result = new DateTime(dateTime1970.Ticks + ticks * timeConversionFactor);`
| 3 | `1039` |  | `} catch (ArgumentOutOfRangeException) {`
| 0 | `1040` |  | `result = dateTime1970;`
| 0 | `1041` |  | `}`
| 3 | `1042` |  | `return result;`
|  | `1043` |  | `}`
|  | `1044` |  | ``
|  | `1045` |  | `#region Instance Fields`
|  | `1046` |  | `string name;`
|  | `1047` |  | `int mode;`
|  | `1048` |  | `int userId;`
|  | `1049` |  | `int groupId;`
|  | `1050` |  | `long size;`
|  | `1051` |  | `DateTime modTime;`
|  | `1052` |  | `int checksum;`
|  | `1053` |  | `bool isChecksumValid;`
|  | `1054` |  | `byte typeFlag;`
|  | `1055` |  | `string linkName;`
|  | `1056` |  | `string magic;`
|  | `1057` |  | `string version;`
|  | `1058` |  | `string userName;`
|  | `1059` |  | `string groupName;`
|  | `1060` |  | `int devMajor;`
|  | `1061` |  | `int devMinor;`
|  | `1062` |  | `#endregion`
|  | `1063` |  | ``
|  | `1064` |  | `#region Class Fields`
|  | `1065` |  | `// Values used during recursive operations.`
|  | `1066` |  | `static internal int userIdAsSet;`
|  | `1067` |  | `static internal int groupIdAsSet;`
|  | `1068` |  | `static internal string userNameAsSet;`
| 1 | `1069` |  | `static internal string groupNameAsSet = "None";`
|  | `1070` |  | ``
|  | `1071` |  | `static internal int defaultUserId;`
|  | `1072` |  | `static internal int defaultGroupId;`
| 1 | `1073` |  | `static internal string defaultGroupName = "None";`
|  | `1074` |  | `static internal string defaultUser;`
|  | `1075` |  | `#endregion`
|  | `1076` |  | `}`
|  | `1077` |  | `}`