/// <summary> /// When a substorage is getting deleted, its references in the dataspacemanager's transform definition are removed. /// This is called recursively because the DeleteSubStorage deletes all its children by default. /// </summary> internal void RemoveSubStorageEntryFromDataSpaceMap(StorageInfo storageInfo) { StorageInfo[] subStorages = storageInfo.GetSubStorages(); foreach(StorageInfo storage in subStorages) { //If this is a storage, call recursively till we encounter a stream. Then we can use that container (storage,stream) reference to remove from the // dataspace manager's data space map. RemoveSubStorageEntryFromDataSpaceMap(storage); //recursive call } //Now we have StorageInfo. Find if there is a stream underneath so a container can be used as reference in data space map of data spacemanager. StreamInfo[] streams = storageInfo.GetStreams(); DataSpaceManager manager = Root.GetDataSpaceManager(); foreach(StreamInfo stream in streams) { manager.RemoveContainerFromDataSpaceMap(new CompoundFileStreamReference( storageInfo.FullNameInternal, stream.Name )); } }
/// <summary> /// Read all transform definitions in one chunk /// </summary> // void ReadTransformDefinitions() { ThrowIfIncorrectReaderVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StorageInfo transformDefinitionsStorage = new StorageInfo( dataSpaceStorage, TransformDefinitions ); if( transformDefinitionsStorage.Exists ) { // Read transform definitions from file foreach( StorageInfo transformStorage in transformDefinitionsStorage.GetSubStorages() ) { // Read from primary stream StreamInfo transformPrimary = new StreamInfo( transformStorage, TransformPrimaryInfo ); using(Stream transformDefinition = transformPrimary.GetStream(FileMode.Open)) { using(BinaryReader definitionReader = new BinaryReader( transformDefinition, System.Text.Encoding.Unicode )) { int headerLength = definitionReader.ReadInt32(); // We don't actually do anything with HeaderLen at the moment int transformType = definitionReader.ReadInt32(); if (headerLength < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Create a TransformInstance class using name from file TransformInstance transformInstance = new TransformInstance(transformType, CU.ReadByteLengthPrefixedDWordPaddedUnicodeString( definitionReader ) ); int extraDataSize = checked ((int) (headerLength - transformDefinition.Position)); if (extraDataSize < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); if (extraDataSize > 0) { if (extraDataSize > AllowedExtraDataMaximumSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Preserve the fields we don't know about. byte[] extraData = definitionReader.ReadBytes(extraDataSize); if (extraData.Length != extraDataSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); transformInstance.ExtraData = extraData; } if( transformDefinition.Length > transformDefinition.Position ) { // We have additional data in the primary instance data stream int instanceDataSize = checked ((int)(transformDefinition.Length - transformDefinition.Position)); byte[] instanceData = new byte[instanceDataSize]; PackagingUtilities.ReliableRead(transformDefinition, instanceData, 0, instanceDataSize); //build memory stream on the byte[] , and allow writes only if // FileAccess is Write or ReadWrite MemoryStream instanceDataStream; if (_associatedStorage.OpenAccess == FileAccess.Read) { // NOTE: Building MemoryStream directly on top of // instanceData byte array because we want it to be // NOT resizable and NOT writable. instanceDataStream = new MemoryStream(instanceData, false /* Not writable */); } else { // Copy additional data into a memory stream // NOTE: Not building MemoryStream directly on top of // instanceData byte array because we want it to be // resizable. instanceDataStream = new MemoryStream(); instanceDataStream.Write( instanceData, 0, instanceDataSize ); } instanceDataStream.Seek( 0, SeekOrigin.Begin ); // Dirty state should be tracked after the original data is read in from the disk into the memory stream transformInstance.transformPrimaryStream = new DirtyStateTrackingStream(instanceDataStream); } transformInstance.transformStorage = transformStorage; SetTransformDefinition( transformStorage.Name, transformInstance ); } } } } }