/// <summary> /// Put an entry on the output stream. This writes the entry's /// header and positions the output stream for writing /// the contents of the entry. Once this method is called, the /// stream is ready for calls to write() to write the entry's /// contents. Once the contents are written, closeEntry() /// <B>MUST</B> be called to ensure that all buffered data /// is completely written to the output stream. /// </summary> /// <param name="entry"> /// The TarEntry to be written to the archive. /// </param> public void PutNextEntry(TarEntry entry) { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } var namelen = nameEncoding != null?nameEncoding.GetByteCount(entry.TarHeader.Name) : entry.TarHeader.Name.Length; if (namelen > TarHeader.NAMELEN) { var longHeader = new TarHeader(); longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.Name = longHeader.Name + "././@LongLink"; longHeader.Mode = 420; //644 by default longHeader.UserId = entry.UserId; longHeader.GroupId = entry.GroupId; longHeader.GroupName = entry.GroupName; longHeader.UserName = entry.UserName; longHeader.LinkName = ""; longHeader.Size = namelen + 1; // Plus one to avoid dropping last char longHeader.WriteHeader(blockBuffer, nameEncoding); buffer.WriteBlock(blockBuffer); // Add special long filename header block int nameCharIndex = 0; while (nameCharIndex < namelen + 1 /* we've allocated one for the null char, now we must make sure it gets written out */) { Array.Clear(blockBuffer, 0, blockBuffer.Length); TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize, nameEncoding); // This func handles OK the extra char out of string length nameCharIndex += TarBuffer.BlockSize; buffer.WriteBlock(blockBuffer); } } entry.WriteEntryHeader(blockBuffer, nameEncoding); buffer.WriteBlock(blockBuffer); currBytes = 0; currSize = entry.IsDirectory ? 0 : entry.Size; }
/// <summary> /// Put an entry on the output stream. This writes the entry's /// header and positions the output stream for writing /// the contents of the entry. Once this method is called, the /// stream is ready for calls to write() to write the entry's /// contents. Once the contents are written, closeEntry() /// <B>MUST</B> be called to ensure that all buffered data /// is completely written to the output stream. /// </summary> /// <param name="entry"> /// The TarEntry to be written to the archive. /// </param> public void PutNextEntry(TarEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entry.TarHeader.Name.Length >= TarHeader.NAMELEN) { TarHeader longHeader = new TarHeader(); longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.Name = longHeader.Name + "././@LongLink"; longHeader.UserId = 0; longHeader.GroupId = 0; longHeader.GroupName = ""; longHeader.UserName = ""; longHeader.LinkName = ""; longHeader.Size = entry.TarHeader.Name.Length; longHeader.WriteHeader(blockBuffer); buffer.WriteBlock(blockBuffer); // Add special long filename header block int nameCharIndex = 0; while (nameCharIndex < entry.TarHeader.Name.Length) { Array.Clear(blockBuffer, 0, blockBuffer.Length); TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize); nameCharIndex += TarBuffer.BlockSize; buffer.WriteBlock(blockBuffer); } } entry.WriteEntryHeader(blockBuffer); buffer.WriteBlock(blockBuffer); currBytes = 0; currSize = entry.IsDirectory ? 0 : entry.Size; }