/// <summary> /// Remove an entry from the current storage and compound file. /// </summary> /// <param name="entryName">The name of the entry in the current storage to delete</param> /// <example> /// <code> /// cf = new CompoundFile("A_FILE_YOU_CAN_CHANGE.cfs", UpdateMode.Update, true, false); /// cf.RootStorage.Delete("AStream"); // AStream item is assumed to exist. /// cf.Commit(true); /// cf.Close(); /// </code> /// </example> /// <exception cref="T:OpenMcdf.CFDisposedException">Raised if trying to delete item from a closed compound file</exception> /// <exception cref="T:OpenMcdf.CFItemNotFound">Raised if item to delete is not found</exception> /// <exception cref="T:OpenMcdf.CFException">Raised if trying to delete root storage</exception> public void Delete(String entryName) { CheckDisposed(); // Find entry to delete IDirectoryEntry tmp = DirectoryEntry.Mock(entryName, StgType.StgInvalid); IRBNode foundObj = null; this.Children.TryLookup(tmp, out foundObj); if (foundObj == null) { throw new CFItemNotFound("Entry named [" + entryName + "] was not found"); } //if (foundObj.GetType() != typeCheck) // throw new CFException("Entry named [" + entryName + "] has not the correct type"); if (((IDirectoryEntry)foundObj).StgType == StgType.StgRoot) { throw new CFException("Root storage cannot be removed"); } IRBNode altDel = null; switch (((IDirectoryEntry)foundObj).StgType) { case StgType.StgStorage: CFStorage temp = new CFStorage(this.CompoundFile, ((IDirectoryEntry)foundObj)); // This is a storage. we have to remove children items first foreach (IRBNode de in temp.Children) { IDirectoryEntry ded = de as IDirectoryEntry; temp.Delete(ded.Name); } // ...then we need to rethread the root of siblings tree... if (this.Children.Root != null) { this.DirEntry.Child = (this.Children.Root as IDirectoryEntry).SID; } else { this.DirEntry.Child = DirectoryEntry.NOSTREAM; } // ...and finally Remove storage item from children tree... this.Children.Delete(foundObj, out altDel); // ...and remove directory (storage) entry if (altDel != null) { foundObj = altDel; } this.CompoundFile.InvalidateDirectoryEntry(((IDirectoryEntry)foundObj).SID); break; case StgType.StgStream: // Free directory associated data stream. CompoundFile.FreeAssociatedData((foundObj as IDirectoryEntry).SID); // Remove item from children tree this.Children.Delete(foundObj, out altDel); // Rethread the root of siblings tree... if (this.Children.Root != null) { this.DirEntry.Child = (this.Children.Root as IDirectoryEntry).SID; } else { this.DirEntry.Child = DirectoryEntry.NOSTREAM; } // Delete operation could possibly have cloned a directory, changing its SID. // Invalidate the ACTUALLY deleted directory. if (altDel != null) { foundObj = altDel; } this.CompoundFile.InvalidateDirectoryEntry(((IDirectoryEntry)foundObj).SID); break; } //// Refresh recursively all SIDs (invariant for tree sorting) //VisitedEntryAction action = delegate(CFSItem target) //{ // if( ((IDirectoryEntry)target).SID>foundObj.SID ) // { // ((IDirectoryEntry)target).SID--; // } // ((IDirectoryEntry)target).LeftSibling--; //}; }
/// <summary> /// Remove an entry from the current storage and compound file. /// </summary> /// <param name="entryName">The name of the entry in the current storage to delete</param> /// <example> /// <code> /// cf = new CompoundFile("A_FILE_YOU_CAN_CHANGE.cfs", UpdateMode.Update, true, false); /// cf.RootStorage.Delete("AStream"); // AStream item is assumed to exist. /// cf.Commit(true); /// cf.Close(); /// </code> /// </example> /// <exception cref="T:OpenMcdf.CFDisposedException">Raised if trying to delete item from a closed compound file</exception> /// <exception cref="T:OpenMcdf.CFItemNotFound">Raised if item to delete is not found</exception> /// <exception cref="T:OpenMcdf.CFException">Raised if trying to delete root storage</exception> public void Delete(string entryName) { CheckDisposed(); // Find entry to delete var tmp = DirectoryEntry.Mock(entryName, StgType.StgInvalid); Children.TryLookup(tmp, out var foundObj); if (foundObj == null) { throw new CFItemNotFound("Entry named [" + entryName + "] was not found"); } if (((IDirectoryEntry)foundObj).StgType == StgType.StgRoot) { throw new CFException("Root storage cannot be removed"); } IRbNode altDel; // ReSharper disable once SwitchStatementMissingSomeCases switch (((IDirectoryEntry)foundObj).StgType) { case StgType.StgStorage: var temp = new CFStorage(CompoundFile, ((IDirectoryEntry)foundObj)); // This is a storage. we have to remove children items first foreach (var de in temp.Children) { if (de is IDirectoryEntry ded) { temp.Delete(ded.Name); } } // ...then we need to re-thread the root of siblings tree... DirEntry.Child = (Children.Root as IDirectoryEntry)?.SID ?? DirectoryEntry.nostream; // ...and finally Remove storage item from children tree... Children.Delete(foundObj, out altDel); // ...and remove directory (storage) entry if (altDel != null) { foundObj = altDel; } CompoundFile.InvalidateDirectoryEntry(((IDirectoryEntry)foundObj).SID); break; case StgType.StgStream: // Free directory associated data stream. CompoundFile.FreeAssociatedData((foundObj as IDirectoryEntry).SID); // Remove item from children tree Children.Delete(foundObj, out altDel); // Re-thread the root of siblings tree... DirEntry.Child = (Children.Root as IDirectoryEntry)?.SID ?? DirectoryEntry.nostream; // Delete operation could possibly have cloned a directory, changing its SID. // Invalidate the ACTUALLY deleted directory. if (altDel != null) { foundObj = altDel; } CompoundFile.InvalidateDirectoryEntry(((IDirectoryEntry)foundObj).SID); break; } }