Ejemplo n.º 1
0
        public WDB5Reader(Stream stream)
        {
            using (var reader = new BinaryReader(stream, Encoding.UTF8))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("DB5 file is corrupted!"));
                }

                uint magic = reader.ReadUInt32();

                if (magic != DB5FmtSig)
                {
                    throw new InvalidDataException(String.Format("DB5 file is corrupted!"));
                }

                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 idIndex       = reader.ReadUInt16();

                bool isSparse = (flags & 0x1) != 0;
                bool hasIndex = (flags & 0x4) != 0;

                m_meta = new FieldMetaData[FieldsCount];

                for (int i = 0; i < m_meta.Length; i++)
                {
                    m_meta[i] = new FieldMetaData()
                    {
                        Bits   = reader.ReadInt16(),
                        Offset = reader.ReadInt16()
                    };
                }

                DB5Row[] m_rows = new DB5Row[RecordsCount];

                for (int i = 0; i < RecordsCount; i++)
                {
                    m_rows[i] = new DB5Row(this, reader.ReadBytes(RecordSize));
                }

                m_stringsTable = new Dictionary <long, string>();

                for (int i = 0; i < StringTableSize;)
                {
                    long oldPos = reader.BaseStream.Position;

                    m_stringsTable[i] = reader.ReadCString();

                    i += (int)(reader.BaseStream.Position - oldPos);
                }

                if (isSparse)
                {
                    // code...
                    throw new Exception("can't do sparse table");
                }

                if (hasIndex)
                {
                    for (int i = 0; i < RecordsCount; i++)
                    {
                        int id  = reader.ReadInt32();
                        var row = m_rows[i];
                        row.Id       = id;
                        _Records[id] = row;
                    }
                }
                else
                {
                    for (int i = 0; i < RecordsCount; i++)
                    {
                        int id  = m_rows[i].Data.Skip(m_meta[idIndex].Offset).Take((32 - m_meta[idIndex].Bits) >> 3).Select((b, k) => b << k * 8).Sum();
                        var row = m_rows[i];
                        row.Id       = id;
                        _Records[id] = row;
                    }
                }

                if (copyTableSize > 0)
                {
                    int copyCount = copyTableSize / 8;

                    for (int i = 0; i < copyCount; i++)
                    {
                        int newId = reader.ReadInt32();
                        int oldId = reader.ReadInt32();

                        _Records[newId] = _Records[oldId];
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public T GetField <T>(int field, int arrayIndex = 0)
        {
            FieldMetaData meta = m_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 = m_data[meta.Offset + bytesCount * arrayIndex];
                break;

            case TypeCode.SByte:
                if (meta.Bits != 0x18)
                {
                    throw new Exception("TypeCode.SByte Unknown meta.Bits");
                }
                value = (sbyte)m_data[meta.Offset + bytesCount * arrayIndex];
                break;

            case TypeCode.Int16:
                if (meta.Bits != 0x10)
                {
                    throw new Exception("TypeCode.Int16 Unknown meta.Bits");
                }
                value = BitConverter.ToInt16(m_data, meta.Offset + bytesCount * arrayIndex);
                break;

            case TypeCode.UInt16:
                if (meta.Bits != 0x10)
                {
                    throw new Exception("TypeCode.UInt16 Unknown meta.Bits");
                }
                value = BitConverter.ToUInt16(m_data, meta.Offset + bytesCount * arrayIndex);
                break;

            case TypeCode.Int32:
                byte[] b1 = new byte[4];
                Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b1, 0, bytesCount);
                value = BitConverter.ToInt32(b1, 0);
                break;

            case TypeCode.UInt32:
                byte[] b2 = new byte[4];
                Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b2, 0, bytesCount);
                value = BitConverter.ToUInt32(b2, 0);
                break;

            case TypeCode.Int64:
                byte[] b3 = new byte[8];
                Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b3, 0, bytesCount);
                value = BitConverter.ToInt64(b3, 0);
                break;

            case TypeCode.UInt64:
                byte[] b4 = new byte[8];
                Array.Copy(m_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(m_data, meta.Offset + bytesCount * arrayIndex, b5, 0, bytesCount);
                int start = BitConverter.ToInt32(b5, 0);
                value = m_reader.StringTable[start];
                break;

            case TypeCode.Single:
                if (meta.Bits != 0x00)
                {
                    throw new Exception("TypeCode.Single Unknown meta.Bits");
                }
                value = BitConverter.ToSingle(m_data, meta.Offset + bytesCount * arrayIndex);
                break;

            default:
                throw new Exception("Unknown TypeCode " + code);
            }

            return((T)value);
        }
Ejemplo n.º 3
0
        private static T[] GetFieldValueArray <T>(BitReader r, FieldMetaData fieldMeta, ColumnMetaData columnMeta, Value32[] palletData, Dictionary <int, Value32> commonData, int arraySize) where T : unmanaged
        {
            switch (columnMeta.CompressionType)
            {
            case CompressionType.None:
                int bitSize = 32 - fieldMeta.Bits;

                T[] arr1 = new T[arraySize];

                for (int i = 0; i < arr1.Length; i++)
                {
                    if (bitSize > 0)
                    {
                        arr1[i] = r.Read <T>(bitSize);
                    }
                    else
                    {
                        arr1[i] = r.Read <T>(columnMeta.Immediate.BitWidth);
                    }
                }

                return(arr1);

            case CompressionType.Immediate:
                T[] arr2 = new T[arraySize];

                for (int i = 0; i < arr2.Length; i++)
                {
                    arr2[i] = r.Read <T>(columnMeta.Immediate.BitWidth);
                }

                return(arr2);

            case CompressionType.SignedImmediate:
                T[] arr4 = new T[arraySize];

                for (int i = 0; i < arr4.Length; i++)
                {
                    arr4[i] = r.ReadSigned <T>(columnMeta.Immediate.BitWidth);
                }

                return(arr4);

            case CompressionType.PalletArray:
                int cardinality = columnMeta.Pallet.Cardinality;

                if (arraySize != cardinality)
                {
                    throw new Exception("Struct missmatch for pallet array field?");
                }

                uint palletArrayIndex = r.ReadUInt32(columnMeta.Pallet.BitWidth);

                T[] arr3 = new T[cardinality];

                for (int i = 0; i < arr3.Length; i++)
                {
                    arr3[i] = palletData[i + cardinality * (int)palletArrayIndex].As <T>();
                }

                return(arr3);
            }
            throw new Exception(string.Format("Unexpected compression type {0}", columnMeta.CompressionType));
        }