private static bool ValidateHeader(Stream stream) { var binaryReader = new BinarySerializationReader(stream); // Read header var header = binaryReader.Read <Header>(); var result = new BundleDescription(); result.Header = header; // Check magic header if (header.MagicHeader != Header.MagicHeaderValid) { return(false); } // Ensure size has properly been set if (header.Size != stream.Length) { return(false); } return(true); }
/// <summary> /// Reads the bundle description. /// </summary> /// <param name="stream">The stream.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException"> /// Invalid bundle header /// or /// Bundle has not been properly written /// </exception> public static BundleDescription ReadBundleDescription(Stream stream) { var binaryReader = new BinarySerializationReader(stream); // Read header var header = binaryReader.Read <Header>(); var result = new BundleDescription(); result.Header = header; // Check magic header if (header.MagicHeader != Header.MagicHeaderValid) { throw new InvalidOperationException("Invalid bundle header"); } // Ensure size has properly been set if (header.Size != stream.Length) { throw new InvalidOperationException("Bundle has not been properly written"); } // Read dependencies var dependencies = result.Dependencies; binaryReader.Serialize(ref dependencies, ArchiveMode.Deserialize); // Read incremental bundles var incrementalBundles = result.IncrementalBundles; binaryReader.Serialize(ref incrementalBundles, ArchiveMode.Deserialize); // Read objects var objects = result.Objects; binaryReader.Serialize(ref objects, ArchiveMode.Deserialize); // Read assets var assets = result.Assets; binaryReader.Serialize(ref assets, ArchiveMode.Deserialize); return(result); }
public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap, string bundleUrl, bool ignoreDependencies = false) { BundleDescription bundle = null; // If there is a .bundle, add incremental id before it var currentBundleExtensionUrl = bundleUrl.Length - (bundleUrl.EndsWith(BundleExtension) ? BundleExtension.Length : 0); // Process incremental bundles one by one using (var packStream = VirtualFileSystem.OpenStream(bundleUrl, VirtualFileMode.Open, VirtualFileAccess.Read)) { bundle = ReadBundleDescription(packStream); } var files = new List <string> { bundleUrl }; files.AddRange(bundle.IncrementalBundles.Select(x => bundleUrl.Insert(currentBundleExtensionUrl, "." + x))); if (bundle == null) { throw new FileNotFoundException("Could not find bundle", bundleUrl); } // Read and resolve dependencies if (!ignoreDependencies) { foreach (var dependency in bundle.Dependencies) { await LoadBundle(dependency, objectDatabaseContentIndexMap); } } LoadedBundle loadedBundle = null; lock (loadedBundles) { foreach (var currentBundle in loadedBundles) { if (currentBundle.BundleName == bundleName) { loadedBundle = currentBundle; break; } } if (loadedBundle == null) { loadedBundle = new LoadedBundle { BundleName = bundleName, BundleUrl = bundleUrl, Description = bundle, ReferenceCount = 1, Files = files, Streams = new List <Stream>(files.Select(x => (Stream)null)), }; loadedBundles.Add(loadedBundle); } else { loadedBundle.ReferenceCount++; } } // Read objects lock (objects) { foreach (var objectEntry in bundle.Objects) { objects[objectEntry.Key] = new ObjectLocation { Info = objectEntry.Value, LoadedBundle = loadedBundle }; } } // Merge with local (asset bundles) index map contentIndexMap.Merge(bundle.Assets); // Merge with global object database map objectDatabaseContentIndexMap.Merge(bundle.Assets); }