internal static Section CreateForIdentifier(string sectionIdentifier, PriFile priFile) { switch (sectionIdentifier) { case PriDescriptorSection.Identifier: return(new PriDescriptorSection(priFile)); case HierarchicalSchemaSection.Identifier1: return(new HierarchicalSchemaSection(priFile, false)); case HierarchicalSchemaSection.Identifier2: return(new HierarchicalSchemaSection(priFile, true)); case DecisionInfoSection.Identifier: return(new DecisionInfoSection(priFile)); case ResourceMapSection.Identifier1: return(new ResourceMapSection(priFile, false)); case ResourceMapSection.Identifier2: return(new ResourceMapSection(priFile, true)); case DataItemSection.Identifier: return(new DataItemSection(priFile)); case ReverseMapSection.Identifier: return(new ReverseMapSection(priFile)); case ReferencedFileSection.Identifier: return(new ReferencedFileSection(priFile)); default: return(new UnknownSection(sectionIdentifier, priFile)); } }
public static PriFile Parse(Stream stream) { PriFile priFile = new PriFile(); priFile.ParseInternal(stream); return(priFile); }
protected Section(string sectionIdentifier, PriFile priFile) { if (sectionIdentifier.Length != 16) { throw new ArgumentException("Section identifiers need to be exactly 16 characters long.", nameof(sectionIdentifier)); } SectionIdentifier = sectionIdentifier; PriFile = priFile; }
internal PriDescriptorSection(PriFile priFile) : base(Identifier, priFile) { }
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 ResourceMapSection(PriFile priFile, bool version2) : base(version2 ? Identifier2 : Identifier1, priFile) { this.version2 = version2; }
internal DecisionInfoSection(PriFile priFile) : base(Identifier, priFile) { }
internal ReferencedFileSection(PriFile priFile) : base(Identifier, priFile) { }
internal DataItemSection(PriFile priFile) : base(Identifier, priFile) { }
internal UnknownSection(string sectionIdentifier, PriFile priFile) : base(sectionIdentifier, priFile) { }
internal HierarchicalSchemaSection(PriFile priFile, bool extendedVersion) : base(extendedVersion ? Identifier2 : Identifier1, priFile) { this.extendedVersion = extendedVersion; }
internal ReverseMapSection(PriFile priFile) : base(Identifier, priFile) { }