public void TestRevertWithChanges()
 {
     using (TempFile temp = new TempFile())
     {
         byte[] sample = new byte[1024];
         new Random().NextBytes(sample);
         List <uint> handles = new List <uint>();
         using (TransactedCompoundFile file = new TransactedCompoundFile(temp.TempPath))
         {
             for (int i = 0; i < 1000; i++)
             {
                 var hid = file.Create();
                 handles.Add(hid);
                 file.Write(hid, sample, i, sample.Length - i);
                 CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(hid)));
             }
             file.Commit();
         }
         using (TransactedCompoundFile file = new TransactedCompoundFile(temp.TempPath))
         {
             byte[] dummy = new byte[1024];
             for (int i = 0; i < 1000; i++)
             {
                 file.Write(handles[i], dummy, 0, dummy.Length);
                 file.Delete(handles[i]);
             }
             file.Rollback();
             for (int i = 0; i < 1000; i++)
             {
                 CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
             }
         }
     }
 }
        static void ExersizeFile(ManualResetEvent stop, TransactedCompoundFile file)
        {
            const int LIMIT = 512 * 512 / 4 - 512 * 3;
            Random    r     = new Random();
            Dictionary <uint, byte[]> state = new Dictionary <uint, byte[]>();

            while (true)
            {
                while (state.Count < 1000)
                {
                    uint   h     = file.Create();
                    byte[] bytes = new byte[r.Next(5) == 0 ? r.Next(512) : r.Next(LIMIT)];
                    r.NextBytes(bytes);
                    file.Write(h, bytes, 0, bytes.Length);
                    state.Add(h, bytes);
                    if (stop.WaitOne(0, false))
                    {
                        return;
                    }
                }
                foreach (var kv in state)
                {
                    Assert.AreEqual(0, BinaryComparer.Compare(kv.Value, IOStream.ReadAllBytes(file.Read(kv.Key))));
                    if (stop.WaitOne(0, false))
                    {
                        return;
                    }
                }
                List <KeyValuePair <uint, byte[]> > capture = new List <KeyValuePair <uint, byte[]> >(state);
                for (int i = 0; i < capture.Count; i += r.Next(4))
                {
                    uint   h     = capture[i].Key;
                    byte[] bytes = new byte[r.Next(512)];
                    r.NextBytes(bytes);
                    file.Write(h, bytes, 0, bytes.Length);
                    state[h] = bytes;
                    Assert.AreEqual(0, BinaryComparer.Compare(bytes, IOStream.ReadAllBytes(file.Read(h))));
                    if (stop.WaitOne(0, false))
                    {
                        return;
                    }
                }
                for (int i = 0; i < capture.Count; i += 1 + r.Next(4))
                {
                    uint h = capture[i].Key;
                    file.Delete(h);
                    state.Remove(h);
                    if (stop.WaitOne(0, false))
                    {
                        return;
                    }
                }
            }
        }
        public void RandomTest()
        {
            Dictionary <uint, byte[]> store = new Dictionary <uint, byte[]>();

            using (TempFile temp = new TempFile())
            {
                uint   id;
                byte[] bytes;
                using (TransactedCompoundFile test = new TransactedCompoundFile(new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512, CreateNew = true
                }))
                {
                    for (int i = 0; i < 10000; i++)
                    {
                        switch (i < 1000 ? 0 : rand.Next(3))
                        {
                        case 0:
                        {
                            id    = test.Create();
                            bytes = RandomBytes(rand.Next(1000));
                            store.Add(id, bytes);
                            test.Write(id, bytes, 0, bytes.Length);
                            break;
                        }

                        case 1:
                        {
                            id    = RandomPick(store.Keys);
                            bytes = store[id];
                            CompareBytes(bytes, 0, bytes.Length, IOStream.ReadAllBytes(test.Read(id)));
                            break;
                        }

                        case 2:
                        {
                            id = RandomPick(store.Keys);
                            Assert.IsTrue(store.Remove(id));
                            test.Delete(id);
                            break;
                        }
                        }
                    }

                    foreach (var kv in store)
                    {
                        CompareBytes(kv.Value, 0, kv.Value.Length, IOStream.ReadAllBytes(test.Read(kv.Key)));
                    }
                }
            }
        }
        public void TestLargeWrite()
        {
            using (TempFile temp = new TempFile())
            {
                var options = new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512
                };
                byte[] sample = new byte[options.MaxWriteSize];
                new Random().NextBytes(sample);
                List <uint> handles = new List <uint>();
                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (int i = 0; i < 2; i++)
                    {
                        var hid = file.Create();
                        handles.Add(hid);
                        file.Write(hid, sample, i, sample.Length - i);
                        CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
                    }
                    file.Commit();
                }
                long size = temp.Info.Length;
                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (int i = 0; i < 2; i++)
                    {
                        CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
                        file.Delete(handles[i]);
                    }
                    file.Commit();
                    Assert.AreEqual(size, temp.Info.Length);
                    for (int i = 0; i < 252; i++)
                    {
                        var hid = file.Create();
                        handles.Add(hid);
                        file.Write(hid, sample, i, 300);
                    }
                    file.Commit();
                    Assert.AreEqual(size, temp.Info.Length);

                    file.Create();
                    Assert.AreNotEqual(size, temp.Info.Length);
                }
            }
        }
        public void SimpleTest()
        {
            uint handle;

            byte[] bytes = RandomBytes(2140);
            using (TempFile temp = new TempFile())
            {
                using (TransactedCompoundFile test = new TransactedCompoundFile(new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512, CreateNew = true
                }))
                {
                    Assert.AreEqual(TransactedCompoundFile.FirstIdentity, test.Create());
                    test.Write(TransactedCompoundFile.FirstIdentity, Encoding.UTF8.GetBytes("Roger was here."), 0, 15);
                    Assert.AreEqual("Roger was here.", Encoding.UTF8.GetString(IOStream.ReadAllBytes(test.Read(TransactedCompoundFile.FirstIdentity))));

                    for (int i = 0; i < 10; i++)
                    {
                        var id = test.Create();
                        test.Write(id, bytes, i, 300);
                        if (i % 2 == 0)
                        {
                            test.Delete(id);
                        }
                    }

                    handle = test.Create();
                    test.Write(handle, bytes, 1000, bytes.Length - 1000);
                    CompareBytes(bytes, 1000, bytes.Length - 1000, IOStream.ReadAllBytes(test.Read(handle)));

                    test.Write(handle, bytes, 0, bytes.Length);
                    CompareBytes(bytes, 0, bytes.Length, IOStream.ReadAllBytes(test.Read(handle)));

                    test.Commit();
                }
                using (TransactedCompoundFile test = new TransactedCompoundFile(new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512, CreateNew = false
                }))
                {
                    Assert.AreEqual("Roger was here.", Encoding.UTF8.GetString(IOStream.ReadAllBytes(test.Read(TransactedCompoundFile.FirstIdentity))));
                    CompareBytes(bytes, 0, bytes.Length, IOStream.ReadAllBytes(test.Read(handle)));
                }
            }
        }