using System.Collections.Generic; using System.Text; namespace ICSharpCode.SharpZipLib.Tar { /// /// Reads the extended header of a Tar stream /// public class TarExtendedHeaderReader { private const byte LENGTH = 0; private const byte KEY = 1; private const byte VALUE = 2; private const byte END = 3; private readonly Dictionary headers = new Dictionary(); private string[] headerParts = new string[3]; private int bbIndex; private byte[] byteBuffer; private char[] charBuffer; private readonly StringBuilder sb = new StringBuilder(); private readonly Decoder decoder = Encoding.UTF8.GetDecoder(); private int state = LENGTH; private static readonly byte[] StateNext = new[] { (byte)' ', (byte)'=', (byte)'\n' }; /// /// Creates a new . /// public TarExtendedHeaderReader() { ResetBuffers(); } /// /// Read bytes from /// /// /// public void Read(byte[] buffer, int length) { for (int i = 0; i < length; i++) { byte next = buffer[i]; if (next == StateNext[state]) { Flush(); headerParts[state] = sb.ToString(); sb.Clear(); if (++state == END) { headers.Add(headerParts[KEY], headerParts[VALUE]); headerParts = new string[3]; state = LENGTH; } } else { byteBuffer[bbIndex++] = next; if (bbIndex == 4) Flush(); } } } private void Flush() { decoder.Convert(byteBuffer, 0, bbIndex, charBuffer, 0, 4, false, out int bytesUsed, out int charsUsed, out bool completed); sb.Append(charBuffer, 0, charsUsed); ResetBuffers(); } private void ResetBuffers() { charBuffer = new char[4]; byteBuffer = new byte[4]; bbIndex = 0; } /// /// Returns the parsed headers as key-value strings /// public Dictionary Headers { get { // TODO: Check for invalid state? -NM 2018-07-01 return headers; } } } }