tarheader.cs
来自「全功能c#编译器」· CS 代码 · 共 769 行 · 第 1/2 页
CS
769 行
hdr.version = (this.version == null) ? null : new StringBuilder(this.version.ToString());
hdr.userName = (this.userName == null) ? null : new StringBuilder(this.userName.ToString());
hdr.groupName = (this.groupName == null) ? null : new StringBuilder(this.groupName.ToString());
hdr.devMajor = this.devMajor;
hdr.devMinor = this.devMinor;
return hdr;
}
/// <summary>
/// Get the name of this entry.
/// </summary>
/// <returns>
/// The entry's name.
/// </returns>
public string GetName()
{
return this.name.ToString();
}
/// <summary>
/// Parse an octal string from a header buffer. This is used for the
/// file permission mode value.
/// </summary>
/// <param name = "header">
/// The header buffer from which to parse.
/// </param>
/// <param name = "offset">
/// The offset into the buffer from which to parse.
/// </param>
/// <param name = "length">
/// The number of header bytes to parse.
/// </param>
/// <returns>
/// The long value of the octal string.
/// </returns>
public static long ParseOctal(byte[] header, int offset, int length)
{
long result = 0;
bool stillPadding = true;
int end = offset + length;
for (int i = offset; i < end ; ++i) {
if (header[i] == 0) {
break;
}
if (header[i] == (byte)' ' || header[i] == '0') {
if (stillPadding) {
continue;
}
if (header[i] == (byte)' ') {
break;
}
}
stillPadding = false;
result = (result << 3) + (header[i] - '0');
}
return result;
}
/// <summary>
/// Parse an entry name from a header buffer.
/// </summary>
/// <param name="header">
/// The header buffer from which to parse.
/// </param>
/// <param name="offset">
/// The offset into the buffer from which to parse.
/// </param>
/// <param name="length">
/// The number of header bytes to parse.
/// </param>
/// <returns>
/// The header's entry name.
/// </returns>
public static StringBuilder ParseName(byte[] header, int offset, int length)
{
StringBuilder result = new StringBuilder(length);
for (int i = offset; i < offset + length; ++i) {
if (header[i] == 0) {
break;
}
result.Append((char)header[i]);
}
return result;
}
/// <summary>
/// Add <paramref name="name">name</paramref> to the buffer as a collection of bytes
/// </summary>
/// <param name="name">the name to add</param>
/// <param name="nameOffset">the offset of the first character</param>
/// <param name="buf">the buffer to add to</param>
/// <param name="bufferOffset">the index of the first byte to add</param>
/// <param name="length">the number of characters/bytes to add</param>
/// <returns>the next free index in the <paramref name="buf">buffer</paramref></returns>
public static int GetNameBytes(StringBuilder name, int nameOffset, byte[] buf, int bufferOffset, int length)
{
int i;
for (i = 0 ; i < length && nameOffset + i < name.Length; ++i) {
buf[bufferOffset + i] = (byte)name[nameOffset + i];
}
for (; i < length ; ++i) {
buf[bufferOffset + i] = 0;
}
return bufferOffset + length;
}
/// <summary>
/// Add an entry name to the buffer
/// </summary>
/// <param name="name">
/// The name to add
/// </param>
/// <param name="buf">
/// The buffer to add to
/// </param>
/// <param name="offset">
/// The offset into the buffer from which to start adding
/// </param>
/// <param name="length">
/// The number of header bytes to add
/// </param>
/// <returns>
/// The index of the next free byte in the buffer
/// </returns>
public static int GetNameBytes(StringBuilder name, byte[] buf, int offset, int length)
{
return GetNameBytes(name, 0, buf, offset, length);
}
/// <summary>
/// Put an octal representation of a value into a buffer
/// </summary>
/// <param name = "val">
/// the value to be converted to octal
/// </param>
/// <param name = "buf">
/// buffer to store the octal string
/// </param>
/// <param name = "offset">
/// The offset into the buffer where the value starts
/// </param>
/// <param name = "length">
/// The length of the octal string to create
/// </param>
/// <returns>
/// The offset of the character next byte after the octal string
/// </returns>
public static int GetOctalBytes(long val, byte[] buf, int offset, int length)
{
int idx = length - 1;
// Either a space or null is valid here. We use NULL as per GNUTar
buf[offset + idx] = 0;
--idx;
if (val > 0) {
for (long v = val; idx >= 0 && v > 0; --idx) {
buf[offset + idx] = (byte)((byte)'0' + (byte)(v & 7));
v >>= 3;
}
}
for (; idx >= 0; --idx) {
buf[offset + idx] = (byte)'0';
}
return offset + length;
}
/// <summary>
/// Put an octal representation of a value into a buffer
/// </summary>
/// <param name = "val">
/// Value to be convert to octal
/// </param>
/// <param name = "buf">
/// The buffer to update
/// </param>
/// <param name = "offset">
/// The offset into the buffer to store the value
/// </param>
/// <param name = "length">
/// The length of the octal string
/// </param>
/// <returns>
/// Index of next byte
/// </returns>
public static int GetLongOctalBytes(long val, byte[] buf, int offset, int length)
{
return GetOctalBytes(val, buf, offset, length);
}
/// <summary>
/// Add the checksum octal integer to header buffer.
/// </summary>
/// <param name = "val">
/// </param>
/// <param name = "buf">
/// The header buffer to set the checksum for
/// </param>
/// <param name = "offset">
/// The offset into the buffer for the checksum
/// </param>
/// <param name = "length">
/// The number of header bytes to update.
/// It's formatted differently from the other fields: it has 6 digits, a
/// null, then a space -- rather than digits, a space, then a null.
/// The final space is already there, from checksumming
/// </param>
/// <returns>
/// The modified buffer offset
/// </returns>
private static int GetCheckSumOctalBytes(long val, byte[] buf, int offset, int length)
{
TarHeader.GetOctalBytes(val, buf, offset, length - 1);
// buf[offset + length - 1] = (byte)' '; -jr- 23-Jan-2004 this causes failure!!!
// buf[offset + length - 2] = 0;
return offset + length;
}
/// <summary>
/// Compute the checksum for a tar entry header.
/// The checksum field must be all spaces prior to this happening
/// </summary>
/// <param name = "buf">
/// The tar entry's header buffer.
/// </param>
/// <returns>
/// The computed checksum.
/// </returns>
private static long ComputeCheckSum(byte[] buf)
{
long sum = 0;
for (int i = 0; i < buf.Length; ++i) {
sum += buf[i];
}
return sum;
}
readonly static long timeConversionFactor = 10000000L; // -jr- 1 tick == 100 nanoseconds
readonly static DateTime datetTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
// readonly static DateTime datetTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToUniversalTime(); // -jr- Should be UTC? doesnt match Gnutar if this is so though, why?
static int GetCTime(System.DateTime dateTime)
{
return (int)((dateTime.Ticks - datetTime1970.Ticks) / timeConversionFactor);
}
static DateTime GetDateTimeFromCTime(long ticks)
{
return new DateTime(datetTime1970.Ticks + ticks * timeConversionFactor);
}
/// <summary>
/// Parse TarHeader information from a header buffer.
/// </summary>
/// <param name = "header">
/// The tar entry header buffer to get information from.
/// </param>
public void ParseBuffer(byte[] header)
{
int offset = 0;
name = TarHeader.ParseName(header, offset, TarHeader.NAMELEN);
offset += TarHeader.NAMELEN;
mode = (int)TarHeader.ParseOctal(header, offset, TarHeader.MODELEN);
offset += TarHeader.MODELEN;
userId = (int)TarHeader.ParseOctal(header, offset, TarHeader.UIDLEN);
offset += TarHeader.UIDLEN;
groupId = (int)TarHeader.ParseOctal(header, offset, TarHeader.GIDLEN);
offset += TarHeader.GIDLEN;
size = TarHeader.ParseOctal(header, offset, TarHeader.SIZELEN);
offset += TarHeader.SIZELEN;
modTime = GetDateTimeFromCTime(TarHeader.ParseOctal(header, offset, TarHeader.MODTIMELEN));
offset += TarHeader.MODTIMELEN;
checkSum = (int)TarHeader.ParseOctal(header, offset, TarHeader.CHKSUMLEN);
offset += TarHeader.CHKSUMLEN;
typeFlag = header[ offset++ ];
linkName = TarHeader.ParseName(header, offset, TarHeader.NAMELEN);
offset += TarHeader.NAMELEN;
magic = TarHeader.ParseName(header, offset, TarHeader.MAGICLEN);
offset += TarHeader.MAGICLEN;
version = TarHeader.ParseName(header, offset, TarHeader.VERSIONLEN);
offset += TarHeader.VERSIONLEN;
userName = TarHeader.ParseName(header, offset, TarHeader.UNAMELEN);
offset += TarHeader.UNAMELEN;
groupName = TarHeader.ParseName(header, offset, TarHeader.GNAMELEN);
offset += TarHeader.GNAMELEN;
devMajor = (int)TarHeader.ParseOctal(header, offset, TarHeader.DEVLEN);
offset += TarHeader.DEVLEN;
devMinor = (int)TarHeader.ParseOctal(header, offset, TarHeader.DEVLEN);
// Fields past this point not currently parsed or used...
}
/// <summary>
/// 'Write' header information to buffer provided
/// </summary>
/// <param name="outbuf">output buffer for header information</param>
public void WriteHeader(byte[] outbuf)
{
int offset = 0;
offset = GetNameBytes(this.name, outbuf, offset, TarHeader.NAMELEN);
offset = GetOctalBytes(this.mode, outbuf, offset, TarHeader.MODELEN);
offset = GetOctalBytes(this.userId, outbuf, offset, TarHeader.UIDLEN);
offset = GetOctalBytes(this.groupId, outbuf, offset, TarHeader.GIDLEN);
long size = this.size;
offset = GetLongOctalBytes(size, outbuf, offset, TarHeader.SIZELEN);
offset = GetLongOctalBytes(GetCTime(this.modTime), outbuf, offset, TarHeader.MODTIMELEN);
int csOffset = offset;
for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) {
outbuf[offset++] = (byte)' ';
}
outbuf[offset++] = this.typeFlag;
offset = GetNameBytes(this.linkName, outbuf, offset, NAMELEN);
offset = GetNameBytes(this.magic, outbuf, offset, MAGICLEN);
offset = GetNameBytes(this.version, outbuf, offset, VERSIONLEN);
offset = GetNameBytes(this.userName, outbuf, offset, UNAMELEN);
offset = GetNameBytes(this.groupName, outbuf, offset, GNAMELEN);
if (this.typeFlag == LF_CHR || this.typeFlag == LF_BLK) {
offset = GetOctalBytes(this.devMajor, outbuf, offset, DEVLEN);
offset = GetOctalBytes(this.devMinor, outbuf, offset, DEVLEN);
}
for ( ; offset < outbuf.Length; ) {
outbuf[offset++] = 0;
}
long checkSum = ComputeCheckSum(outbuf);
GetCheckSumOctalBytes(checkSum, outbuf, csOffset, CHKSUMLEN);
}
}
}
/* The original Java file had this header:
*
** Authored by Timothy Gerard Endres
** <mailto:time@gjt.org> <http://www.trustice.com>
**
** This work has been placed into the public domain.
** You may use this work in any way and for any purpose you wish.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?