protected override bool ParseSectionContent(BinaryReader binaryReader) { PriFlags = (PriDescriptorFlags)binaryReader.ReadUInt16(); ushort includedFileListSection = binaryReader.ReadUInt16(); binaryReader.ExpectUInt16(0); ushort numHierarchicalSchemaSections = binaryReader.ReadUInt16(); ushort numDecisionInfoSections = binaryReader.ReadUInt16(); ushort numResourceMapSections = binaryReader.ReadUInt16(); ushort primaryResourceMapSection = binaryReader.ReadUInt16(); if (primaryResourceMapSection != 0xFFFF) PrimaryResourceMapSection = new SectionRef<ResourceMapSection>(primaryResourceMapSection); else PrimaryResourceMapSection = null; ushort numReferencedFileSections = binaryReader.ReadUInt16(); ushort numDataItemSections = binaryReader.ReadUInt16(); binaryReader.ExpectUInt16(0); List<SectionRef<HierarchicalSchemaSection>> hierarchicalSchemaSections = new List<SectionRef<HierarchicalSchemaSection>>(numHierarchicalSchemaSections); for (int i = 0; i < numHierarchicalSchemaSections; i++) hierarchicalSchemaSections.Add(new SectionRef<HierarchicalSchemaSection>(binaryReader.ReadUInt16())); HierarchicalSchemaSections = hierarchicalSchemaSections; List<SectionRef<DecisionInfoSection>> decisionInfoSections = new List<SectionRef<DecisionInfoSection>>(numDecisionInfoSections); for (int i = 0; i < numDecisionInfoSections; i++) decisionInfoSections.Add(new SectionRef<DecisionInfoSection>(binaryReader.ReadUInt16())); DecisionInfoSections = decisionInfoSections; List<SectionRef<ResourceMapSection>> resourceMapSections = new List<SectionRef<ResourceMapSection>>(numResourceMapSections); for (int i = 0; i < numResourceMapSections; i++) resourceMapSections.Add(new SectionRef<ResourceMapSection>(binaryReader.ReadUInt16())); ResourceMapSections = resourceMapSections; List<SectionRef<ReferencedFileSection>> referencedFileSections = new List<SectionRef<ReferencedFileSection>>(numReferencedFileSections); for (int i = 0; i < numReferencedFileSections; i++) referencedFileSections.Add(new SectionRef<ReferencedFileSection>(binaryReader.ReadUInt16())); ReferencedFileSections = referencedFileSections; List<SectionRef<DataItemSection>> dataItemSections = new List<SectionRef<DataItemSection>>(numDataItemSections); for (int i = 0; i < numDataItemSections; i++) dataItemSections.Add(new SectionRef<DataItemSection>(binaryReader.ReadUInt16())); DataItemSections = dataItemSections; return true; }
internal ResourceMapItemRef(SectionRef <HierarchicalSchemaSection> schemaSection, int itemIndex) { this.schemaSection = schemaSection; this.itemIndex = itemIndex; }
public T GetSectionByRef <T>(SectionRef <T> sectionRef) where T : Section { return((T)Sections[sectionRef.sectionIndex]); }
protected override bool ParseSectionContent(BinaryReader binaryReader) { long sectionPosition = (binaryReader.BaseStream as SubStream)?.SubStreamPosition ?? 0; ushort environmentReferencesLength = binaryReader.ReadUInt16(); ushort numEnvironmentReferences = binaryReader.ReadUInt16(); if (!version2) { if (environmentReferencesLength == 0 || numEnvironmentReferences == 0) { throw new InvalidDataException(); } } else { if (environmentReferencesLength != 0 || numEnvironmentReferences != 0) { throw new InvalidDataException(); } } SchemaSection = new SectionRef <HierarchicalSchemaSection>(binaryReader.ReadUInt16()); ushort hierarchicalSchemaReferenceLength = binaryReader.ReadUInt16(); DecisionInfoSection = new SectionRef <DecisionInfoSection>(binaryReader.ReadUInt16()); ushort resourceValueTypeTableSize = binaryReader.ReadUInt16(); ushort ItemToItemInfoGroupCount = binaryReader.ReadUInt16(); ushort itemInfoGroupCount = binaryReader.ReadUInt16(); uint itemInfoCount = binaryReader.ReadUInt32(); uint numCandidates = binaryReader.ReadUInt32(); uint dataLength = binaryReader.ReadUInt32(); uint largeTableLength = binaryReader.ReadUInt32(); if (PriFile.GetSectionByRef(DecisionInfoSection) == null) { return(false); } byte[] environmentReferencesData = binaryReader.ReadBytes(environmentReferencesLength); byte[] schemaReferenceData = binaryReader.ReadBytes(hierarchicalSchemaReferenceLength); if (schemaReferenceData.Length != 0) { using (BinaryReader r = new BinaryReader(new MemoryStream(schemaReferenceData, false))) { ushort majorVersion = r.ReadUInt16(); ushort minorVersion = r.ReadUInt16(); r.ExpectUInt32(0); uint checksum = r.ReadUInt32(); uint numScopes = r.ReadUInt32(); uint numItems = r.ReadUInt32(); HierarchicalSchemaVersionInfo versionInfo = new HierarchicalSchemaVersionInfo(majorVersion, minorVersion, checksum, numScopes, numItems); ushort stringDataLength = r.ReadUInt16(); r.ExpectUInt16(0); uint unknown1 = r.ReadUInt32(); uint unknown2 = r.ReadUInt32(); string uniqueName = r.ReadNullTerminatedString(Encoding.Unicode); if (uniqueName.Length != stringDataLength - 1) { throw new InvalidDataException(); } HierarchicalSchemaReference = new HierarchicalSchemaReference(versionInfo, unknown1, unknown2, uniqueName); } } List <ResourceValueType> resourceValueTypeTable = new List <ResourceValueType>(resourceValueTypeTableSize); for (int i = 0; i < resourceValueTypeTableSize; i++) { binaryReader.ExpectUInt32(4); ResourceValueType resourceValueType = (ResourceValueType)binaryReader.ReadUInt32(); resourceValueTypeTable.Add(resourceValueType); } List <ItemToItemInfoGroup> itemToItemInfoGroups = new List <ItemToItemInfoGroup>(); for (int i = 0; i < ItemToItemInfoGroupCount; i++) { ushort firstItem = binaryReader.ReadUInt16(); ushort itemInfoGroup = binaryReader.ReadUInt16(); itemToItemInfoGroups.Add(new ItemToItemInfoGroup(firstItem, itemInfoGroup)); } List <ItemInfoGroup> itemInfoGroups = new List <ItemInfoGroup>(); for (int i = 0; i < itemInfoGroupCount; i++) { ushort groupSize = binaryReader.ReadUInt16(); ushort firstItemInfo = binaryReader.ReadUInt16(); itemInfoGroups.Add(new ItemInfoGroup(groupSize, firstItemInfo)); } List <ItemInfo> itemInfos = new List <ItemInfo>(); for (int i = 0; i < itemInfoCount; i++) { ushort decision = binaryReader.ReadUInt16(); ushort firstCandidate = binaryReader.ReadUInt16(); itemInfos.Add(new ItemInfo(decision, firstCandidate)); } byte[] largeTable = binaryReader.ReadBytes((int)largeTableLength); if (largeTable.Length != 0) { using (BinaryReader r = new BinaryReader(new MemoryStream(largeTable, false))) { uint ItemToItemInfoGroupCountLarge = r.ReadUInt32(); uint itemInfoGroupCountLarge = r.ReadUInt32(); uint itemInfoCountLarge = r.ReadUInt32(); for (int i = 0; i < ItemToItemInfoGroupCountLarge; i++) { uint firstItem = r.ReadUInt32(); uint itemInfoGroup = r.ReadUInt32(); itemToItemInfoGroups.Add(new ItemToItemInfoGroup(firstItem, itemInfoGroup)); } for (int i = 0; i < itemInfoGroupCountLarge; i++) { uint groupSize = r.ReadUInt32(); uint firstItemInfo = r.ReadUInt32(); itemInfoGroups.Add(new ItemInfoGroup(groupSize, firstItemInfo)); } for (int i = 0; i < itemInfoCountLarge; i++) { uint decision = r.ReadUInt32(); uint firstCandidate = r.ReadUInt32(); itemInfos.Add(new ItemInfo(decision, firstCandidate)); } if (r.BaseStream.Position != r.BaseStream.Length) { throw new InvalidDataException(); } } } List <CandidateInfo> candidateInfos = new List <CandidateInfo>((int)numCandidates); for (int i = 0; i < numCandidates; i++) { byte type = binaryReader.ReadByte(); if (type == 0x01) { ResourceValueType resourceValueType = resourceValueTypeTable[binaryReader.ReadByte()]; ushort sourceFileIndex = binaryReader.ReadUInt16(); ushort valueLocation = binaryReader.ReadUInt16(); ushort dataItemSection = binaryReader.ReadUInt16(); candidateInfos.Add(new CandidateInfo(resourceValueType, sourceFileIndex, valueLocation, dataItemSection)); } else if (type == 0x00) { ResourceValueType resourceValueType = resourceValueTypeTable[binaryReader.ReadByte()]; ushort length = binaryReader.ReadUInt16(); uint stringOffset = binaryReader.ReadUInt32(); candidateInfos.Add(new CandidateInfo(resourceValueType, length, stringOffset)); } else { throw new InvalidDataException(); } } long stringDataStartOffset = binaryReader.BaseStream.Position; Dictionary <ushort, CandidateSet> candidateSets = new Dictionary <ushort, CandidateSet>(); for (int itemToItemInfoGroupIndex = 0; itemToItemInfoGroupIndex < itemToItemInfoGroups.Count; itemToItemInfoGroupIndex++) { ItemToItemInfoGroup itemToItemInfoGroup = itemToItemInfoGroups[itemToItemInfoGroupIndex]; ItemInfoGroup itemInfoGroup; if (itemToItemInfoGroup.ItemInfoGroup < itemInfoGroups.Count) { itemInfoGroup = itemInfoGroups[(int)itemToItemInfoGroup.ItemInfoGroup]; } else { itemInfoGroup = new ItemInfoGroup(1, (uint)(itemToItemInfoGroup.ItemInfoGroup - itemInfoGroups.Count)); } for (uint itemInfoIndex = itemInfoGroup.FirstItemInfo; itemInfoIndex < itemInfoGroup.FirstItemInfo + itemInfoGroup.GroupSize; itemInfoIndex++) { ItemInfo itemInfo = itemInfos[(int)itemInfoIndex]; ushort decisionIndex = (ushort)itemInfo.Decision; Decision decision = PriFile.GetSectionByRef(DecisionInfoSection).Decisions[decisionIndex]; List <Candidate> candidates = new List <Candidate>(decision.QualifierSets.Count); for (int i = 0; i < decision.QualifierSets.Count; i++) { CandidateInfo candidateInfo = candidateInfos[(int)itemInfo.FirstCandidate + i]; if (candidateInfo.Type == 0x01) { ReferencedFileRef?sourceFile; if (candidateInfo.SourceFileIndex == 0) { sourceFile = null; } else { sourceFile = new ReferencedFileRef(candidateInfo.SourceFileIndex - 1); } candidates.Add(new Candidate(decision.QualifierSets[i].Index, candidateInfo.ResourceValueType, sourceFile, new DataItemRef(new SectionRef <DataItemSection>(candidateInfo.DataItemSection), candidateInfo.DataItemIndex))); } else if (candidateInfo.Type == 0x00) { ByteSpan data = new ByteSpan(sectionPosition + stringDataStartOffset + candidateInfo.DataOffset, candidateInfo.DataLength); candidates.Add(new Candidate(decision.QualifierSets[i].Index, candidateInfo.ResourceValueType, data)); } } ushort resourceMapItemIndex = (ushort)(itemToItemInfoGroup.FirstItem + (itemInfoIndex - itemInfoGroup.FirstItemInfo)); CandidateSet candidateSet = new CandidateSet( new ResourceMapItemRef(SchemaSection, resourceMapItemIndex), decisionIndex, candidates); candidateSets.Add(resourceMapItemIndex, candidateSet); } } CandidateSets = candidateSets; return(true); }
internal DataItemRef(SectionRef <DataItemSection> dataItemSection, int itemIndex) { this.dataItemSection = dataItemSection; this.itemIndex = itemIndex; }