Ejemplo n.º 1
0
        private Stream CacheAndCreateEntryStream(string filename, string entryName)
        {
            Stream stream     = null;
            var    dataStream = _dataProvider.Fetch(filename);

            if (dataStream != null)
            {
                try
                {
                    var newItem = new CachedZipFile(dataStream, DateTime.UtcNow, filename);

                    // here we don't need to lock over the cache item
                    // because it was still not added in the cache
                    stream = CreateEntryStream(newItem, entryName, filename);

                    if (!_zipFileCache.TryAdd(filename, newItem))
                    {
                        // some other thread could of added it already, lets dispose ours
                        newItem.Dispose();
                    }
                }
                catch (Exception exception)
                {
                    if (exception is ZipException || exception is ZlibException)
                    {
                        Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            return(stream);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a stream of a specific ZipEntry
        /// </summary>
        /// <param name="zipFile">The zipFile containing the zipEntry</param>
        /// <param name="entryName">The name of the entry</param>
        /// <param name="fileName">The name of the zip file on disk</param>
        /// <returns>A <see cref="Stream"/> of the appropriate zip entry</returns>
        private Stream CreateEntryStream(CachedZipFile zipFile, string entryName, string fileName)
        {
            ZipEntryCache entryCache;

            if (entryName == null)
            {
                entryCache = zipFile.EntryCache.FirstOrDefault().Value;
            }
            else
            {
                zipFile.EntryCache.TryGetValue(entryName, out entryCache);
            }

            if (entryCache is { Modified : true })
Ejemplo n.º 3
0
        /// <summary>
        /// Cache a Zip
        /// </summary>
        /// <param name="filename">Zip to cache</param>
        /// <param name="cachedZip">The resulting CachedZipFile</param>
        /// <returns></returns>
        private bool Cache(string filename, out CachedZipFile cachedZip)
        {
            cachedZip = null;
            var dataStream = _dataProvider.Fetch(filename);

            if (dataStream != null)
            {
                try
                {
                    cachedZip = new CachedZipFile(dataStream, DateTime.UtcNow, filename);

                    if (!_zipFileCache.TryAdd(filename, cachedZip))
                    {
                        // some other thread could of added it already, lets dispose ours
                        cachedZip.Dispose();
                        return(_zipFileCache.TryGetValue(filename, out cachedZip));
                    }

                    return(true);
                }
                catch (Exception exception)
                {
                    if (exception is ZipException || exception is ZlibException)
                    {
                        Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + " Error: " + exception);
                    }
                    else
                    {
                        throw;
                    }
                }

                dataStream.Dispose();
            }

            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Does not attempt to retrieve any data
        /// </summary>
        public Stream Fetch(string key)
        {
            string entryName = null; // default to all entries
            var    filename  = key;
            var    hashIndex = key.LastIndexOf("#", StringComparison.Ordinal);

            if (hashIndex != -1)
            {
                entryName = key.Substring(hashIndex + 1);
                filename  = key.Substring(0, hashIndex);
            }

            // handles zip files
            if (filename.GetExtension() == ".zip")
            {
                Stream stream = null;

                // scan the cache once every 3 seconds
                if (_lastCacheScan == DateTime.MinValue || _lastCacheScan < DateTime.Now.AddSeconds(-3))
                {
                    CleanCache();
                }

                try
                {
                    CachedZipFile existingEntry;
                    if (!_zipFileCache.TryGetValue(filename, out existingEntry))
                    {
                        var dataStream = _dataProvider.Fetch(filename);

                        if (dataStream != null)
                        {
                            try
                            {
                                var newItem = new CachedZipFile(dataStream, filename);
                                stream = CreateStream(newItem, entryName, filename);

                                if (!_zipFileCache.TryAdd(filename, newItem))
                                {
                                    newItem.Dispose();
                                }
                            }
                            catch (Exception exception)
                            {
                                if (exception is ZipException || exception is ZlibException)
                                {
                                    Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception);
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            lock (existingEntry)
                            {
                                stream = CreateStream(existingEntry, entryName, filename);
                            }
                        }
                        catch (Exception exception)
                        {
                            if (exception is ZipException || exception is ZlibException)
                            {
                                Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception);
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }

                    return(stream);
                }
                catch (Exception err)
                {
                    Log.Error(err, "Inner try/catch");
                    stream?.DisposeSafely();
                    return(null);
                }
            }
            else
            {
                // handles text files
                return(_dataProvider.Fetch(filename));
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Create a stream of a specific ZipEntry
        /// </summary>
        /// <param name="zipFile">The zipFile containing the zipEntry</param>
        /// <param name="entryName">The name of the entry</param>
        /// <param name="fileName">The name of the zip file on disk</param>
        /// <returns>A <see cref="Stream"/> of the appropriate zip entry</returns>
        private Stream CreateStream(CachedZipFile zipFile, string entryName, string fileName)
        {
            ZipEntry entry;

            if (entryName == null)
            {
                entry = zipFile.EntryCache.FirstOrDefault().Value;
            }
            else
            {
                zipFile.EntryCache.TryGetValue(entryName, out entry);
            }

            if (entry != null)
            {
                var stream = new MemoryStream();

                try
                {
                    stream.SetLength(entry.UncompressedSize);
                }
                catch (ArgumentOutOfRangeException)
                {
                    // The needed size of the MemoryStream is longer than allowed.
                    // just read the data directly from the file.
                    // Note that we cannot use entry.OpenReader() because only one OpenReader
                    // can be open at a time without causing corruption.

                    // We must use fileName instead of zipFile.Name,
                    // because zipFile is initialized from a stream and not a file.
                    var zipStream = new ZipInputStream(fileName);

                    var zipEntry = zipStream.GetNextEntry();

                    // The zip file was empty!
                    if (zipEntry == null)
                    {
                        return(null);
                    }

                    // Null entry name, return the first.
                    if (entryName == null)
                    {
                        return(zipStream);
                    }

                    // Non-default entry name, return matching one if it exists, otherwise null.
                    while (zipEntry != null)
                    {
                        if (string.Compare(zipEntry.FileName, entryName, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            return(zipStream);
                        }

                        zipEntry = zipStream.GetNextEntry();
                    }
                }

                entry.OpenReader().CopyTo(stream);
                stream.Position = 0;
                return(stream);
            }

            return(null);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Does not attempt to retrieve any data
        /// </summary>
        public Stream Fetch(string key)
        {
            string entryName = null; // default to all entries
            var    filename  = key;
            var    hashIndex = key.LastIndexOf("#", StringComparison.Ordinal);

            if (hashIndex != -1)
            {
                entryName = key.Substring(hashIndex + 1);
                filename  = key.Substring(0, hashIndex);
            }

            // handles zip files
            if (filename.GetExtension() == ".zip")
            {
                Stream stream = null;

                // scan the cache once every 3 seconds
                if (_lastCacheScan == DateTime.MinValue || _lastCacheScan < DateTime.Now.AddSeconds(-3))
                {
                    CleanCache();
                }

                try
                {
                    var dataStream = _dataProvider.Fetch(filename);

                    if (dataStream != null)
                    {
                        _zipFileCache.AddOrUpdate(filename,
                                                  x =>
                        {
                            var newItem = new CachedZipFile(ZipFile.Read(dataStream), filename);
                            stream      = CreateStream(newItem.ZipFile, entryName);
                            return(newItem);
                        },
                                                  (x, existingEntry) =>
                        {
                            stream = CreateStream(existingEntry.ZipFile, entryName);
                            return(existingEntry);
                        });
                        //stream = CreateStream(ZipFile.Read(dataStream), entryName);
                    }


                    return(stream);
                }
                catch (Exception err)
                {
                    Log.Error(err, "Inner try/catch");
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                    return(null);
                }
            }
            else
            {
                // handles text files
                return(_dataProvider.Fetch(filename));
            }
        }