Files
App-Installer-For-Windows-8…/PriFormat/Section.cs
2026-01-27 22:47:49 +08:00

127 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace PriFormat
{
public abstract class Section: IDisposable
{
protected PriFile PriFile { get; private set; }
public string SectionIdentifier { get; private set; }
public uint SectionQualifier { get; private set; }
public uint Flags { get; private set; }
public uint SectionFlags { get; private set; }
public uint SectionLength { get; private set; }
protected Section (string sectionIdentifier, PriFile priFile)
{
if (sectionIdentifier == null)
throw new ArgumentNullException ("sectionIdentifier");
if (sectionIdentifier.Length != 16)
throw new ArgumentException (
"Section identifiers must be exactly 16 characters long.",
"sectionIdentifier");
SectionIdentifier = sectionIdentifier;
PriFile = priFile;
}
internal bool Parse (BinaryReader binaryReader)
{
// identifier
string identifier = new string (binaryReader.ReadChars (16));
if (identifier != SectionIdentifier)
throw new InvalidDataException ("Unexpected section identifier.");
SectionQualifier = binaryReader.ReadUInt32 ();
Flags = binaryReader.ReadUInt16 ();
SectionFlags = binaryReader.ReadUInt16 ();
SectionLength = binaryReader.ReadUInt32 ();
binaryReader.ExpectUInt32 (0);
// 跳到 section 尾部校验
long contentLength = SectionLength - 16 - 24;
binaryReader.BaseStream.Seek (contentLength, SeekOrigin.Current);
binaryReader.ExpectUInt32 (0xDEF5FADE);
binaryReader.ExpectUInt32 (SectionLength);
// 回到 section 内容起始位置
binaryReader.BaseStream.Seek (-8 - contentLength, SeekOrigin.Current);
//关键点SubStream + BinaryReader 生命周期
using (SubStream subStream = new SubStream (
binaryReader.BaseStream,
binaryReader.BaseStream.Position,
contentLength))
{
using (BinaryReader subReader =
new BinaryReader (subStream, Encoding.ASCII))
{
return ParseSectionContent (subReader);
}
}
}
protected abstract bool ParseSectionContent (BinaryReader binaryReader);
public override string ToString ()
{
return SectionIdentifier.TrimEnd ('\0', ' ') +
" length: " + SectionLength;
}
internal static Section CreateForIdentifier (
string sectionIdentifier,
PriFile priFile)
{
if (sectionIdentifier == null)
throw new ArgumentNullException ("sectionIdentifier");
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 virtual void Dispose ()
{
this.PriFile = null;
}
}
}