internal ResourceMapItem(ushort index, ResourceMapScope parent, string name) : base(index, parent, name) { }
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); }
internal ResourceMapEntry(ushort index, ResourceMapScope parent, string name) { Index = index; Parent = parent; Name = name; }
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); }