public async Task <Stream> OpenStreamAsync(string path, FileMode mode, FileAccess access) { if (access.HasFlag(FileAccess.Write)) { return(await ReadWriteRootFolder.OpenStreamForWriteAsync(path, ToCreationCollisionOption(mode))); } else { if (mode != FileMode.Open) { throw new ArgumentException("File mode has to be FileMode.Open when FileAccess.Read is specified."); } if (await ExistsAsync(ReadWriteRootFolder, path)) { return(await ReadWriteRootFolder.OpenStreamForReadAsync(path)); } if (RootFolder != ReadWriteRootFolder && await ExistsAsync(RootFolder, path)) { return(await RootFolder.OpenStreamForReadAsync(path)); } throw new FileNotFoundException(); } }
internal async Task <object> DeserializeAsync(string path, Type type, Reference?parentReference, Reference?referenceToReload) { Reference reference; // Check if reference exists and immediately return. if (referenceToReload is null) { Reference?foundReference = await FindDeserializedReferenceAsync(path, type); if (foundReference != null) { if (parentReference is null || parentReference.References.Add(foundReference)) { IncrementReference(foundReference, parentReference is null); } return(foundReference.Object); } } // Reference not found, so deserialize asset. if (!await ExistsAsync(path)) { throw new FileNotFoundException(); } using Stream stream = await RootFolder.OpenStreamForReadAsync(path + FileExtension); Type rootObjectType = GetRootObjectType(stream); object rootObjectInstance = referenceToReload != null && referenceToReload.Object.GetType().IsAssignableFrom(rootObjectType) ? referenceToReload.Object : Activator.CreateInstance(rootObjectType); object result = rootObjectInstance; if (!type.IsInstanceOfType(rootObjectInstance) || (type == typeof(object) && rootObjectInstance is Asset)) { if (!(rootObjectInstance is Asset)) { throw new InvalidOperationException(); } AssetContentTypeAttribute?contentType = rootObjectInstance.GetType().GetCustomAttribute <AssetContentTypeAttribute>(); if (type == typeof(object) && contentType != null) { type = contentType.ContentType; } result = Activator.CreateInstance(type); } reference = referenceToReload ?? new Reference(path, result, parentReference is null); reference.DeserializationTask = Task.Run(async() => await DeserializeAsync(stream, rootObjectInstance, reference)); if (referenceToReload is null) { AddReference(reference); } parentReference?.References.Add(reference); await reference.DeserializationTask; return(reference.Object); }