예제 #1
0
        /// <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--;
            //};
        }
예제 #2
0
        /// <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;
            }
        }