Exemplo n.º 1
0
        public new Dictionary <int, byte[]> ReadOffsetData(BinaryReader dbReader, long pos)
        {
            Dictionary <int, byte[]>          CopyTable  = new Dictionary <int, byte[]>();
            List <Tuple <int, short> >        offsetmap  = new List <Tuple <int, short> >();
            Dictionary <int, OffsetDuplicate> firstindex = new Dictionary <int, OffsetDuplicate>();
            Dictionary <int, List <int> >     Copies     = new Dictionary <int, List <int> >();

            columnOffsets = new List <int>();
            recordOffsets = new List <int>();
            int[] m_indexes = null;

            // OffsetTable
            if (HasOffsetTable && OffsetTableOffset > 0)
            {
                dbReader.BaseStream.Position = OffsetTableOffset;
                for (int i = 0; i < (MaxId - MinId + 1); i++)
                {
                    int   offset = dbReader.ReadInt32();
                    short length = dbReader.ReadInt16();

                    if (offset == 0 || length == 0)
                    {
                        continue;
                    }

                    // special case, may contain duplicates in the offset map that we don't want
                    if (CopyTableSize == 0)
                    {
                        if (!firstindex.ContainsKey(offset))
                        {
                            firstindex.Add(offset, new OffsetDuplicate(offsetmap.Count, firstindex.Count));
                        }
                        else
                        {
                            continue;
                        }
                    }

                    offsetmap.Add(new Tuple <int, short>(offset, length));
                }
            }

            // IndexTable
            if (HasIndexTable)
            {
                m_indexes = new int[RecordCount];
                for (int i = 0; i < RecordCount; i++)
                {
                    m_indexes[i] = dbReader.ReadInt32();
                }
            }

            // Copytable
            if (CopyTableSize > 0)
            {
                long end = dbReader.BaseStream.Position + CopyTableSize;
                while (dbReader.BaseStream.Position < end)
                {
                    int id     = dbReader.ReadInt32();
                    int idcopy = dbReader.ReadInt32();

                    if (!Copies.ContainsKey(idcopy))
                    {
                        Copies.Add(idcopy, new List <int>());
                    }

                    Copies[idcopy].Add(id);
                }
            }

            // Relationships
            if (RelationshipDataSize > 0)
            {
                RelationShipData = new RelationShipData()
                {
                    Records = dbReader.ReadUInt32(),
                    MinId   = dbReader.ReadUInt32(),
                    MaxId   = dbReader.ReadUInt32(),
                    Entries = new Dictionary <uint, byte[]>()
                };

                for (int i = 0; i < RelationShipData.Records; i++)
                {
                    byte[] foreignKey = dbReader.ReadBytes(4);
                    uint   index      = dbReader.ReadUInt32();
                    // has duplicates just like the copy table does... why?
                    if (!RelationShipData.Entries.ContainsKey(index))
                    {
                        RelationShipData.Entries.Add(index, foreignKey);
                    }
                }

                FieldStructure.Add(new FieldStructureEntry(0, 0));
                ColumnMeta.Add(new ColumnStructureEntry());
            }

            // Record Data
            BitStream bitStream = new BitStream(recordData);

            for (int i = 0; i < RecordCount; i++)
            {
                int id = 0;

                if (HasOffsetTable && HasIndexTable)
                {
                    id = m_indexes[CopyTable.Count];
                    var map = offsetmap[i];

                    if (CopyTableSize == 0 && firstindex[map.Item1].HiddenIndex != i)                     //Ignore duplicates
                    {
                        continue;
                    }

                    dbReader.BaseStream.Position = map.Item1;

                    byte[] data = dbReader.ReadBytes(map.Item2);

                    IEnumerable <byte> recordbytes = BitConverter.GetBytes(id).Concat(data);

                    // append relationship id
                    if (RelationShipData != null)
                    {
                        // seen cases of missing indicies
                        if (RelationShipData.Entries.TryGetValue((uint)i, out byte[] foreignData))