示例#1
0
        void ProcessBlockRecursive(Block block, Map map, int address, int count, ref Report report)
        {
            br.BaseStream.Position = address - magic;

            #region Check Alignement

            if (br.BaseStream.Position % block.Alignment != 0)
            {
                //if (OnAddressError != null)
                //{
                //    OnAddressError(this, new AddressingErrorArgs()
                //    {
                //        Block = block,
                //        Offset = startAddress,
                //        Length = length,
                //        Type = AddressingErrorArgs.ErrorType.InvalidAlignment
                //    });
                //}
            }

            #endregion

            #region Read Sector

            bool internalSector = (address - magic) >= startAddress && (address - magic) < startAddress + length;
            report.Sectors.Add(new Sector(address - magic, block.Size * count, block.Alignment, block) { IsInternal = internalSector });

            //if (OnSectorRead != null)
            //{
            //    bool internalSector = (address - magic) >= startAddress && (address - magic) < startAddress + length;
            //    OnSectorRead(this, new ReadSectorArgs()
            //    {
            //        Sector = new Sector(address - magic, block.Size * count, block.Alignment, block) { IsInternal = internalSector }
            //    });
            //}

            #endregion

            int blockAddress = (int)br.BaseStream.Position;

            #region Check Values

            for (int i = 0; i < count; i++)
            {
                for (int j = 0; j < block.Values.Length; j++)
                {
                    int offset = blockAddress + (block.Size * i) + block.Values[j].Offset;
                    br.BaseStream.Seek(offset, SeekOrigin.Begin);
                    switch (block.Values[j].Type)
                    {
                        #region Check StringReference Values

                        case Sunfish.Developmental.Value.ValueType.StringId:
                            ValueTypes.StringId stringRef = br.ReadStringReference();
                            int index = Strings.BinarySearch(map.StringIdNames[stringRef.Index]);
                            if (index < 0)
                                Strings.Insert(~index, map.StringIdNames[stringRef.Index]);
                            if (stringRef.Index < 0 || stringRef.Index > map.StringIdNames.Count || map.StringIdNames[stringRef.Index].Length != stringRef.Length)
                            {
                                //if (OnValueError != null)
                                //{
                                //    OnValueError(this, new ValueErrorArgs()
                                //    {
                                //        Type = ValueErrorArgs.ErrorType.InvalidStringReference,
                                //        Block = block,
                                //        ValueIndex = j,
                                //        Offset = offset
                                //    });
                                //}
                            }
                            break;

                        #endregion

                        #region Check TagIndex Values

                        case Sunfish.Developmental.Value.ValueType.TagId:
                            ValueTypes.TagIndex tagIndex = br.ReadTagIndex();
                            if (tagIndex != -1 && !(tagIndex.Index < map.Index.TagInfoCount && tagIndex.Index > 0 && map.Index.TagEntries[tagIndex.Index].Index.Index == tagIndex))
                            {
                                //if (OnValueError != null)
                                //{
                                //    OnValueError(this, new ValueErrorArgs()
                                //    {
                                //        Type = ValueErrorArgs.ErrorType.InvalidTagIndex,
                                //        Block = block,
                                //        ValueIndex = j,
                                //        Offset = offset,
                                //        Value = tagIndex,
                                //    });
                                //}
                            }
                            break;

                        #endregion

                        #region Check TagReference Value

                        case Sunfish.Developmental.Value.ValueType.TagReference:
                            TagType tagType = br.ReadTagType();
                            tagIndex = br.ReadTagIndex();
                            if (tagIndex == -1)
                            {
                                if (tagType == TagType.Null)
                                { break; }
                                bool matched = false;
                                foreach (TagType tt in Sunfish.Index.Types)
                                {
                                    if (tt == tagType) matched = true;
                                }
                                if (!matched)
                                {
                                    //if (OnValueError != null)
                                    //{
                                    //    OnValueError(this, new ValueErrorArgs()
                                    //    {
                                    //        Type = ValueErrorArgs.ErrorType.InvalidTagType,
                                    //        Block = block,
                                    //        ValueIndex = j,
                                    //        Offset = offset,
                                    //        Value = tagType,
                                    //    });
                                    //}
                                }
                            }
                            else if (!(tagIndex.Index < map.Index.TagInfoCount && tagIndex.Index > 0 && map.Index.TagEntries[tagIndex.Index].Index.Index == tagIndex))
                            {
                                //if (OnValueError != null)
                                //{
                                //    OnValueError(this, new ValueErrorArgs()
                                //    {
                                //        Type = ValueErrorArgs.ErrorType.InvalidTagIndex,
                                //        Block = block,
                                //        ValueIndex = j,
                                //        Offset = offset,
                                //        Value = tagIndex,
                                //    });
                                //}
                            }
                            break;

                        #endregion
                    }
                }
            }
            #endregion

            #region Cache Raws

            //if (block.Raws.Length > 0)
            //{
            //    for (int i = 0; i < count; i++)
            //    {
            //        foreach (ResourceReference r in block.Raws)
            //        {
            //            ResourceReference raw = r;
            //            raw.Offset0 = blockAddress + (block.Size * i) + r.Offset0;
            //            raw.Offset1 = blockAddress + (block.Size * i) + r.Offset1;
            //        }
            //    }
            //}

            #endregion

            #region Process Nested Blocks

            if (block.NestedBlocks.Length > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    foreach (Block nestedBlock in block.NestedBlocks)
                    {
                        br.BaseStream.Position = (address - magic) + (i * block.Size) + nestedBlock.Offset;
                        int nestedBlockCount = br.ReadInt32();
                        if (nestedBlockCount == 0) continue;
                        int nestedBlockAddress = br.ReadInt32();
                        int offset = nestedBlockAddress - magic;
                        if (nestedBlockCount < 0)
                        {
                            //if (OnValueError != null)
                            //{
                            //    OnValueError(this, new ValueErrorArgs()
                            //    {
                            //        Type = ValueErrorArgs.ErrorType.InvalidArrayCount,
                            //        Offset = offset
                            //    });
                            //}
                        }
                        if (offset < 0 || offset > map.BaseStream.Length)
                        {
                            //if (OnValueError != null)
                            //{
                            //    OnValueError(this, new ValueErrorArgs()
                            //    {
                            //        Type = ValueErrorArgs.ErrorType.InvalidPointer,
                            //        Offset = offset
                            //    });
                            //}
                        }
                        else ProcessBlockRecursive(nestedBlock, map, nestedBlockAddress, nestedBlockCount, ref report);
                    }
                }
            }

            #endregion
        }
示例#2
0
 Report ProcessBlock(Block block, Map map, int address, int magic)
 {
     br = new BinaryReader(map.BaseStream);
     this.magic = magic;
     Report report = new Report();
     report.Sectors = new List<Sector>();
     ProcessBlockRecursive(block, map, address, 1, ref report);
     return report;
 }