132 lines
4.9 KiB
C#
132 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Lucidiot.Raima {
|
|
public enum DatabaseVersion {
|
|
/// <summary>
|
|
/// Version 3.00, with a <c>V3.00 + 0x1A</c> file magic.
|
|
/// </summary>
|
|
V300
|
|
}
|
|
|
|
public class DatabaseSchema {
|
|
private short _pageSize = 512;
|
|
public short PageSize { get { return _pageSize; } }
|
|
|
|
public const DatabaseVersion Version = DatabaseVersion.V300;
|
|
|
|
public const string Magic = "V3.00\x1a";
|
|
|
|
public string DatabaseFileName;
|
|
|
|
public readonly IDatabaseStorage StorageMethod;
|
|
|
|
private List<FileEntry> _fileEntries = new List<FileEntry>();
|
|
|
|
public ReadOnlyCollection<FileEntry> FileEntries {
|
|
get { return _fileEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<RecordEntry> _recordEntries = new List<RecordEntry>();
|
|
|
|
public ReadOnlyCollection<RecordEntry> RecordEntries {
|
|
get { return _recordEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<FieldEntry> _fieldEntries = new List<FieldEntry>();
|
|
|
|
public ReadOnlyCollection<FieldEntry> FieldEntries {
|
|
get { return _fieldEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<SetEntry> _setEntries = new List<SetEntry>();
|
|
|
|
public ReadOnlyCollection<SetEntry> SetEntries {
|
|
get { return _setEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<MemberEntry> _memberEntries = new List<MemberEntry>();
|
|
|
|
public ReadOnlyCollection<MemberEntry> MemberEntries {
|
|
get { return _memberEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<SortEntry> _sortEntries = new List<SortEntry>();
|
|
|
|
public ReadOnlyCollection<SortEntry> SortEntries {
|
|
get { return _sortEntries.AsReadOnly(); }
|
|
}
|
|
|
|
private List<KeyEntry> _keyEntries = new List<KeyEntry>();
|
|
|
|
public ReadOnlyCollection<KeyEntry> KeyEntries {
|
|
get { return _keyEntries.AsReadOnly(); }
|
|
}
|
|
|
|
public DatabaseSchema(string fileName, IDatabaseStorage storage) {
|
|
this.DatabaseFileName = fileName;
|
|
this.StorageMethod = storage;
|
|
}
|
|
|
|
public static DatabaseSchema Load(string fileName, IDatabaseStorage storage) {
|
|
if (!storage.CanRead)
|
|
throw new NotSupportedException("A readable storage method is required to load an existing database.");
|
|
DatabaseSchema ds = new DatabaseSchema(fileName, storage);
|
|
using (BinaryReader br = storage.GetReader(fileName)) {
|
|
ds.Parse(br);
|
|
}
|
|
return ds;
|
|
}
|
|
|
|
private void Parse(BinaryReader br) {
|
|
string foundMagic = new String(Encoding.ASCII.GetChars(br.ReadBytes(Magic.Length)));
|
|
if (foundMagic != Magic)
|
|
throw new InvalidDataException("Unexpected file magic: " + foundMagic);
|
|
short pageSize = br.ReadInt16();
|
|
if (pageSize % 512 != 0)
|
|
throw new ArgumentOutOfRangeException("Page size must be a multiple of 512 bytes.");
|
|
this._pageSize = pageSize;
|
|
|
|
short fileCount, recordCount, fieldCount, setCount, memberCount, sortCount, keyCount;
|
|
fileCount = br.ReadInt16();
|
|
recordCount = br.ReadInt16();
|
|
fieldCount = br.ReadInt16();
|
|
setCount = br.ReadInt16();
|
|
memberCount = br.ReadInt16();
|
|
sortCount = br.ReadInt16();
|
|
keyCount = br.ReadInt16();
|
|
|
|
_fileEntries.Capacity = Math.Max(_fileEntries.Capacity, fileCount);
|
|
for (ushort i = 0; i < fileCount; i++)
|
|
_fileEntries.Add(Helpers.ReadStruct<FileEntry>(br));
|
|
|
|
_recordEntries.Capacity = Math.Max(_recordEntries.Capacity, recordCount);
|
|
for (ushort i = 0; i < recordCount; i++)
|
|
_recordEntries.Add(Helpers.ReadStruct<RecordEntry>(br));
|
|
|
|
_fieldEntries.Capacity = Math.Max(_fieldEntries.Capacity, fieldCount);
|
|
for (ushort i = 0; i < fieldCount; i++)
|
|
_fieldEntries.Add(Helpers.ReadStruct<FieldEntry>(br));
|
|
|
|
_setEntries.Capacity = Math.Max(_setEntries.Capacity, setCount);
|
|
for (ushort i = 0; i < setCount; i++)
|
|
_setEntries.Add(Helpers.ReadStruct<SetEntry>(br));
|
|
|
|
_memberEntries.Capacity = Math.Max(_memberEntries.Capacity, memberCount);
|
|
for (ushort i = 0; i < memberCount; i++)
|
|
_memberEntries.Add(Helpers.ReadStruct<MemberEntry>(br));
|
|
|
|
_sortEntries.Capacity = Math.Max(_sortEntries.Capacity, sortCount);
|
|
for (ushort i = 0; i < sortCount; i++)
|
|
_sortEntries.Add(Helpers.ReadStruct<SortEntry>(br));
|
|
|
|
_keyEntries.Capacity = Math.Max(_keyEntries.Capacity, keyCount);
|
|
for (ushort i = 0; i < keyCount; i++)
|
|
_keyEntries.Add(Helpers.ReadStruct<KeyEntry>(br));
|
|
}
|
|
}
|
|
}
|