1 /* Copyright (C) 2004 - 2009 Versant Inc. http://www.db4o.com */ 2 3 using System; 4 using Db4objects.Db4o.Internal; 5 using Db4objects.Db4o.Internal.Fileheader; 6 using Sharpen.Lang; 7 8 namespace Db4objects.Db4o.Internal.Fileheader 9 { 10 /// <exclude></exclude> 11 public abstract class FileHeader 12 { 13 public const int TransactionPointerLength = Const4.IntLength * 2; 14 15 private static readonly FileHeader[] AvailableFileHeaders = new FileHeader[] { new 16 FileHeader1(), new FileHeader2(), new FileHeader3() }; 17 NewCurrentFileHeader()18 public static NewFileHeaderBase NewCurrentFileHeader() 19 { 20 return new FileHeader3(); 21 } 22 ReaderLength()23 private static int ReaderLength() 24 { 25 int length = AvailableFileHeaders[0].Length(); 26 for (int i = 1; i < AvailableFileHeaders.Length; i++) 27 { 28 length = Math.Max(length, AvailableFileHeaders[i].Length()); 29 } 30 return length; 31 } 32 33 /// <exception cref="Db4objects.Db4o.Ext.OldFormatException"></exception> Read(LocalObjectContainer file)34 public static FileHeader Read(LocalObjectContainer file) 35 { 36 ByteArrayBuffer reader = PrepareFileHeaderReader(file); 37 FileHeader header = DetectFileHeader(file, reader); 38 if (header == null) 39 { 40 Exceptions4.ThrowRuntimeException(Db4objects.Db4o.Internal.Messages.IncompatibleFormat 41 , file.ToString()); 42 } 43 else 44 { 45 header.Read(file, reader); 46 } 47 return header; 48 } 49 Convert(LocalObjectContainer file)50 public virtual FileHeader Convert(LocalObjectContainer file) 51 { 52 FileHeader3 fileHeader = new FileHeader3(); 53 fileHeader.InitNew(file); 54 return fileHeader; 55 } 56 PrepareFileHeaderReader(LocalObjectContainer file)57 private static ByteArrayBuffer PrepareFileHeaderReader(LocalObjectContainer file) 58 { 59 ByteArrayBuffer reader = new ByteArrayBuffer(ReaderLength()); 60 reader.Read(file, 0, 0); 61 return reader; 62 } 63 DetectFileHeader(LocalObjectContainer file, ByteArrayBuffer reader)64 private static FileHeader DetectFileHeader(LocalObjectContainer file, ByteArrayBuffer 65 reader) 66 { 67 for (int i = 0; i < AvailableFileHeaders.Length; i++) 68 { 69 reader.Seek(0); 70 FileHeader result = AvailableFileHeaders[i].NewOnSignatureMatch(file, reader); 71 if (result != null) 72 { 73 return result; 74 } 75 } 76 return null; 77 } 78 79 /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> Close()80 public abstract void Close(); 81 82 /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> InitNew(LocalObjectContainer file)83 public abstract void InitNew(LocalObjectContainer file); 84 CompleteInterruptedTransaction(LocalObjectContainer container )85 public abstract void CompleteInterruptedTransaction(LocalObjectContainer container 86 ); 87 Length()88 public abstract int Length(); 89 NewOnSignatureMatch(LocalObjectContainer file, ByteArrayBuffer reader)90 protected abstract FileHeader NewOnSignatureMatch(LocalObjectContainer file, ByteArrayBuffer 91 reader); 92 TimeToWrite(long time, bool shuttingDown)93 protected virtual long TimeToWrite(long time, bool shuttingDown) 94 { 95 return shuttingDown ? 0 : time; 96 } 97 Read(LocalObjectContainer file, ByteArrayBuffer reader)98 protected abstract void Read(LocalObjectContainer file, ByteArrayBuffer reader); 99 SignatureMatches(ByteArrayBuffer reader, byte[] signature, byte version)100 protected virtual bool SignatureMatches(ByteArrayBuffer reader, byte[] signature, 101 byte version) 102 { 103 for (int i = 0; i < signature.Length; i++) 104 { 105 if (reader.ReadByte() != signature[i]) 106 { 107 return false; 108 } 109 } 110 return reader.ReadByte() == version; 111 } 112 113 // TODO: freespaceID should not be passed here, it should be taken from SystemData WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread , bool shuttingDown, StatefulBuffer writer, int blockSize)114 public abstract void WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread 115 , bool shuttingDown, StatefulBuffer writer, int blockSize); 116 WriteTransactionPointer(Transaction systemTransaction, int transactionPointer )117 public abstract void WriteTransactionPointer(Transaction systemTransaction, int transactionPointer 118 ); 119 WriteTransactionPointer(Transaction systemTransaction, int transactionPointer, int address, int offset)120 protected virtual void WriteTransactionPointer(Transaction systemTransaction, int 121 transactionPointer, int address, int offset) 122 { 123 StatefulBuffer bytes = new StatefulBuffer(systemTransaction, address, TransactionPointerLength 124 ); 125 bytes.MoveForward(offset); 126 bytes.WriteInt(transactionPointer); 127 bytes.WriteInt(transactionPointer); 128 // Dangerous write. 129 // On corruption transaction pointers will not be the same and nothing will happen. 130 bytes.Write(); 131 } 132 WriteVariablePart(LocalObjectContainer file)133 public virtual void WriteVariablePart(LocalObjectContainer file) 134 { 135 WriteVariablePart(file, false); 136 } 137 WriteVariablePart(LocalObjectContainer file, bool shuttingDown )138 public abstract void WriteVariablePart(LocalObjectContainer file, bool shuttingDown 139 ); 140 LockedByOtherSession(LocalObjectContainer container, long lastAccessTime )141 public static bool LockedByOtherSession(LocalObjectContainer container, long lastAccessTime 142 ) 143 { 144 return container.NeedsLockFileThread() && (lastAccessTime != 0); 145 } 146 ReadIdentity(LocalObjectContainer container)147 public abstract void ReadIdentity(LocalObjectContainer container); 148 Commit(bool shuttingDown)149 public abstract IRunnable Commit(bool shuttingDown); 150 } 151 } 152