/// <summary> /// Reads the bundle description from a <see cref="Stream"/>. /// </summary> /// <param name="stream">The stream.</param> /// <returns>A <see cref="BundleDescription"/> representing a description of the bundle.</returns> /// <exception cref="InvalidDataException">Invalid bundle header.</exception> /// <exception cref="InvalidDataException">The bundle has not been properly written.</exception> public static BundleDescription ReadBundleDescription(Stream stream) { var binaryReader = new BinarySerializationReader(stream); // Read header Header header; try { header = binaryReader.Read <Header>(); } catch (InvalidOperationException ex) { throw new InvalidDataException("Invalid bundle header.", ex); } var result = new BundleDescription { Header = header }; // Check magic header if (header.MagicHeader != Header.MagicHeaderValid) { throw new InvalidDataException("Invalid bundle header."); } // Ensure size has properly been set if (header.Size != stream.Length) { throw new InvalidDataException("Bundle has not been properly written."); } try { // 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); } catch (InvalidOperationException ex) { throw new InvalidDataException("Bundle has not been properly written.", ex); } return(result); }
public T CopyBySerialization <T>(T obj, SerializationBackend serializationBackend) { var result = default(T); if (serializationBackend == SerializationBackend.Binary) { var memoryStream = new MemoryStream(); var writer = new BinarySerializationWriter(memoryStream); writer.Write(obj); writer.Flush(); memoryStream.Seek(0, SeekOrigin.Begin); var reader = new BinarySerializationReader(memoryStream); reader.Serialize(ref result, ArchiveMode.Deserialize); } //else if (serializationBackend == SerializationBackend.Xml) //{ // var xmlDoc = new XmlDocument(); // var xmlElement = xmlDoc.CreateElement("object"); // var writer = new XmlSerializationWriter(xmlElement); // writer.Write(obj); // writer.Flush(); // var reader = new XmlSerializationReader(xmlElement); // reader.Serialize(ref result, ArchiveMode.Deserialize); //} return(result); }
/// <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 List <string> dependencies = result.Dependencies; binaryReader.Serialize(ref dependencies, ArchiveMode.Deserialize); // Read objects List <KeyValuePair <ObjectId, ObjectInfo> > objects = result.Objects; binaryReader.Serialize(ref objects, ArchiveMode.Deserialize); // Read assets List <KeyValuePair <string, ObjectId> > assets = result.Assets; binaryReader.Serialize(ref assets, ArchiveMode.Deserialize); return(result); }
protected virtual List <T> ReadEntries(Stream localStream) { var reader = new BinarySerializationReader(localStream); var entries = new List <T>(); while (localStream.Position < localStream.Length) { var entry = new T(); reader.Serialize(ref entry, ArchiveMode.Deserialize); entries.Add(entry); } return(entries); }
/// <summary> /// Loads intermediate data used for building a navigation mesh /// </summary> /// <param name="objectId">The unique Id for this data in the object database</param> /// <returns>The found cached build or null if there is no previous build</returns> private NavigationMesh LoadIntermediateData(ObjectId objectId) { try { var objectDatabase = ContentManager.FileProvider.ObjectDatabase; using (var stream = objectDatabase.OpenStream(objectId)) { var reader = new BinarySerializationReader(stream); NavigationMesh result = new NavigationMesh(); reader.Serialize(ref result, ArchiveMode.Deserialize); return(result); } } catch (Exception ex) { return(null); } }
public static async Task UnpackAPK() { // get the apk last update time var packageManager = PlatformAndroid.Context.PackageManager; var packageInfo = packageManager.GetPackageInfo(PlatformAndroid.Context.PackageName, PackageInfoFlags.Activities); var lastUpdateTime = packageInfo.LastUpdateTime; var sourceDir = PlatformAndroid.Context.ApplicationInfo.SourceDir; // evaluate if asset data should be extracted from apk file var shouldExtractAssets = true; if (ApplicationTemporary.FileExists(LastExtractedApkFileName)) { Int64 extractedLastUpdateTime = 0; using (var file = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Open, VirtualFileAccess.Read)) { var binaryReader = new BinarySerializationReader(file); binaryReader.Serialize(ref extractedLastUpdateTime, ArchiveMode.Deserialize); } shouldExtractAssets = extractedLastUpdateTime != lastUpdateTime; } // Copy assets if (shouldExtractAssets) { var assets = PlatformAndroid.Context.Assets; // Make sure assets exists var logger = GlobalLogger.GetLogger("VFS"); CopyFileOrDirectory(logger, sourceDir, "assets/data/", string.Empty); // update value of extracted last update time using (var stream = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.None)) { var binaryWriter = new BinarySerializationWriter(stream); binaryWriter.Write(lastUpdateTime); } } }
public static unsafe Image LoadFromMemory(IntPtr pSource, int size, bool makeACopy, GCHandle?handle) { var stream = new BinarySerializationReader(new NativeMemoryStream((byte *)pSource, size)); // Read and check magic code var magicCode = stream.ReadUInt32(); if (magicCode != MagicCode) { return(null); } // Read header var imageDescription = new ImageDescription(); ImageDescriptionSerializer.Serialize(ref imageDescription, ArchiveMode.Deserialize, stream); if (makeACopy) { var buffer = Utilities.AllocateMemory(size); Utilities.CopyMemory(buffer, pSource, size); pSource = buffer; makeACopy = false; } var image = new Image(imageDescription, pSource, 0, handle, !makeACopy); var totalSizeInBytes = stream.ReadInt32(); if (totalSizeInBytes != image.TotalSizeInBytes) { throw new InvalidOperationException("Image size is different than expected."); } // Read image data stream.Serialize(image.DataPointer, image.TotalSizeInBytes); return(image); }
/// <summary> /// Gets and cache the asset url referenced by the chunk with the given identifier. /// </summary> /// <param name="objectId">The object identifier.</param> /// <returns>The list of asset url referenced.</returns> private List <string> GetChunkReferences(ref ObjectId objectId) { List <string> references; // Check the cache if (!referencesByObjectId.TryGetValue(objectId, out references)) { // First time, need to scan it referencesByObjectId[objectId] = references = new List <string>(); // Open stream to read list of chunk references using (var stream = AssetManager.FileProvider.OpenStream("obj/" + objectId, VirtualFileMode.Open, VirtualFileAccess.Read)) { // Read chunk header var streamReader = new BinarySerializationReader(stream); var header = ChunkHeader.Read(streamReader); // Only process chunks if (header != null) { if (header.OffsetToReferences != -1) { // Seek to where references are stored and deserialize them streamReader.NativeStream.Seek(header.OffsetToReferences, SeekOrigin.Begin); List <ChunkReference> chunkReferences = null; streamReader.Serialize(ref chunkReferences, ArchiveMode.Deserialize); foreach (var chunkReference in chunkReferences) { references.Add(chunkReference.Location); } } } } } return(references); }
private static void Collect(HashSet <ObjectId> objectIds, ObjectId objectId, IAssetIndexMap assetIndexMap) { // Already added? if (!objectIds.Add(objectId)) { return; } using (var stream = AssetManager.FileProvider.OpenStream(DatabaseFileProvider.ObjectIdUrl + objectId, VirtualFileMode.Open, VirtualFileAccess.Read)) { // Read chunk header var streamReader = new BinarySerializationReader(stream); var header = ChunkHeader.Read(streamReader); // Only process chunks if (header != null) { if (header.OffsetToReferences != -1) { // Seek to where references are stored and deserialize them streamReader.NativeStream.Seek(header.OffsetToReferences, SeekOrigin.Begin); List <ChunkReference> references = null; streamReader.Serialize(ref references, ArchiveMode.Deserialize); foreach (var reference in references) { ObjectId refObjectId; var databaseFileProvider = DatabaseFileProvider.ResolveObjectId(reference.Location, out refObjectId); if (databaseFileProvider != null) { Collect(objectIds, refObjectId, databaseFileProvider.AssetIndexMap); } } } } } }
/// <summary> /// Synchronizes files to an android device. /// </summary> /// <param name="logger">The logger.</param> /// <param name="device">The device.</param> /// <param name="fileMapping">The file mapping (relative target path, source HDD filename).</param> /// <param name="androidPath">The android path.</param> /// <param name="cacheFile">The cache file.</param> public static void Synchronize(Logger logger, string device, Dictionary<string, string> fileMapping, string androidPath, string cacheFile) { // Ensure android path ends up with directory separator if (!androidPath.EndsWith("/")) androidPath = androidPath + "/"; // Search files var currentVersions = fileMapping .ToDictionary(x => x.Key, x => new FileVersion(x.Value)); // Try to read previous cache file var previousVersions = new Dictionary<string, FileVersion>(); try { using (var file = File.OpenRead(cacheFile)) { var binaryReader = new BinarySerializationReader(file); binaryReader.Serialize(ref previousVersions, ArchiveMode.Deserialize); } } catch (IOException) { } var filesToRemove = new List<string>(); var filesToUpload = new List<string>(); // Remove unecessary files (in previousVersions but not in currentVersions) foreach (var file in previousVersions.Where(x => !currentVersions.ContainsKey(x.Key))) { filesToRemove.Add(file.Key); } // Upload files that are either not uploaded yet, or not up to date foreach (var file in currentVersions) { FileVersion fileVersion; if (!previousVersions.TryGetValue(file.Key, out fileVersion) || fileVersion.FileSize != file.Value.FileSize || fileVersion.LastModifiedDate != file.Value.LastModifiedDate) { filesToUpload.Add(file.Key); } } // Upload files foreach (var file in filesToUpload) { if (logger != null) logger.Verbose("Copying file {0}", file); RunAdb(device, string.Format("push \"{0}\" \"{1}\"", fileMapping[file], androidPath + file.Replace('\\', '/'))); } // Remove files foreach (var file in filesToRemove) { if (logger != null) logger.Verbose("Deleting file {0}", file); RunAdb(device, string.Format("shell \"rm {0}\"", androidPath + file.Replace('\\', '/'))); } // Write new cache file using (var file = File.Create(cacheFile)) { var binaryWriter = new BinarySerializationWriter(file); binaryWriter.Write(currentVersions); } }
/// <summary> /// Synchronizes files to an android device. /// </summary> /// <param name="logger">The logger.</param> /// <param name="device">The device.</param> /// <param name="fileMapping">The file mapping (relative target path, source HDD filename).</param> /// <param name="androidPath">The android path.</param> /// <param name="cacheFile">The cache file.</param> public static void Synchronize(Logger logger, string device, Dictionary <string, string> fileMapping, string androidPath, string cacheFile) { // Ensure android path ends up with directory separator if (!androidPath.EndsWith("/")) { androidPath = androidPath + "/"; } // Search files var currentVersions = fileMapping .ToDictionary(x => x.Key, x => new FileVersion(x.Value)); // Try to read previous cache file var previousVersions = new Dictionary <string, FileVersion>(); try { using (var file = File.OpenRead(cacheFile)) { var binaryReader = new BinarySerializationReader(file); binaryReader.Serialize(ref previousVersions, ArchiveMode.Deserialize); } } catch (IOException) { } var filesToRemove = new List <string>(); var filesToUpload = new List <string>(); // Remove unecessary files (in previousVersions but not in currentVersions) foreach (var file in previousVersions.Where(x => !currentVersions.ContainsKey(x.Key))) { filesToRemove.Add(file.Key); } // Upload files that are either not uploaded yet, or not up to date foreach (var file in currentVersions) { FileVersion fileVersion; if (!previousVersions.TryGetValue(file.Key, out fileVersion) || fileVersion.FileSize != file.Value.FileSize || fileVersion.LastModifiedDate != file.Value.LastModifiedDate) { filesToUpload.Add(file.Key); } } // Upload files foreach (var file in filesToUpload) { if (logger != null) { logger.Verbose("Copying file {0}", file); } RunAdb(device, string.Format("push \"{0}\" \"{1}\"", fileMapping[file], androidPath + file.Replace('\\', '/'))); } // Remove files foreach (var file in filesToRemove) { if (logger != null) { logger.Verbose("Deleting file {0}", file); } RunAdb(device, string.Format("shell \"rm {0}\"", androidPath + file.Replace('\\', '/'))); } // Write new cache file using (var file = File.Create(cacheFile)) { var binaryWriter = new BinarySerializationWriter(file); binaryWriter.Write(currentVersions); } }