diff --git a/.gitignore b/.gitignore index a02a88d7..43151fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ bin/ # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper -*.DotSettings.user \ No newline at end of file +*.DotSettings.user +/sources/Test/OpenMcdf.Benchmark/BenchmarkDotNet.Artifacts/OpenMcdf.Benchmark.InMemory-20190412-113734.log diff --git a/sources/OpenMcdf/CFItem.cs b/sources/OpenMcdf/CFItem.cs index 06ba3885..ceb9eeeb 100644 --- a/sources/OpenMcdf/CFItem.cs +++ b/sources/OpenMcdf/CFItem.cs @@ -137,6 +137,8 @@ public String Name else return String.Empty; } + + } /// diff --git a/sources/OpenMcdf/CFStorage.cs b/sources/OpenMcdf/CFStorage.cs index 24ac3534..7be94ef7 100644 --- a/sources/OpenMcdf/CFStorage.cs +++ b/sources/OpenMcdf/CFStorage.cs @@ -385,7 +385,7 @@ public CFStorage TryGetStorage(String storageName) /// cf.Close(); /// /// - public bool TryGetStorage(String storageName, CFStorage cfStorage) + public bool TryGetStorage(String storageName, out CFStorage cfStorage) { bool result = false; cfStorage = null; @@ -402,7 +402,7 @@ public bool TryGetStorage(String storageName, CFStorage cfStorage) cfStorage = new CFStorage(this.CompoundFile, outDe as IDirectoryEntry); result = true; } - + } catch (CFDisposedException) { @@ -639,6 +639,33 @@ public void Delete(String entryName) // ((IDirectoryEntry)target).LeftSibling--; //}; + + + } + + + /// + /// Rename a Stream or Storage item in the current storage + /// + /// The item old name to lookup + /// The new name to assign + public void RenameItem(string oldItemName, string newItemName) + { + IDirectoryEntry template = DirectoryEntry.Mock(oldItemName, StgType.StgInvalid); + IRBNode item; + if (Children.TryLookup(template, out item)) + { + ((DirectoryEntry)item).SetEntryName(newItemName); + } + else throw new CFItemNotFound("Item " + oldItemName + " not found in Storage"); + + children = null; + children = LoadChildren(this.DirEntry.SID); //Rethread + + if (children == null) + { + children = this.CompoundFile.CreateNewTree(); + } } } } diff --git a/sources/OpenMcdf/CFStream.cs b/sources/OpenMcdf/CFStream.cs index 80544d45..854f29ff 100644 --- a/sources/OpenMcdf/CFStream.cs +++ b/sources/OpenMcdf/CFStream.cs @@ -26,7 +26,7 @@ internal CFStream(CompoundFile compoundFile, IDirectoryEntry dirEntry) { if (dirEntry == null || dirEntry.SID < 0) throw new CFException("Attempting to add a CFStream using an unitialized directory"); - + this.DirEntry = dirEntry; } diff --git a/sources/OpenMcdf/CompoundFile.cs b/sources/OpenMcdf/CompoundFile.cs index ff559b49..9254e687 100644 --- a/sources/OpenMcdf/CompoundFile.cs +++ b/sources/OpenMcdf/CompoundFile.cs @@ -1271,7 +1271,7 @@ List result int nextSecID = Sector.ENDOFCHAIN; - HashSet processedSectors = new HashSet(); + HashSet processedSectors = new HashSet(); if (header.DIFATSectorsNumber != 0) { @@ -1304,8 +1304,11 @@ int nextSecID if (validationCount < 0) { - this.Close(); - throw new CFCorruptedFileException("DIFAT sectors count mismatched. Corrupted compound file"); + if (this.closeStream) + this.Close(); + + if (this.validationExceptionEnabled) + throw new CFCorruptedFileException("DIFAT sectors count mismatched. Corrupted compound file"); } s = sectors[nextSecID] as Sector; @@ -1324,14 +1327,14 @@ int nextSecID return result; } - private static void EnsureUniqueSectorIndex(int nextSecID, HashSet processedSectors) + private void EnsureUniqueSectorIndex(int nextSecID, HashSet processedSectors) { - if (processedSectors.Contains(nextSecID)) - { - throw new CFCorruptedFileException("The file is corrupted."); - } + if (processedSectors.Contains(nextSecID) && this.validationExceptionEnabled) + { + throw new CFCorruptedFileException("The file is corrupted."); + } - processedSectors.Add(nextSecID); + processedSectors.Add(nextSecID); } /// @@ -1374,7 +1377,7 @@ int nextSecID //Is there any DIFAT sector containing other FAT entries ? if (difatSectors.Count > 0) { - HashSet processedSectors = new HashSet(); + HashSet processedSectors = new HashSet(); StreamView difatStream = new StreamView ( @@ -1440,7 +1443,7 @@ List result int nextSecID = secID; List fatSectors = GetFatSectorChain(); - HashSet processedSectors = new HashSet(); + HashSet processedSectors = new HashSet(); StreamView fatStream = new StreamView(fatSectors, GetSectorSize(), fatSectors.Count * GetSectorSize(), null, sourceStream); @@ -1471,7 +1474,7 @@ StreamView fatStream EnsureUniqueSectorIndex(next, processedSectors); nextSecID = next; - + } @@ -1527,7 +1530,7 @@ StreamView miniFATView int next = miniFATReader.ReadInt32(); nextSecID = next; - EnsureUniqueSectorIndex(nextSecID, processedSectors); + EnsureUniqueSectorIndex(nextSecID, processedSectors); } } return result; diff --git a/sources/Test/OpenMcdf.Test/CFSStreamTest.cs b/sources/Test/OpenMcdf.Test/CFSStreamTest.cs index 8addc974..9de41e9a 100644 --- a/sources/Test/OpenMcdf.Test/CFSStreamTest.cs +++ b/sources/Test/OpenMcdf.Test/CFSStreamTest.cs @@ -496,7 +496,7 @@ public void Test_TRANSACTED_REMOVE_MINI_STREAM_ADD_MINISTREAM_TO_EXISTING_FILE() } - + [TestMethod] public void Test_DELETE_STREAM_1() { @@ -1004,7 +1004,7 @@ public void TEST_STREAM_VIEW() Buffer.BlockCopy(BitConverter.GetBytes((int)1), 0, s.GetData(), 0, 4); temp.Add(s); - StreamView sv = new StreamView(temp, 512, 0,null, a); + StreamView sv = new StreamView(temp, 512, 0, null, a); BinaryReader br = new BinaryReader(sv); Int32 t = br.ReadInt32(); @@ -1080,7 +1080,41 @@ public void Test_STREAM_VIEW_LARGE_DATA() } } - + /// + /// Write a sequence of Int32 greater than sector size, + /// read and compare. + /// + [TestMethod] + public void Test_CHANGE_STREAM_NAME_FIX_54() + { + try + { + CompoundFile cf = new CompoundFile("report.xls", CFSUpdateMode.ReadOnly, CFSConfiguration.Default); + cf.RootStorage.RenameItem("Workbook", "Workbuk"); + + cf.Save("report_n.xls"); + cf.Close(); + + CompoundFile cf2 = new CompoundFile("report_n.xls", CFSUpdateMode.Update, CFSConfiguration.Default); + cf2.RootStorage.RenameItem("Workbuk", "Workbook"); + cf2.Commit(); + cf2.Close(); + + CompoundFile cf3 = new CompoundFile("MultipleStorage.cfs", CFSUpdateMode.Update, CFSConfiguration.Default); + cf3.RootStorage.RenameItem("MyStorage", "MyNewStorage"); + cf3.Commit(); + cf3.Close(); + + CompoundFile cf4 = new CompoundFile("MultipleStorage.cfs", CFSUpdateMode.Update, CFSConfiguration.Default); + cf4.RootStorage.RenameItem("MyNewStorage", "MyStorage"); + cf4.Commit(); + cf4.Close(); + } + catch (Exception ex) + { + Assert.Fail("Unexpected exception raised: " + ex.Message); + } + } } } diff --git a/sources/Test/OpenMcdf.Test/CFSTorageTest.cs b/sources/Test/OpenMcdf.Test/CFSTorageTest.cs index 0f834b48..405e99f6 100644 --- a/sources/Test/OpenMcdf.Test/CFSTorageTest.cs +++ b/sources/Test/OpenMcdf.Test/CFSTorageTest.cs @@ -146,25 +146,29 @@ public void Test_TRY_GET_STREAM_STORAGE_NEW() { String FILENAME = "MultipleStorage.cfs"; CompoundFile cf = new CompoundFile(FILENAME); + CFStorage st = null; + bool bs = cf.RootStorage.TryGetStorage("MyStorage", out st); - CFStorage st = cf.RootStorage.TryGetStorage("MyStorage"); + Assert.IsTrue(bs); Assert.IsNotNull(st); try { - CFStorage nf = cf.RootStorage.TryGetStorage("IDONTEXIST"); + CFStorage nf = null; + bool nb = cf.RootStorage.TryGetStorage("IDONTEXIST", out nf); + Assert.IsFalse(nb); Assert.IsNull(nf); } catch (Exception) { - Assert.Fail("Exception raised for try_get method"); + Assert.Fail("Exception raised for TryGetStorage method"); } try { var b = st.TryGetStream("MyStream", out CFStream s); Assert.IsNotNull(s); - b = st.TryGetStream("IDONTEXIST2",out CFStream ns); + b = st.TryGetStream("IDONTEXIST2", out CFStream ns); Assert.IsFalse(b); } catch (Exception) @@ -453,7 +457,8 @@ public void Test_FIX_BUG_31() [ExpectedException(typeof(OpenMcdf.CFCorruptedFileException))] public void Test_CORRUPTEDDOC_BUG36_SHOULD_THROW_CORRUPTED_FILE_EXCEPTION() { - using (CompoundFile file = new CompoundFile("CorruptedDoc_bug36.doc", CFSUpdateMode.ReadOnly, CFSConfiguration.NoValidationException) ) { + using (CompoundFile file = new CompoundFile("CorruptedDoc_bug36.doc", CFSUpdateMode.ReadOnly, CFSConfiguration.NoValidationException)) + { //Many thanks to theseus for bug reporting } }