/// <summary> /// Visit all entities contained in the storage applying a user provided action /// </summary> /// <exception cref="T:OpenMcdf.CFDisposedException">Raised when visiting items of a closed compound file</exception> /// <param name="action">User <see cref="T:OpenMcdf.VisitedEntryAction">action</see> to apply to visited entities</param> /// <param name="recursive"> Visiting recursion level. True means substorages are visited recursively, false indicates that only the direct children of this storage are visited</param> /// <example> /// <code> /// const String STORAGE_NAME = "report.xls"; /// CompoundFile cf = new CompoundFile(STORAGE_NAME); /// /// FileStream output = new FileStream("LogEntries.txt", FileMode.Create); /// TextWriter tw = new StreamWriter(output); /// /// VisitedEntryAction va = delegate(CFItem item) /// { /// tw.WriteLine(item.Name); /// }; /// /// cf.RootStorage.VisitEntries(va, true); /// /// tw.Close(); /// </code> /// </example> public void VisitEntries(VisitedEntryAction action, bool recursive) { CheckDisposed(); if (action != null) { List <BinaryTreeNode <CFItem> > subStorages = new List <BinaryTreeNode <CFItem> >(); internalAction = delegate(BinaryTreeNode <CFItem> targetNode) { action(targetNode.Value as CFItem); if (targetNode.Value.DirEntry.Child != DirectoryEntry.NOSTREAM) { subStorages.Add(targetNode); } return; }; this.Children.VisitTreeInOrder(internalAction); if (recursive && subStorages.Count > 0) { foreach (BinaryTreeNode <CFItem> n in subStorages) { ((CFStorage)n.Value).VisitEntries(action, recursive); } } } }
/// <summary> /// Recursive addition of tree nodes foreach child of current item in the storage /// </summary> /// <param name="node">Current TreeNode</param> /// <param name="cfs">Current storage associated with node</param> private void AddNodes(TreeNode node, CFStorage cfs) { VisitedEntryAction va = delegate(CFItem target) { TreeNode temp = node.Nodes.Add( target.Name, target.Name + (target.IsStream ? " (" + target.Size + " bytes )" : "") ); temp.Tag = target; if (target.IsStream) { //Stream temp.ImageIndex = 1; temp.SelectedImageIndex = 1; } else { //Storage temp.ImageIndex = 0; temp.SelectedImageIndex = 0; //Recursion into the storage AddNodes(temp, (CFStorage)target); } }; //Visit NON-recursively (first level only) cfs.VisitEntries(va, false); }
/// <summary> /// This overload of the VisitEntries method allows the passing of a parameter arry of /// objects to the delegate method. /// </summary> /// <param name="action"> /// User <see cref="T:OpenMcdf.VisitedEntryParamsAction">action</see> to apply to visited /// entities /// </param> /// <param name="recursive"> /// Visiting recursion level. True means substorages are visited recursively, false /// indicates that only the direct children of this storage are visited</param> /// <param name="args"> /// The arguments to pass through to the delegate method /// </param> /// <example> /// <code> /// const String STORAGE_NAME = "report.xls"; /// CompoundFile cf = new CompoundFile(STORAGE_NAME); /// /// FileStream output = new FileStream("LogEntries.txt", FileMode.Create); /// TextWriter tw = new StreamWriter(output); /// /// VisitedEntryParamsAction va = delegate(CFItem item, object[] args) /// { /// var castList = (List<string>)args[0]; /// castList.Add(item.Name); /// }; /// /// var list = new List<string>(); /// /// cf.RootStorage.VisitEntries(va, true, list); /// /// list.ForEach(tw.WriteLine); /// /// tw.Close(); /// </code> /// </example> public void VisitEntries(VisitedEntryParamsAction action, bool recursive, params object[] args) { VisitedEntryAction wrappedDelegate = delegate(ICFItem item) { action(item, args); }; VisitEntries(wrappedDelegate, recursive); }
public void Test_VISIT_STORAGE() { String FILENAME = "testVisiting.xls"; // Remove... if (File.Exists(FILENAME)) { File.Delete(FILENAME); } //Create... CompoundFile ncf = new CompoundFile(); ICFStorage l1 = ncf.RootStorage.AddStorage("Storage Level 1"); l1.AddStream("l1ns1"); l1.AddStream("l1ns2"); l1.AddStream("l1ns3"); ICFStorage l2 = l1.AddStorage("Storage Level 2"); l2.AddStream("l2ns1"); l2.AddStream("l2ns2"); ncf.Save(FILENAME); ncf.Close(); // Read... CompoundFile cf = new CompoundFile(FILENAME); FileStream output = new FileStream("reportVisit.txt", FileMode.Create); TextWriter sw = new StreamWriter(output); Console.SetOut(sw); VisitedEntryAction va = delegate(ICFItem target) { sw.WriteLine(target.Name); }; cf.RootStorage.VisitEntries(va, true); cf.Close(); sw.Close(); }
public void Test_VISIT_ENTRIES() { const String STORAGE_NAME = "report.xls"; CompoundFile cf = new CompoundFile(STORAGE_NAME); FileStream output = new FileStream("LogEntries.txt", FileMode.Create); TextWriter tw = new StreamWriter(output); VisitedEntryAction va = delegate(ICFItem item) { tw.WriteLine(item.Name); }; cf.RootStorage.VisitEntries(va, true); tw.Close(); }
public void Test_VISIT_ENTRIES_CORRUPTED_FILE_VALIDATION_OFF_BUT_CAN_LOAD() { CompoundFile f = null; try { //Corrupted file has invalid children item sid reference f = new CompoundFile("CorruptedDoc_bug3547815_B.doc", UpdateMode.ReadOnly, false, false, true); } catch (Exception ex) { Assert.Fail("No exception has to be fired on creation due to lazy loading"); } FileStream output = null; try { output = new FileStream("LogEntriesCorrupted_2.txt", FileMode.Create); using (TextWriter tw = new StreamWriter(output)) { VisitedEntryAction va = delegate(ICFItem item) { tw.WriteLine(item.Name); }; f.RootStorage.VisitEntries(va, true); tw.Flush(); } } catch (Exception ex) { Assert.Fail("Fail is corrupted but it has to be loaded anyway by test design"); } finally { if (output != null) { output.Close(); } } }
public void Test_VISIT_ENTRIES_CORRUPTED_FILE_VALIDATION_ON() { CompoundFile f = null; try { f = new CompoundFile("CorruptedDoc_bug3547815.doc", UpdateMode.ReadOnly, false, false, false); } catch (Exception ex) { Assert.Fail("No exception has to be fired on creation due to lazy loading"); } FileStream output = null; try { output = new FileStream("LogEntriesCorrupted_1.txt", FileMode.Create); using (TextWriter tw = new StreamWriter(output)) { VisitedEntryAction va = delegate(ICFItem item) { tw.WriteLine(item.Name); }; f.RootStorage.VisitEntries(va, true); tw.Flush(); } } catch (Exception ex) { Assert.IsTrue(ex is CFCorruptedFileException); Assert.IsTrue(f != null && f.IsClosed); } finally { if (output != null) { output.Close(); } } }
public void Test_DELETE_STREAM() { String FILENAME = "MultipleStorage3.cfs"; CompoundFile cf = new CompoundFile(FILENAME); ICFStorage found = null; VisitedEntryAction action = delegate(ICFItem item) { if (item.Name == "AnotherStorage") { found = item as ICFStorage; } }; cf.RootStorage.VisitEntries(action, true); Assert.IsNotNull(found); found.Delete("Another2Stream"); cf.Save("MultipleDeleteStream"); cf.Close(); }
private static void AddNodes(String depth, CFStorage cfs) { VisitedEntryAction va = delegate(ICFItem target) { String temp = target.Name + (target is CFStorage ? "" : " (" + target.Size + " bytes )"); //Stream Console.WriteLine(depth + temp); if (target is CFStorage) { //Storage String newDepth = depth + " "; //Recursion into the storage AddNodes(newDepth, (CFStorage)target); } }; //Visit NON-recursively (first level only) cfs.VisitEntries(va, false); }
/// <summary> /// Visit all entities contained in the storage applying a user provided action /// </summary> /// <exception cref="T:OpenMcdf.CFDisposedException">Raised when visiting items of a closed compound file</exception> /// <param name="action">User <see cref="T:OpenMcdf.VisitedEntryAction">action</see> to apply to visited entities</param> /// <param name="recursive"> Visiting recursion level. True means substorages are visited recursively, false indicates that only the direct children of this storage are visited</param> /// <example> /// <code> /// const String STORAGE_NAME = "report.xls"; /// CompoundFile cf = new CompoundFile(STORAGE_NAME); /// /// FileStream output = new FileStream("LogEntries.txt", FileMode.Create); /// TextWriter tw = new StreamWriter(output); /// /// VisitedEntryAction va = delegate(CFItem item) /// { /// tw.WriteLine(item.Name); /// }; /// /// cf.RootStorage.VisitEntries(va, true); /// /// tw.Close(); /// </code> /// </example> public void VisitEntries(VisitedEntryAction action, bool recursive) { CheckDisposed(); if (action != null) { List<BinaryTreeNode<CFItem>> subStorages = new List<BinaryTreeNode<CFItem>>(); internalAction = delegate(BinaryTreeNode<CFItem> targetNode) { action(targetNode.Value as CFItem); if (targetNode.Value.DirEntry.Child != DirectoryEntry.NOSTREAM) subStorages.Add(targetNode); return; }; this.Children.VisitTreeInOrder(internalAction); if (recursive && subStorages.Count > 0) foreach (BinaryTreeNode<CFItem> n in subStorages) { ((CFStorage)n.Value).VisitEntries(action, recursive); } } }
public void Test_FUNCTIONAL_BEHAVIOUR() { const int N_FACTOR = 1; byte[] bA = Helpers.GetBuffer(20 * 1024 * N_FACTOR, 0x0A); byte[] bB = Helpers.GetBuffer(5 * 1024, 0x0B); byte[] bC = Helpers.GetBuffer(5 * 1024, 0x0C); byte[] bD = Helpers.GetBuffer(5 * 1024, 0x0D); byte[] bE = Helpers.GetBuffer(8 * 1024 * N_FACTOR + 1, 0x1A); byte[] bF = Helpers.GetBuffer(16 * 1024 * N_FACTOR, 0x1B); byte[] bG = Helpers.GetBuffer(14 * 1024 * N_FACTOR, 0x1C); byte[] bH = Helpers.GetBuffer(12 * 1024 * N_FACTOR, 0x1D); byte[] bE2 = Helpers.GetBuffer(8 * 1024 * N_FACTOR, 0x2A); byte[] bMini = Helpers.GetBuffer(1027, 0xEE); Stopwatch sw = new Stopwatch(); sw.Start(); //############ // Phase 1 var cf = new CompoundFile(CFSVersion.Ver_3, true, false); cf.RootStorage.AddStream("A").SetData(bA); cf.Save("OneStream.cfs"); cf.Close(); // Test Phase 1 var cfTest = new CompoundFile("OneStream.cfs"); ICFStream testSt = cfTest.RootStorage.GetStream("A"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bA.Length); Assert.IsTrue(Helpers.CompareBuffer(bA, testSt.GetData())); cfTest.Close(); //########### //Phase 2 cf = new CompoundFile("OneStream.cfs", UpdateMode.ReadOnly, true, false); cf.RootStorage.AddStream("B").SetData(bB); cf.RootStorage.AddStream("C").SetData(bC); cf.RootStorage.AddStream("D").SetData(bD); cf.RootStorage.AddStream("E").SetData(bE); cf.RootStorage.AddStream("F").SetData(bF); cf.RootStorage.AddStream("G").SetData(bG); cf.RootStorage.AddStream("H").SetData(bH); cf.Save("8_Streams.cfs"); cf.Close(); // Test Phase 2 cfTest = new CompoundFile("8_Streams.cfs"); testSt = cfTest.RootStorage.GetStream("B"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bB.Length); Assert.IsTrue(Helpers.CompareBuffer(bB, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("C"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bC.Length); Assert.IsTrue(Helpers.CompareBuffer(bC, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("D"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bD.Length); Assert.IsTrue(Helpers.CompareBuffer(bD, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("E"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bE.Length); Assert.IsTrue(Helpers.CompareBuffer(bE, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("F"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bF.Length); Assert.IsTrue(Helpers.CompareBuffer(bF, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("G"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bG.Length); Assert.IsTrue(Helpers.CompareBuffer(bG, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("H"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bH.Length); Assert.IsTrue(Helpers.CompareBuffer(bH, testSt.GetData())); cfTest.Close(); File.Copy("8_Streams.cfs", "6_Streams.cfs", true); File.Delete("8_Streams.cfs"); //########### // Phase 3 cf = new CompoundFile("6_Streams.cfs", UpdateMode.Update, true, true); cf.RootStorage.Delete("D"); cf.RootStorage.Delete("G"); cf.Commit(); cf.Close(); //Test Phase 3 cfTest = new CompoundFile("6_Streams.cfs"); bool catched = false; try { testSt = cfTest.RootStorage.GetStream("D"); } catch (Exception ex) { if (ex is CFItemNotFound) { catched = true; } } Assert.IsTrue(catched); catched = false; try { testSt = cfTest.RootStorage.GetStream("G"); } catch (Exception ex) { if (ex is CFItemNotFound) { catched = true; } } Assert.IsTrue(catched); cfTest.Close(); //########## // Phase 4 File.Copy("6_Streams.cfs", "6_Streams_Shrinked.cfs", true); CompoundFile.ShrinkCompoundFile("6_Streams_Shrinked.cfs"); // Test Phase 4 Assert.IsTrue(new FileInfo("6_Streams_Shrinked.cfs").Length < new FileInfo("6_Streams.cfs").Length); cfTest = new CompoundFile("6_Streams_Shrinked.cfs"); VisitedEntryAction va = delegate(ICFItem item) { if (item.IsStream) { ICFStream ia = item as ICFStream; Assert.IsNotNull(ia); Assert.IsTrue(ia.Size > 0); byte[] d = ia.GetData(); Assert.IsNotNull(d); Assert.IsTrue(d.Length > 0); Assert.IsTrue(d.Length == ia.Size); } }; cfTest.RootStorage.VisitEntries(va, true); cfTest.Close(); //########## //Phase 5 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStream("ZZZ").SetData(bF); cf.RootStorage.GetStream("E").AppendData(bE2); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.CLSID = new Guid("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("MyStorage").AddStream("ANS").AppendData(bE); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("AnotherStorage").AddStream("ANS").AppendData(bE); cf.RootStorage.Delete("MyStorage"); cf.Commit(); cf.Close(); //Test Phase 5 //##### //Phase 6 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("MiniStorage").AddStream("miniSt").AppendData(bMini); cf.RootStorage.GetStorage("MiniStorage").AddStream("miniSt2").AppendData(bMini); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.GetStorage("MiniStorage").Delete("miniSt"); cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").AppendData(bE); cf.Commit(); cf.Close(); //Test Phase 6 cfTest = new CompoundFile("6_Streams_Shrinked.cfs"); byte[] d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(); Assert.IsTrue(d2.Length == (bE.Length + bMini.Length)); int cnt = 1; d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(bMini.Length, ref cnt); Assert.IsTrue(cnt == 1); Assert.IsTrue(d2.Length == 1); Assert.IsTrue(d2[0] == 0x1A); cnt = 1; d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(bMini.Length - 1, ref cnt); Assert.IsTrue(cnt == 1); Assert.IsTrue(d2.Length == 1); Assert.IsTrue(d2[0] == 0xEE); try { cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt"); } catch (Exception ex) { Assert.IsTrue(ex is CFItemNotFound); } cfTest.Close(); //############## //Phase 7 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").SetData(bA); cf.Commit(); cf.Close(); //Test Phase 7 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); d2 = cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(); Assert.IsNotNull(d2); Assert.IsTrue(d2.Length == bA.Length); cf.Close(); //############## cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.ReadOnly, true, false); var myStream = cf.RootStorage.GetStream("C"); var data = myStream.GetData(); Console.WriteLine(data[0] + " : " + data[data.Length - 1]); myStream = cf.RootStorage.GetStream("B"); data = myStream.GetData(); Console.WriteLine(data[0] + " : " + data[data.Length - 1]); cf.Close(); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); }