示例#1
0
        protected override bool ParseSectionContent(BinaryReader binaryReader)
        {
            if (binaryReader.BaseStream.Length == 0)
            {
                Version    = null;
                UniqueName = null;
                Name       = null;
                Scopes     = Array.Empty <ResourceMapScope>();
                Items      = Array.Empty <ResourceMapItem>();
                return(true);
            }

            binaryReader.ExpectUInt16(1);
            ushort uniqueNameLength = binaryReader.ReadUInt16();
            ushort nameLength       = binaryReader.ReadUInt16();

            binaryReader.ExpectUInt16(0);

            bool extendedHNames;

            if (extendedVersion)
            {
                switch (new string(binaryReader.ReadChars(16)))
                {
                case "[def_hnamesx]  \0":
                    extendedHNames = true;
                    break;

                case "[def_hnames]   \0":
                    extendedHNames = false;
                    break;

                default:
                    throw new InvalidDataException();
                }
            }
            else
            {
                extendedHNames = false;
            }

            // hierarchical schema version info
            ushort majorVersion = binaryReader.ReadUInt16();
            ushort minorVersion = binaryReader.ReadUInt16();

            binaryReader.ExpectUInt32(0);
            uint checksum  = binaryReader.ReadUInt32();
            uint numScopes = binaryReader.ReadUInt32();
            uint numItems  = binaryReader.ReadUInt32();

            Version = new HierarchicalSchemaVersionInfo(majorVersion, minorVersion, checksum, numScopes, numItems);

            UniqueName = binaryReader.ReadNullTerminatedString(Encoding.Unicode);
            Name       = binaryReader.ReadNullTerminatedString(Encoding.Unicode);

            if (UniqueName.Length != uniqueNameLength - 1 || Name.Length != nameLength - 1)
            {
                throw new InvalidDataException();
            }

            binaryReader.ExpectUInt16(0);
            ushort maxFullPathLength = binaryReader.ReadUInt16();

            binaryReader.ExpectUInt16(0);
            binaryReader.ExpectUInt32(numScopes + numItems);
            binaryReader.ExpectUInt32(numScopes);
            binaryReader.ExpectUInt32(numItems);
            uint unicodeDataLength = binaryReader.ReadUInt32();

            binaryReader.ReadUInt32(); // meaning unknown

            if (extendedHNames)
            {
                binaryReader.ReadUInt32(); // meaning unknown
            }
            List <ScopeAndItemInfo> scopeAndItemInfos = new List <ScopeAndItemInfo>((int)(numScopes + numItems));

            for (int i = 0; i < numScopes + numItems; i++)
            {
                ushort parent             = binaryReader.ReadUInt16();
                ushort fullPathLength     = binaryReader.ReadUInt16();
                char   uppercaseFirstChar = (char)binaryReader.ReadUInt16();
                byte   nameLength2        = binaryReader.ReadByte();
                byte   flags       = binaryReader.ReadByte();
                uint   nameOffset  = binaryReader.ReadUInt16() | (uint)((flags & 0xF) << 16);
                ushort index       = binaryReader.ReadUInt16();
                bool   isScope     = (flags & 0x10) != 0;
                bool   nameInAscii = (flags & 0x20) != 0;
                scopeAndItemInfos.Add(new ScopeAndItemInfo(parent, fullPathLength, isScope, nameInAscii, nameOffset, index));
            }

            List <ScopeExInfo> scopeExInfos = new List <ScopeExInfo>((int)numScopes);

            for (int i = 0; i < numScopes; i++)
            {
                ushort scopeIndex      = binaryReader.ReadUInt16();
                ushort childCount      = binaryReader.ReadUInt16();
                ushort firstChildIndex = binaryReader.ReadUInt16();
                binaryReader.ExpectUInt16(0);
                scopeExInfos.Add(new ScopeExInfo(scopeIndex, childCount, firstChildIndex));
            }

            ushort[] itemIndexPropertyToIndex = new ushort[numItems];
            for (int i = 0; i < numItems; i++)
            {
                itemIndexPropertyToIndex[i] = binaryReader.ReadUInt16();
            }

            long unicodeDataOffset = binaryReader.BaseStream.Position;
            long asciiDataOffset   = binaryReader.BaseStream.Position + unicodeDataLength * 2;

            ResourceMapScope[] scopes = new ResourceMapScope[numScopes];
            ResourceMapItem[]  items  = new ResourceMapItem[numItems];

            for (int i = 0; i < numScopes + numItems; i++)
            {
                long pos;

                if (scopeAndItemInfos[i].NameInAscii)
                {
                    pos = asciiDataOffset + scopeAndItemInfos[i].NameOffset;
                }
                else
                {
                    pos = unicodeDataOffset + scopeAndItemInfos[i].NameOffset * 2;
                }

                binaryReader.BaseStream.Seek(pos, SeekOrigin.Begin);

                string name;

                if (scopeAndItemInfos[i].FullPathLength != 0)
                {
                    name = binaryReader.ReadNullTerminatedString(scopeAndItemInfos[i].NameInAscii ? Encoding.ASCII : Encoding.Unicode);
                }
                else
                {
                    name = string.Empty;
                }

                ushort index = scopeAndItemInfos[i].Index;

                if (scopeAndItemInfos[i].IsScope)
                {
                    if (scopes[index] != null)
                    {
                        throw new InvalidDataException();
                    }

                    scopes[index] = new ResourceMapScope(index, null, name);
                }
                else
                {
                    if (items[index] != null)
                    {
                        throw new InvalidDataException();
                    }

                    items[index] = new ResourceMapItem(index, null, name);
                }
            }

            for (int i = 0; i < numScopes + numItems; i++)
            {
                ushort index = scopeAndItemInfos[i].Index;

                ushort parent = scopeAndItemInfos[scopeAndItemInfos[i].Parent].Index;

                if (parent != 0xFFFF)
                {
                    if (scopeAndItemInfos[i].IsScope)
                    {
                        if (parent != index)
                        {
                            scopes[index].Parent = scopes[parent];
                        }
                    }
                    else
                    {
                        items[index].Parent = scopes[parent];
                    }
                }
            }

            for (int i = 0; i < numScopes; i++)
            {
                List <ResourceMapEntry> children = new List <ResourceMapEntry>(scopeExInfos[i].ChildCount);

                for (int j = 0; j < scopeExInfos[i].ChildCount; j++)
                {
                    ScopeAndItemInfo saiInfo = scopeAndItemInfos[scopeExInfos[i].FirstChildIndex + j];

                    if (saiInfo.IsScope)
                    {
                        children.Add(scopes[saiInfo.Index]);
                    }
                    else
                    {
                        children.Add(items[saiInfo.Index]);
                    }
                }

                scopes[i].Children = children;
            }

            Scopes = scopes;
            Items  = items;

            //if (checksum != ComputeHierarchicalSchemaVersionInfoChecksum())
            //    throw new Exception();

            return(true);
        }
示例#2
0
        protected override bool ParseSectionContent(BinaryReader binaryReader)
        {
            uint numItems = binaryReader.ReadUInt32();

            binaryReader.ExpectUInt32((uint)(binaryReader.BaseStream.Length - 8));

            uint[] mapping = new uint[numItems];
            for (int i = 0; i < numItems; i++)
            {
                mapping[i] = binaryReader.ReadUInt32();
            }
            Mapping = mapping;

            ushort maxFullPathLength = binaryReader.ReadUInt16();

            binaryReader.ExpectUInt16(0);
            uint numEntries = binaryReader.ReadUInt32();
            uint numScopes  = binaryReader.ReadUInt32();

            binaryReader.ExpectUInt32(numItems);
            uint unicodeDataLength = binaryReader.ReadUInt32();

            binaryReader.ReadUInt32();

            List <Tuple <ushort, ushort, uint, uint, ushort> > scopeAndItemInfo = new List <Tuple <ushort, ushort, uint, uint, ushort> >();

            for (int i = 0; i < numScopes + numItems; i++)
            {
                ushort parent         = binaryReader.ReadUInt16();
                ushort fullPathLength = binaryReader.ReadUInt16();
                uint   hashCode       = binaryReader.ReadUInt32();
                uint   nameOffset     = binaryReader.ReadUInt16() | (((hashCode >> 24) & 0xF) << 16);
                ushort index          = binaryReader.ReadUInt16();
                scopeAndItemInfo.Add(new Tuple <ushort, ushort, uint, uint, ushort>(parent, fullPathLength, hashCode, nameOffset, index));
            }

            List <Tuple <ushort, ushort, ushort> > scopeExInfo = new List <Tuple <ushort, ushort, ushort> >();

            for (int i = 0; i < numScopes; i++)
            {
                ushort scopeIndex      = binaryReader.ReadUInt16();
                ushort childCount      = binaryReader.ReadUInt16();
                ushort firstChildIndex = binaryReader.ReadUInt16();
                binaryReader.ExpectUInt16(0);
                scopeExInfo.Add(new Tuple <ushort, ushort, ushort>(scopeIndex, childCount, firstChildIndex));
            }

            ushort[] itemIndexPropertyToIndex = new ushort[numItems];
            for (int i = 0; i < numItems; i++)
            {
                itemIndexPropertyToIndex[i] = binaryReader.ReadUInt16();
            }

            long unicodeDataOffset = binaryReader.BaseStream.Position;
            long asciiDataOffset   = binaryReader.BaseStream.Position + unicodeDataLength * 2;

            ResourceMapScope[] scopes = new ResourceMapScope[numScopes];
            ResourceMapItem[]  items  = new ResourceMapItem[numItems];

            for (int i = 0; i < numScopes + numItems; i++)
            {
                bool nameInAscii = (scopeAndItemInfo[i].Item3 & 0x20000000) != 0;
                long pos         = (nameInAscii ? asciiDataOffset : unicodeDataOffset) + (scopeAndItemInfo[i].Item4 * (nameInAscii ? 1 : 2));

                binaryReader.BaseStream.Seek(pos, SeekOrigin.Begin);

                string name;

                if (scopeAndItemInfo[i].Item2 != 0)
                {
                    name = binaryReader.ReadNullTerminatedString(nameInAscii ? Encoding.ASCII : Encoding.Unicode);
                }
                else
                {
                    name = string.Empty;
                }

                ushort index = scopeAndItemInfo[i].Item5;

                bool isScope = (scopeAndItemInfo[i].Item3 & 0x10000000) != 0;

                if (isScope)
                {
                    if (scopes[index] != null)
                    {
                        throw new InvalidDataException();
                    }

                    scopes[index] = new ResourceMapScope(index, null, name);
                }
                else
                {
                    if (items[index] != null)
                    {
                        throw new InvalidDataException();
                    }

                    items[index] = new ResourceMapItem(index, null, name);
                }
            }

            for (int i = 0; i < numScopes + numItems; i++)
            {
                ushort index = scopeAndItemInfo[i].Item5;

                bool isScope = (scopeAndItemInfo[i].Item3 & 0x10000000) != 0;

                ushort parent = scopeAndItemInfo[i].Item1;

                parent = scopeAndItemInfo[parent].Item5;

                if (parent != 0xFFFF)
                {
                    if (isScope)
                    {
                        if (parent != index)
                        {
                            scopes[index].Parent = scopes[parent];
                        }
                    }
                    else
                    {
                        items[index].Parent = scopes[parent];
                    }
                }
            }

            for (int i = 0; i < numScopes; i++)
            {
                ResourceMapEntry[] children = new ResourceMapEntry[scopeExInfo[i].Item2];

                for (int j = 0; j < children.Length; j++)
                {
                    var saiInfo = scopeAndItemInfo[scopeExInfo[i].Item3 + j];

                    bool isScope = (saiInfo.Item3 & 0x10000000) != 0;

                    if (isScope)
                    {
                        children[j] = scopes[saiInfo.Item5];
                    }
                    else
                    {
                        children[j] = items[saiInfo.Item5];
                    }
                }

                scopes[i].Children = children;
            }

            Scopes = scopes;
            Items  = items;

            return(true);
        }