/// <summary>
        /// Extracts the raw data for a resource.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="outStream">The stream to write the extracted data to.</param>
        /// <exception cref="System.ArgumentException">Thrown if the output stream is not open for writing.</exception>
        /// <exception cref="System.InvalidOperationException">Thrown if the file containing the resource has not been loaded.</exception>
        public void Extract(ResourceReference resource, Stream outStream)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");
            if (!outStream.CanWrite)
                throw new ArgumentException("The output stream is not open for writing", "outStream");

            var cache = GetCache(resource);
            using (var stream = cache.File.OpenRead())
                cache.Cache.Decompress(stream, resource.Index, resource.CompressedSize, outStream);
        }
     /// <summary>
     /// Adds a new resource to a cache.
     /// </summary>
     /// <param name="resource">The resource reference to initialize.</param>
     /// <param name="location">The location where the resource should be stored.</param>
     /// <param name="dataStream">The stream to read the resource data from.</param>
     /// <exception cref="System.ArgumentNullException">resource</exception>
     /// <exception cref="System.ArgumentException">The input stream is not open for reading;dataStream</exception>
     public void Add(ResourceReference resource, ResourceLocation location, Stream dataStream)
     {
         if (resource == null)
             throw new ArgumentNullException("resource");
         if (!dataStream.CanRead)
             throw new ArgumentException("The input stream is not open for reading", "dataStream");
 
         resource.ChangeLocation(location);
         var cache = GetCache(resource);
         using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite))
         {
             var dataSize = (int)(dataStream.Length - dataStream.Position);
             var data = new byte[dataSize];
             dataStream.Read(data, 0, dataSize);
             uint compressedSize;
             resource.Index = cache.Cache.Add(stream, data, out compressedSize);
             resource.CompressedSize = compressedSize;
             resource.DecompressedSize = (uint)dataSize;
             resource.DisableChecksum();
         }
     }
 public ResourceSerializationContext(ResourceReference resource)
 {
     _resource = resource;
 }
 private LoadedCache GetCache(ResourceReference resource)
 {
     LoadedCache cache;
     if (!_loadedCaches.TryGetValue(resource.GetLocation(), out cache))
         throw new InvalidOperationException("The requested resource is located in " + resource.GetLocation() + ", but the corresponding cache file has not been loaded.");
     return cache;
 }
        /// <summary>
        /// Replaces a resource with raw, pre-compressed data.
        /// </summary>
        /// <param name="resource">The resource whose data should be replaced. On success, the reference will be adjusted to account for the new data.</param>
        /// <param name="data">The raw, pre-compressed data to use.</param>
        public void ReplaceRaw(ResourceReference resource, byte[] data)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");

            resource.DisableChecksum();
            var cache = GetCache(resource);
            using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite))
                cache.Cache.ImportRaw(stream, resource.Index, data);
        }
        /// <summary>
        /// Extracts raw, compressed resource data.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <returns>The raw, compressed resource data.</returns>
        public byte[] ExtractRaw(ResourceReference resource)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");

            var cache = GetCache(resource);
            using (var stream = cache.File.OpenRead())
                return cache.Cache.ExtractRaw(stream, resource.Index, resource.CompressedSize);
        }
        /// <summary>
        /// Adds raw, pre-compressed resource data to a cache.
        /// </summary>
        /// <param name="resource">The resource reference to initialize.</param>
        /// <param name="location">The location where the resource should be stored.</param>
        /// <param name="data">The pre-compressed data to store.</param>
        public void AddRaw(ResourceReference resource, ResourceLocation location, byte[] data)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");

            resource.ChangeLocation(location);
            resource.DisableChecksum();
            var cache = GetCache(resource);
            using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite))
                resource.Index = cache.Cache.AddRaw(stream, data);
        }
        /// <summary>
        /// Replaces the raw data for a resource.
        /// </summary>
        /// <param name="resource">The resource whose data should be replaced. On success, the reference will be adjusted to account for the new data.</param>
        /// <param name="dataStream">The stream to read the new data from.</param>
        /// <exception cref="System.ArgumentException">Thrown if the input stream is not open for reading.</exception>
        public void Replace(ResourceReference resource, Stream dataStream)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");
            if (!dataStream.CanRead)
                throw new ArgumentException("The input stream is not open for reading", "dataStream");

            var cache = GetCache(resource);
            using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                var dataSize = (int)(dataStream.Length - dataStream.Position);
                var data = new byte[dataSize];
                dataStream.Read(data, 0, dataSize);
                var compressedSize = cache.Cache.Compress(stream, resource.Index, data);
                resource.CompressedSize = compressedSize;
                resource.DecompressedSize = (uint)dataSize;
                resource.LocationFlags &= ~(ResourceLocationFlags.UseChecksum | ResourceLocationFlags.UseChecksum2);
            }
        }