Пример #1
0
        protected virtual BlockingStream GetTarStream(IAsset asset)
        {
            const int      chunk          = 4096;
            BlockingStream blockingStream = new BlockingStream(1000);

            asset.GetStreamable().GetStreamAsync()
            .ContinueWith(task =>
            {
                var stream = task.GetAwaiter().GetResult();
                Task.Factory.StartNew(() =>
                {
                    int read;
                    var buffer = new byte[chunk];
                    do
                    {
                        read = stream.Read(buffer, 0, chunk);
                        blockingStream.Write(buffer, 0, read);
                    } while (read == chunk);
                    blockingStream.Close();
                });
            });
            return(blockingStream);
        }
Пример #2
0
        /// <summary>
        /// Extractes a <c>tar</c> archive to the specified directory.
        /// </summary>
        /// <param name="tarStream">The <i>.tar</i> to extract.</param>
        /// <param name="outputDir">Output directory to write the files.</param>
        public Task <IDictionary <string, IAsset> > ExtractTar(Stream tarStream, Func <TarEntryAsset, IDestination, CarrierManager, Task <IAsset> > tarEntryAction, IDestination destination, CarrierManager carrierManager)
        {
            Dictionary <string, IAsset> extractedAssets = new Dictionary <string, IAsset>();
            string longLink = null;

            while (true)
            {
                var buffer = new byte[100];
                tarStream.Read(buffer, 0, 100);
                var name = Encoding.ASCII.GetString(buffer);
                if (name.IndexOf('\0') >= 0)
                {
                    name = name.Substring(0, name.IndexOf('\0'));
                }
                if (String.IsNullOrWhiteSpace(name))
                {
                    break;
                }
                buffer = new byte[24];
                tarStream.Read(buffer, 0, 24);
                buffer = new byte[12];
                tarStream.Read(buffer, 0, 12);
                string sizestr = Encoding.UTF8.GetString(buffer, 0, 12).Trim('\0').Trim();
                int    size    = 0;
                if (!string.IsNullOrEmpty(sizestr))
                {
                    size = Convert.ToInt32(sizestr, 8);
                }
                buffer = new byte[376];
                tarStream.Read(buffer, 0, 376);

                if (longLink != null)
                {
                    name     = longLink;
                    longLink = null;
                }

                if (name.Contains("@LongLink"))
                {
                    buffer = new byte[size];
                    tarStream.Read(buffer, 0, size);
                    longLink = Encoding.ASCII.GetString(buffer);
                    longLink = longLink.Substring(0, longLink.IndexOf('\0'));
                    size     = 0;
                }

                if (size > 0)
                {
                    BlockingStream blockingStream = new BlockingStream(Convert.ToUInt64(size));

                    TarEntryAsset tarEntryAsset = new TarEntryAsset(name, Convert.ToUInt64(size), blockingStream);

                    const int chunk       = 81920;
                    long      totalRead   = 0;
                    var       extractTask = Task.Factory.StartNew((state) =>
                    {
                        int chunkSize = chunk;
                        int read      = 0;
                        if (size < chunk)
                        {
                            chunkSize = Convert.ToInt32(size);
                        }
                        var buffer = new byte[chunk];
                        do
                        {
                            try
                            {
                                read = tarStream.Read(buffer, 0, chunkSize);
                                blockingStream.Write(buffer, 0, read);
                            }
                            catch (Exception e)
                            {
                                logger.LogWarning(e.Message);
                            }
                            totalRead += read;
                            if (size < (totalRead + chunk))
                            {
                                chunkSize = Convert.ToInt32(size - totalRead);
                            }
                            buffer = new byte[chunk];
                        } while (totalRead < size);
                        blockingStream.Close();
                    }, null, TaskCreationOptions.AttachedToParent);

                    extractedAssets.Add(name, tarEntryAction(tarEntryAsset, destination, carrierManager).GetAwaiter().GetResult());

                    if (!extractTask.IsCompleted)
                    {
                        // Read until the end of the entry
                        blockingStream.CopyTo(Stream.Null);
                    }
                }

                var pos = tarStream.Position;

                int offset = Convert.ToInt32(512 - (pos % 512));
                if (offset == 512)
                {
                    offset = 0;
                }

                if (offset > 0)
                {
                    var offsetBuf = new byte[offset];
                    tarStream.Read(offsetBuf, 0, offset);
                }
            }
            return(Task.FromResult <IDictionary <string, IAsset> >(extractedAssets));
        }