mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1144 lines
29 KiB
1144 lines
29 KiB
/* |
|
Copyright (c) 2015 Ki |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
of this software and associated documentation files (the "Software"), to deal |
|
in the Software without restriction, including without limitation the rights |
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
copies of the Software, and to permit persons to whom the Software is |
|
furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included in |
|
all copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
THE SOFTWARE. |
|
*/ |
|
|
|
using System; |
|
using System.Diagnostics; |
|
using System.IO; |
|
|
|
namespace ICSharpCode.BamlDecompiler.Baml |
|
{ |
|
internal enum BamlRecordType : byte |
|
{ |
|
ClrEvent = 0x13, |
|
Comment = 0x17, |
|
AssemblyInfo = 0x1c, |
|
AttributeInfo = 0x1f, |
|
ConstructorParametersStart = 0x2a, |
|
ConstructorParametersEnd = 0x2b, |
|
ConstructorParameterType = 0x2c, |
|
ConnectionId = 0x2d, |
|
ContentProperty = 0x2e, |
|
DefAttribute = 0x19, |
|
DefAttributeKeyString = 0x26, |
|
DefAttributeKeyType = 0x27, |
|
DeferableContentStart = 0x25, |
|
DefTag = 0x18, |
|
DocumentEnd = 0x2, |
|
DocumentStart = 0x1, |
|
ElementEnd = 0x4, |
|
ElementStart = 0x3, |
|
EndAttributes = 0x1a, |
|
KeyElementEnd = 0x29, |
|
KeyElementStart = 0x28, |
|
LastRecordType = 0x39, |
|
LineNumberAndPosition = 0x35, |
|
LinePosition = 0x36, |
|
LiteralContent = 0xf, |
|
NamedElementStart = 0x2f, |
|
OptimizedStaticResource = 0x37, |
|
PIMapping = 0x1b, |
|
PresentationOptionsAttribute = 0x34, |
|
ProcessingInstruction = 0x16, |
|
Property = 0x5, |
|
PropertyArrayEnd = 0xa, |
|
PropertyArrayStart = 0x9, |
|
PropertyComplexEnd = 0x8, |
|
PropertyComplexStart = 0x7, |
|
PropertyCustom = 0x6, |
|
PropertyDictionaryEnd = 0xe, |
|
PropertyDictionaryStart = 0xd, |
|
PropertyListEnd = 0xc, |
|
PropertyListStart = 0xb, |
|
PropertyStringReference = 0x21, |
|
PropertyTypeReference = 0x22, |
|
PropertyWithConverter = 0x24, |
|
PropertyWithExtension = 0x23, |
|
PropertyWithStaticResourceId = 0x38, |
|
RoutedEvent = 0x12, |
|
StaticResourceEnd = 0x31, |
|
StaticResourceId = 0x32, |
|
StaticResourceStart = 0x30, |
|
StringInfo = 0x20, |
|
Text = 0x10, |
|
TextWithConverter = 0x11, |
|
TextWithId = 0x33, |
|
TypeInfo = 0x1d, |
|
TypeSerializerInfo = 0x1e, |
|
XmlAttribute = 0x15, |
|
XmlnsProperty = 0x14 |
|
} |
|
|
|
internal abstract class BamlRecord |
|
{ |
|
public abstract BamlRecordType Type { get; } |
|
public long Position { get; internal set; } |
|
public abstract void Read(BamlBinaryReader reader); |
|
public abstract void Write(BamlBinaryWriter writer); |
|
} |
|
|
|
internal abstract class SizedBamlRecord : BamlRecord |
|
{ |
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
long pos = reader.BaseStream.Position; |
|
int size = reader.ReadEncodedInt(); |
|
|
|
ReadData(reader, size - (int)(reader.BaseStream.Position - pos)); |
|
} |
|
|
|
int SizeofEncodedInt(int val) |
|
{ |
|
if ((val & ~0x7F) == 0) |
|
{ |
|
return 1; |
|
} |
|
if ((val & ~0x3FFF) == 0) |
|
{ |
|
return 2; |
|
} |
|
if ((val & ~0x1FFFFF) == 0) |
|
{ |
|
return 3; |
|
} |
|
if ((val & ~0xFFFFFFF) == 0) |
|
{ |
|
return 4; |
|
} |
|
return 5; |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
long pos = writer.BaseStream.Position; |
|
WriteData(writer); |
|
var size = (int)(writer.BaseStream.Position - pos); |
|
size = SizeofEncodedInt(SizeofEncodedInt(size) + size) + size; |
|
writer.BaseStream.Position = pos; |
|
writer.WriteEncodedInt(size); |
|
WriteData(writer); |
|
} |
|
|
|
protected abstract void ReadData(BamlBinaryReader reader, int size); |
|
protected abstract void WriteData(BamlBinaryWriter writer); |
|
} |
|
|
|
internal interface IBamlDeferRecord |
|
{ |
|
long Position { get; } |
|
BamlRecord Record { get; set; } |
|
void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve); |
|
void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr); |
|
} |
|
|
|
internal class XmlnsPropertyRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.XmlnsProperty; |
|
|
|
public string Prefix { get; set; } |
|
public string XmlNamespace { get; set; } |
|
public ushort[] AssemblyIds { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
Prefix = reader.ReadString(); |
|
XmlNamespace = reader.ReadString(); |
|
AssemblyIds = new ushort[reader.ReadUInt16()]; |
|
for (int i = 0; i < AssemblyIds.Length; i++) |
|
AssemblyIds[i] = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Prefix); |
|
writer.Write(XmlNamespace); |
|
writer.Write((ushort)AssemblyIds.Length); |
|
foreach (ushort i in AssemblyIds) |
|
writer.Write(i); |
|
} |
|
} |
|
|
|
internal class PresentationOptionsAttributeRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PresentationOptionsAttribute; |
|
|
|
public string Value { get; set; } |
|
public ushort NameId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
Value = reader.ReadString(); |
|
NameId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Value); |
|
writer.Write(NameId); |
|
} |
|
} |
|
|
|
internal class PIMappingRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PIMapping; |
|
|
|
public string XmlNamespace { get; set; } |
|
public string ClrNamespace { get; set; } |
|
public ushort AssemblyId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
XmlNamespace = reader.ReadString(); |
|
ClrNamespace = reader.ReadString(); |
|
AssemblyId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(XmlNamespace); |
|
writer.Write(ClrNamespace); |
|
writer.Write(AssemblyId); |
|
} |
|
} |
|
|
|
internal class AssemblyInfoRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.AssemblyInfo; |
|
|
|
public ushort AssemblyId { get; set; } |
|
public string AssemblyFullName { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
AssemblyId = reader.ReadUInt16(); |
|
AssemblyFullName = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AssemblyId); |
|
writer.Write(AssemblyFullName); |
|
} |
|
} |
|
|
|
internal class PropertyRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.Property; |
|
|
|
public ushort AttributeId { get; set; } |
|
public string Value { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
AttributeId = reader.ReadUInt16(); |
|
Value = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AttributeId); |
|
writer.Write(Value); |
|
} |
|
} |
|
|
|
internal class PropertyWithConverterRecord : PropertyRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyWithConverter; |
|
|
|
public ushort ConverterTypeId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
base.ReadData(reader, size); |
|
ConverterTypeId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
base.WriteData(writer); |
|
writer.Write(ConverterTypeId); |
|
} |
|
} |
|
|
|
internal class PropertyCustomRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyCustom; |
|
|
|
public ushort AttributeId { get; set; } |
|
public ushort SerializerTypeId { get; set; } |
|
public byte[] Data { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
long pos = reader.BaseStream.Position; |
|
AttributeId = reader.ReadUInt16(); |
|
SerializerTypeId = reader.ReadUInt16(); |
|
Data = reader.ReadBytes(size - (int)(reader.BaseStream.Position - pos)); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AttributeId); |
|
writer.Write(SerializerTypeId); |
|
writer.Write(Data); |
|
} |
|
} |
|
|
|
internal class DefAttributeRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.DefAttribute; |
|
|
|
public string Value { get; set; } |
|
public ushort NameId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
Value = reader.ReadString(); |
|
NameId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Value); |
|
writer.Write(NameId); |
|
} |
|
} |
|
|
|
internal class DefAttributeKeyStringRecord : SizedBamlRecord, IBamlDeferRecord |
|
{ |
|
internal uint pos = 0xffffffff; |
|
|
|
public override BamlRecordType Type => BamlRecordType.DefAttributeKeyString; |
|
|
|
public ushort ValueId { get; set; } |
|
public bool Shared { get; set; } |
|
public bool SharedSet { get; set; } |
|
|
|
public BamlRecord Record { get; set; } |
|
|
|
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) |
|
{ |
|
bool keys = true; |
|
do |
|
{ |
|
switch (doc[index].Type) |
|
{ |
|
case BamlRecordType.DefAttributeKeyString: |
|
case BamlRecordType.DefAttributeKeyType: |
|
case BamlRecordType.OptimizedStaticResource: |
|
keys = true; |
|
break; |
|
case BamlRecordType.StaticResourceStart: |
|
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index); |
|
keys = true; |
|
break; |
|
case BamlRecordType.KeyElementStart: |
|
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index); |
|
keys = true; |
|
break; |
|
default: |
|
keys = false; |
|
index--; |
|
break; |
|
} |
|
index++; |
|
} while (keys); |
|
Record = resolve(doc[index].Position + pos); |
|
} |
|
|
|
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) |
|
{ |
|
bool keys = true; |
|
do |
|
{ |
|
switch (doc[index].Type) |
|
{ |
|
case BamlRecordType.DefAttributeKeyString: |
|
case BamlRecordType.DefAttributeKeyType: |
|
case BamlRecordType.OptimizedStaticResource: |
|
keys = true; |
|
break; |
|
case BamlRecordType.StaticResourceStart: |
|
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index); |
|
keys = true; |
|
break; |
|
case BamlRecordType.KeyElementStart: |
|
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index); |
|
keys = true; |
|
break; |
|
default: |
|
keys = false; |
|
index--; |
|
break; |
|
} |
|
index++; |
|
} while (keys); |
|
wtr.BaseStream.Seek(pos, SeekOrigin.Begin); |
|
wtr.Write((uint)(Record.Position - doc[index].Position)); |
|
} |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
ValueId = reader.ReadUInt16(); |
|
pos = reader.ReadUInt32(); |
|
Shared = reader.ReadBoolean(); |
|
SharedSet = reader.ReadBoolean(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(ValueId); |
|
pos = (uint)writer.BaseStream.Position; |
|
writer.Write((uint)0); |
|
writer.Write(Shared); |
|
writer.Write(SharedSet); |
|
} |
|
|
|
static void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index) |
|
{ |
|
index++; |
|
while (true) //Assume there alway is a end |
|
{ |
|
if (doc[index].Type == start) |
|
NavigateTree(doc, start, end, ref index); |
|
else if (doc[index].Type == end) |
|
return; |
|
index++; |
|
} |
|
} |
|
} |
|
|
|
internal class TypeInfoRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.TypeInfo; |
|
|
|
public ushort TypeId { get; set; } |
|
public ushort AssemblyId { get; set; } |
|
public string TypeFullName { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
TypeId = reader.ReadUInt16(); |
|
AssemblyId = reader.ReadUInt16(); |
|
TypeFullName = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(TypeId); |
|
writer.Write(AssemblyId); |
|
writer.Write(TypeFullName); |
|
} |
|
} |
|
|
|
internal class TypeSerializerInfoRecord : TypeInfoRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.TypeSerializerInfo; |
|
|
|
public ushort SerializerTypeId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
base.ReadData(reader, size); |
|
SerializerTypeId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
base.WriteData(writer); |
|
writer.Write(SerializerTypeId); |
|
} |
|
} |
|
|
|
internal class AttributeInfoRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.AttributeInfo; |
|
|
|
public ushort AttributeId { get; set; } |
|
public ushort OwnerTypeId { get; set; } |
|
public byte AttributeUsage { get; set; } |
|
public string Name { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
AttributeId = reader.ReadUInt16(); |
|
OwnerTypeId = reader.ReadUInt16(); |
|
AttributeUsage = reader.ReadByte(); |
|
Name = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AttributeId); |
|
writer.Write(OwnerTypeId); |
|
writer.Write(AttributeUsage); |
|
writer.Write(Name); |
|
} |
|
} |
|
|
|
internal class StringInfoRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.StringInfo; |
|
|
|
public ushort StringId { get; set; } |
|
public string Value { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
StringId = reader.ReadUInt16(); |
|
Value = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(StringId); |
|
writer.Write(Value); |
|
} |
|
} |
|
|
|
internal class TextRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.Text; |
|
|
|
public string Value { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) => Value = reader.ReadString(); |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) => writer.Write(Value); |
|
} |
|
|
|
internal class TextWithConverterRecord : TextRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.TextWithConverter; |
|
|
|
public ushort ConverterTypeId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
base.ReadData(reader, size); |
|
ConverterTypeId = reader.ReadUInt16(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
base.WriteData(writer); |
|
writer.Write(ConverterTypeId); |
|
} |
|
} |
|
|
|
internal class TextWithIdRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.TextWithId; |
|
|
|
public ushort ValueId { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) => ValueId = reader.ReadUInt16(); |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) => writer.Write(ValueId); |
|
} |
|
|
|
internal class LiteralContentRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.LiteralContent; |
|
|
|
public string Value { get; set; } |
|
public uint Reserved0 { get; set; } |
|
public uint Reserved1 { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
Value = reader.ReadString(); |
|
Reserved0 = reader.ReadUInt32(); |
|
Reserved1 = reader.ReadUInt32(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Value); |
|
writer.Write(Reserved0); |
|
writer.Write(Reserved1); |
|
} |
|
} |
|
|
|
internal class RoutedEventRecord : SizedBamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.RoutedEvent; |
|
|
|
public string Value { get; set; } |
|
public ushort AttributeId { get; set; } |
|
public uint Reserved1 { get; set; } |
|
|
|
protected override void ReadData(BamlBinaryReader reader, int size) |
|
{ |
|
AttributeId = reader.ReadUInt16(); |
|
Value = reader.ReadString(); |
|
} |
|
|
|
protected override void WriteData(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Value); |
|
writer.Write(AttributeId); |
|
} |
|
} |
|
|
|
internal class DocumentStartRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.DocumentStart; |
|
|
|
public bool LoadAsync { get; set; } |
|
public uint MaxAsyncRecords { get; set; } |
|
public bool DebugBaml { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
LoadAsync = reader.ReadBoolean(); |
|
MaxAsyncRecords = reader.ReadUInt32(); |
|
DebugBaml = reader.ReadBoolean(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(LoadAsync); |
|
writer.Write(MaxAsyncRecords); |
|
writer.Write(DebugBaml); |
|
} |
|
} |
|
|
|
internal class DocumentEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.DocumentEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class ElementStartRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ElementStart; |
|
|
|
public ushort TypeId { get; set; } |
|
public byte Flags { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
TypeId = reader.ReadUInt16(); |
|
Flags = reader.ReadByte(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(TypeId); |
|
writer.Write(Flags); |
|
} |
|
} |
|
|
|
internal class ElementEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ElementEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class KeyElementStartRecord : DefAttributeKeyTypeRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.KeyElementStart; |
|
} |
|
|
|
internal class KeyElementEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.KeyElementEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class ConnectionIdRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ConnectionId; |
|
|
|
public uint ConnectionId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => ConnectionId = reader.ReadUInt32(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(ConnectionId); |
|
} |
|
|
|
internal class PropertyWithExtensionRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyWithExtension; |
|
|
|
public ushort AttributeId { get; set; } |
|
public ushort Flags { get; set; } |
|
public ushort ValueId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
AttributeId = reader.ReadUInt16(); |
|
Flags = reader.ReadUInt16(); |
|
ValueId = reader.ReadUInt16(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AttributeId); |
|
writer.Write(Flags); |
|
writer.Write(ValueId); |
|
} |
|
} |
|
|
|
internal class PropertyTypeReferenceRecord : PropertyComplexStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyTypeReference; |
|
|
|
public ushort TypeId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
base.Read(reader); |
|
TypeId = reader.ReadUInt16(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
base.Write(writer); |
|
writer.Write(TypeId); |
|
} |
|
} |
|
|
|
internal class PropertyStringReferenceRecord : PropertyComplexStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyStringReference; |
|
|
|
public ushort StringId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
base.Read(reader); |
|
StringId = reader.ReadUInt16(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
base.Write(writer); |
|
writer.Write(StringId); |
|
} |
|
} |
|
|
|
internal class PropertyWithStaticResourceIdRecord : StaticResourceIdRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyWithStaticResourceId; |
|
|
|
public ushort AttributeId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
AttributeId = reader.ReadUInt16(); |
|
base.Read(reader); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(AttributeId); |
|
base.Write(writer); |
|
} |
|
} |
|
|
|
internal class ContentPropertyRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ContentProperty; |
|
|
|
public ushort AttributeId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId); |
|
} |
|
|
|
internal class DefAttributeKeyTypeRecord : ElementStartRecord, IBamlDeferRecord |
|
{ |
|
internal uint pos = 0xffffffff; |
|
|
|
public override BamlRecordType Type => BamlRecordType.DefAttributeKeyType; |
|
|
|
public bool Shared { get; set; } |
|
public bool SharedSet { get; set; } |
|
|
|
public BamlRecord Record { get; set; } |
|
|
|
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) |
|
{ |
|
bool keys = true; |
|
do |
|
{ |
|
switch (doc[index].Type) |
|
{ |
|
case BamlRecordType.DefAttributeKeyString: |
|
case BamlRecordType.DefAttributeKeyType: |
|
case BamlRecordType.OptimizedStaticResource: |
|
keys = true; |
|
break; |
|
case BamlRecordType.StaticResourceStart: |
|
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index); |
|
keys = true; |
|
break; |
|
case BamlRecordType.KeyElementStart: |
|
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index); |
|
keys = true; |
|
break; |
|
default: |
|
keys = false; |
|
index--; |
|
break; |
|
} |
|
index++; |
|
} while (keys); |
|
Record = resolve(doc[index].Position + pos); |
|
} |
|
|
|
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) |
|
{ |
|
bool keys = true; |
|
do |
|
{ |
|
switch (doc[index].Type) |
|
{ |
|
case BamlRecordType.DefAttributeKeyString: |
|
case BamlRecordType.DefAttributeKeyType: |
|
case BamlRecordType.OptimizedStaticResource: |
|
keys = true; |
|
break; |
|
case BamlRecordType.StaticResourceStart: |
|
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index); |
|
keys = true; |
|
break; |
|
case BamlRecordType.KeyElementStart: |
|
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index); |
|
keys = true; |
|
break; |
|
default: |
|
keys = false; |
|
index--; |
|
break; |
|
} |
|
index++; |
|
} while (keys); |
|
wtr.BaseStream.Seek(pos, SeekOrigin.Begin); |
|
wtr.Write((uint)(Record.Position - doc[index].Position)); |
|
} |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
base.Read(reader); |
|
pos = reader.ReadUInt32(); |
|
Shared = reader.ReadBoolean(); |
|
SharedSet = reader.ReadBoolean(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
base.Write(writer); |
|
pos = (uint)writer.BaseStream.Position; |
|
writer.Write((uint)0); |
|
writer.Write(Shared); |
|
writer.Write(SharedSet); |
|
} |
|
|
|
static void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index) |
|
{ |
|
index++; |
|
while (true) |
|
{ |
|
if (doc[index].Type == start) |
|
NavigateTree(doc, start, end, ref index); |
|
else if (doc[index].Type == end) |
|
return; |
|
index++; |
|
} |
|
} |
|
} |
|
|
|
internal class PropertyListStartRecord : PropertyComplexStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyListStart; |
|
} |
|
|
|
internal class PropertyListEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyListEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class PropertyDictionaryStartRecord : PropertyComplexStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyDictionaryStart; |
|
} |
|
|
|
internal class PropertyDictionaryEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyDictionaryEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class PropertyArrayStartRecord : PropertyComplexStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyArrayStart; |
|
} |
|
|
|
internal class PropertyArrayEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyArrayEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class PropertyComplexStartRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyComplexStart; |
|
|
|
public ushort AttributeId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId); |
|
} |
|
|
|
internal class PropertyComplexEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.PropertyComplexEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class ConstructorParametersStartRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ConstructorParametersStart; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class ConstructorParametersEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ConstructorParametersEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class ConstructorParameterTypeRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.ConstructorParameterType; |
|
|
|
public ushort TypeId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => TypeId = reader.ReadUInt16(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(TypeId); |
|
} |
|
|
|
internal class DeferableContentStartRecord : BamlRecord, IBamlDeferRecord |
|
{ |
|
long pos; |
|
internal uint size = 0xffffffff; |
|
|
|
public override BamlRecordType Type => BamlRecordType.DeferableContentStart; |
|
|
|
public BamlRecord Record { get; set; } |
|
|
|
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) => Record = resolve(pos + size); |
|
|
|
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) |
|
{ |
|
wtr.BaseStream.Seek(pos, SeekOrigin.Begin); |
|
wtr.Write((uint)(Record.Position - (pos + 4))); |
|
} |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
size = reader.ReadUInt32(); |
|
pos = reader.BaseStream.Position; |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
pos = writer.BaseStream.Position; |
|
writer.Write((uint)0); |
|
} |
|
} |
|
|
|
internal class StaticResourceStartRecord : ElementStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.StaticResourceStart; |
|
} |
|
|
|
internal class StaticResourceEndRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.StaticResourceEnd; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
} |
|
} |
|
|
|
internal class StaticResourceIdRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.StaticResourceId; |
|
|
|
public ushort StaticResourceId { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => StaticResourceId = reader.ReadUInt16(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(StaticResourceId); |
|
} |
|
|
|
internal class OptimizedStaticResourceRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.OptimizedStaticResource; |
|
|
|
public byte Flags { get; set; } |
|
public ushort ValueId { get; set; } |
|
|
|
public bool IsType => (Flags & 1) != 0; |
|
|
|
public bool IsStatic => (Flags & 2) != 0; |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
Flags = reader.ReadByte(); |
|
ValueId = reader.ReadUInt16(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(Flags); |
|
writer.Write(ValueId); |
|
} |
|
} |
|
|
|
internal class LineNumberAndPositionRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.LineNumberAndPosition; |
|
|
|
public uint LineNumber { get; set; } |
|
public uint LinePosition { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
LineNumber = reader.ReadUInt32(); |
|
LinePosition = reader.ReadUInt32(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(LineNumber); |
|
writer.Write(LinePosition); |
|
} |
|
} |
|
|
|
internal class LinePositionRecord : BamlRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.LinePosition; |
|
|
|
public uint LinePosition { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) => LinePosition = reader.ReadUInt32(); |
|
|
|
public override void Write(BamlBinaryWriter writer) => writer.Write(LinePosition); |
|
} |
|
|
|
internal class NamedElementStartRecord : ElementStartRecord |
|
{ |
|
public override BamlRecordType Type => BamlRecordType.NamedElementStart; |
|
|
|
public string RuntimeName { get; set; } |
|
|
|
public override void Read(BamlBinaryReader reader) |
|
{ |
|
TypeId = reader.ReadUInt16(); |
|
RuntimeName = reader.ReadString(); |
|
} |
|
|
|
public override void Write(BamlBinaryWriter writer) |
|
{ |
|
writer.Write(TypeId); |
|
if (RuntimeName != null) |
|
{ |
|
writer.Write(RuntimeName); |
|
} |
|
} |
|
} |
|
} |