public T GetField <T>(int field, int arrayIndex = 0) { DB2_Meta meta = reader.Meta[field]; if (meta.Bits != 0x00 && meta.Bits != 0x08 && meta.Bits != 0x10 && meta.Bits != 0x18 && meta.Bits != -32) { throw new Exception("Unknown meta.Flags"); } int bytesCount = (32 - meta.Bits) >> 3; TypeCode code = Type.GetTypeCode(typeof(T)); object value = null; switch (code) { case TypeCode.Byte: if (meta.Bits != 0x18) { throw new Exception("TypeCode.Byte Unknown meta.Bits"); } value = data[meta.Offset + bytesCount * arrayIndex]; break; case TypeCode.SByte: if (meta.Bits != 0x18) { throw new Exception("TypeCode.SByte Unknown meta.Bits"); } value = (sbyte)data[meta.Offset + bytesCount * arrayIndex]; break; case TypeCode.Int16: if (meta.Bits != 0x10) { throw new Exception("TypeCode.Int16 Unknown meta.Bits"); } value = BitConverter.ToInt16(data, meta.Offset + bytesCount * arrayIndex); break; case TypeCode.UInt16: if (meta.Bits != 0x10) { throw new Exception("TypeCode.UInt16 Unknown meta.Bits"); } value = BitConverter.ToUInt16(data, meta.Offset + bytesCount * arrayIndex); break; case TypeCode.Int32: byte[] b1 = new byte[4]; Array.Copy(data, meta.Offset + bytesCount * arrayIndex, b1, 0, bytesCount); value = BitConverter.ToInt32(b1, 0); break; case TypeCode.UInt32: byte[] b2 = new byte[4]; Array.Copy(data, meta.Offset + bytesCount * arrayIndex, b2, 0, bytesCount); value = BitConverter.ToUInt32(b2, 0); break; case TypeCode.Int64: byte[] b3 = new byte[8]; Array.Copy(data, meta.Offset + bytesCount * arrayIndex, b3, 0, bytesCount); value = BitConverter.ToInt64(b3, 0); break; case TypeCode.UInt64: byte[] b4 = new byte[8]; Array.Copy(data, meta.Offset + bytesCount * arrayIndex, b4, 0, bytesCount); value = BitConverter.ToUInt64(b4, 0); break; case TypeCode.String: if (meta.Bits != 0x00) { throw new Exception("TypeCode.String Unknown meta.Bits"); } byte[] b5 = new byte[4]; Array.Copy(data, meta.Offset + bytesCount * arrayIndex, b5, 0, bytesCount); int start = BitConverter.ToInt32(b5, 0), len = 0; while (reader.StringTable[start + len] != 0) { len++; } value = Encoding.UTF8.GetString(reader.StringTable, start, len); break; case TypeCode.Single: if (meta.Bits != 0x00) { throw new Exception("TypeCode.Single Unknown meta.Bits"); } value = BitConverter.ToSingle(data, meta.Offset + bytesCount * arrayIndex); break; default: throw new Exception("Invalid TypeCode: " + code); } return((T)value); }
public DB5_Reader(Stream stream) { using (var reader = new BinaryReader(stream, Encoding.UTF8)) { if (reader.BaseStream.Length < HeaderSize) { throw new InvalidDataException("Corrupted DB5 file (header mis-match)"); } if (reader.ReadUInt32() != Magic) { throw new InvalidDataException("Corrupted DB5 file (magic)"); } RecordsCount = reader.ReadInt32(); FieldsCount = reader.ReadInt32(); RecordSize = reader.ReadInt32(); StringTableSize = reader.ReadInt32(); uint tableHash = reader.ReadUInt32(); uint layoutHash = reader.ReadUInt32(); MinIndex = reader.ReadInt32(); MaxIndex = reader.ReadInt32(); int locale = reader.ReadInt32(); int copyTableSize = reader.ReadInt32(); int flags = reader.ReadUInt16(); int index = reader.ReadUInt16(); bool isSparse = (flags & 0x1) != 0; bool hasIndex = (flags & 0x4) != 0; meta = new DB2_Meta[FieldsCount]; for (int i = 0; i < meta.Length; i++) { meta[i] = new DB2_Meta(); meta[i].Bits = reader.ReadInt16(); meta[i].Offset = reader.ReadInt16(); } DB5_Row[] rows = new DB5_Row[RecordsCount]; for (int i = 0; i < RecordsCount; i++) { rows[i] = new DB5_Row(this, reader.ReadBytes(RecordSize)); } stringTable = reader.ReadBytes(StringTableSize); if (isSparse) { throw new Exception("Sparse table encountered!"); } if (hasIndex) { for (int i = 0; i < RecordsCount; i++) { this.index[reader.ReadInt32()] = rows[i]; } } else { for (int i = 0; i < RecordsCount; i++) { int id = rows[i].Data.Skip(meta[index].Offset).Take((32 - this.meta[index].Bits) >> 3).Select((b, k) => b << k * 8).Sum(); this.index[id] = rows[i]; } } if (copyTableSize > 0) { // Duplicate existing entry as new one. int count = copyTableSize / 8; for (int i = 0; i < count; i++) { this.index[reader.ReadInt32()] = this.index[reader.ReadInt32()]; } } } }