Example #1
0
        /// <summary>
        /// Store a data stream inside the Pacakge.
        /// If the data already exists in the Package it will be overwritten.
        /// </summary>
        /// <param name="packagePath">Path to the Package</param>
        /// <param name="data">The stream that should be stored in the Package</param>
        /// <param name="storagePath">The relative path where the data should be stored inside the Package</param>
        public async Task AddItemToPackageAsync(string packagePath, Stream data, string storagePath)
        {
            var package = await RetrievePackageAsync(packagePath);

            var semaphore = LockingDictionary.GetOrAdd(packagePath, new SemaphoreSlim(1));

            try
            {
                await semaphore.WaitAsync();

                var part = package.Entries.Any(x => x.FullName == storagePath)
                    ? package.GetEntry(storagePath)
                    : package.CreateEntry(storagePath);

                using (var partStream = part.Open())
                {
                    await data.CopyToAsync(partStream);
                }

                AutoFlushPackage(packagePath);
            }
            finally
            {
                semaphore.Release();
            }
        }
Example #2
0
        /// <summary>
        /// Retrieve a Package for usage. This method will create the Package if it does not exist yet or open it if it exists
        /// </summary>
        /// <param name="packagePath">Path to the Package to initialize</param>
        private async Task <ZipArchive> RetrievePackageAsync(string packagePath)
        {
            var semaphore = LockingDictionary.GetOrAdd(packagePath, new SemaphoreSlim(1));

            try
            {
                await semaphore.WaitAsync();

                if (PackageDictionary.ContainsKey(packagePath))
                {
                    return(PackageDictionary[packagePath]);
                }

                if (!File.Exists(packagePath))
                {
                    var createdZip = new ZipArchive(File.Open(packagePath, FileMode.OpenOrCreate), ZipArchiveMode.Create);
                    createdZip.Dispose();
                }

                var tmpPackage = new ZipArchive(File.Open(packagePath, FileMode.OpenOrCreate), ZipArchiveMode.Update);

                PackageDictionary.Add(packagePath, tmpPackage);
                return(tmpPackage);
            }
            finally
            {
                semaphore.Release();
            }
        }
Example #3
0
        /// <summary>
        /// Retrieves data from the Package.
        /// </summary>
        /// <param name="packagePath">Path to the Package</param>
        /// <param name="storagePath">The relative path where data is stored inside the Package</param>
        /// <exception cref="KeyNotFoundException">Thrown if the storagePath could not be found in the package</exception>
        /// <returns>MemoryStream containing the data from the Package</returns>
        public async Task <Stream> RetrieveDataFromPackageAsync(string packagePath, string storagePath)
        {
            var package = await RetrievePackageAsync(packagePath);

            var semaphore = LockingDictionary.GetOrAdd(packagePath, new SemaphoreSlim(1));

            try
            {
                await semaphore.WaitAsync();

                if (package.Entries.All(x => x.FullName != storagePath))
                {
                    throw new KeyNotFoundException($"The path {storagePath} could not be found in the Package");
                }

                var part = package.GetEntry(storagePath);

                var returnStream = new MemoryStream();
                using (var partStream = part.Open())
                {
                    await partStream.CopyToAsync(returnStream);

                    returnStream.Position = 0;
                }

                return(returnStream);
            }
            finally
            {
                semaphore.Release();
            }
        }
Example #4
0
        /// <summary>
        /// Delete all data from the Package that is not contained in the list of paths to keep
        /// </summary>
        /// <param name="packagePath">Path to the Package</param>
        /// <param name="storagePathsToKeep">List of relative paths of data in the package that should be kept</param>
        public async Task ScrubStorageAsync(string packagePath, List <string> storagePathsToKeep)
        {
            var package = await RetrievePackageAsync(packagePath);

            var semaphore = LockingDictionary.GetOrAdd(packagePath, new SemaphoreSlim(1));

            try
            {
                await semaphore.WaitAsync();

                var parts        = package.Entries.ToList();
                var totalEntries = parts.Count;
                var progress     = 0;
                foreach (var part in parts)
                {
                    if (!storagePathsToKeep.Contains(part.FullName))
                    {
                        part.Delete();
                    }
                    progress++;
                    ScrubProgress?.Invoke(this, new ScrubProgressArgs(packagePath, totalEntries, progress));
                }

                AutoFlushPackage(packagePath);
            }
            finally
            {
                semaphore.Release();
            }
        }
Example #5
0
        /// <summary>
        /// Remove data from a Package
        /// <remark>
        /// If the data does not exist in the package nothing will be done
        /// </remark>
        /// </summary>
        /// <param name="packagePath">Path to the Package</param>
        /// <param name="storagePath">The relative path where data is stored inside the Package</param>
        public async Task RemoveDataFromPackageAsync(string packagePath, string storagePath)
        {
            var package = await RetrievePackageAsync(packagePath);

            var semaphore = LockingDictionary.GetOrAdd(packagePath, new SemaphoreSlim(1));

            try
            {
                await semaphore.WaitAsync();

                if (package.Entries.All(x => x.FullName != storagePath))
                {
                    return;
                }

                package.GetEntry(storagePath).Delete();
            }
            finally
            {
                semaphore.Release();
            }
        }