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);
        }
Beispiel #2
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);
        }
Beispiel #3
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));
            }
        }