Пример #1
0
        public Stream Open()
        {
            if (this.Archive.AccessMode == StreamAccessMode.Sequential)
            {
                Stream output = this.stream;
                this.stream = null;

                if (output == null)
                {
                    throw new IOException("The entry is currently open or has been closed. It cannot be reopened.");
                }
                else
                {
                    return(output);
                }
            }
            else if (this.Archive.AccessMode == StreamAccessMode.Random)
            {
                return(Archive.BlockManager.OpenStream(index));
            }
            else
            {
                throw new NotImplementedException("Unknown access mode");
            }
        }
Пример #2
0
        internal Stream OpenStream(int index)
        {
            lock (this)
            {
                if (index < 0 || index >= this.realEntries.Count)
                {
                    throw new ArgumentOutOfRangeException("index");
                }

                TarIOEntry entry = realEntries[index];

                if (entry.Stream != null && entry.Stream.Closed)
                {
                    throw new InvalidOperationException(
                              "A stream for the requested resouce is already open");
                }
                else
                {
                    var @return = new TarIOFileItemStream(entry.Offset, entry.Length, this);
                    realEntries[index].Stream = @return;

                    return(@return);
                }
            }
        }
Пример #3
0
        internal void SaveEntry(TarIOFileItemStream stream)
        {
            lock (this)
            {
                // Alloc space
                long dataLength  = stream.Length - stream.PhysicalLength;         // Length of suffix
                long allocLength = (dataLength + BLOCK_SIZE - 1) & (-BLOCK_SIZE); // Block-adjusted length of suffix

                if (dataLength == 0)
                {
                    return;                                      // Skip if all data is already in the stream
                }
                if (allocLength == 0)
                {
                    allocLength = BLOCK_SIZE;                    // If dataLength < BLOCK_SIZE, round alloc length to BLOCK_SIZE
                }
                // Make space for the new data
                Move(stream.Offset + stream.PhysicalLength, allocLength);

                // Save stream
                stream.SaveToPhysical();

                // Update positions
                foreach (TarIOEntry entry in realEntries)
                {
                    if (entry.Offset > stream.Offset)
                    {
                        entry.Offset += allocLength;
                    }
                    else if (f.Item1 == stream.Offset)
                    {
                        f.Item2 += dataLength;
                    }
                }
            }
        }
Пример #4
0
 internal TarArchiveEntry(TarArchive archive, TarIOFileHeader header, TarIOFileItemStream stream)
     : this(archive, header)
 {
     this.stream = stream;
 }