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