obfuz/Plugins/dnlib/DotNet/Pdb/Managed/NumericReader.cs

102 lines
2.2 KiB
C#
Raw Normal View History

// dnlib: See LICENSE.txt for more info
using dnlib.IO;
namespace dnlib.DotNet.Pdb.Managed {
static class NumericReader {
public static bool TryReadNumeric(ref DataReader reader, ulong end, out object value) {
value = null;
ulong position = reader.Position;
if (position + 2 > end)
return false;
var numLeaf = (NumericLeaf)reader.ReadUInt16();
if (numLeaf < NumericLeaf.LF_NUMERIC) {
value = (short)numLeaf;
return true;
}
switch (numLeaf) {
case NumericLeaf.LF_CHAR:
if (position > end)
return false;
value = reader.ReadSByte();
return true;
case NumericLeaf.LF_SHORT:
if (position + 2 > end)
return false;
value = reader.ReadInt16();
return true;
case NumericLeaf.LF_USHORT:
if (position + 2 > end)
return false;
value = reader.ReadUInt16();
return true;
case NumericLeaf.LF_LONG:
if (position + 4 > end)
return false;
value = reader.ReadInt32();
return true;
case NumericLeaf.LF_ULONG:
if (position + 4 > end)
return false;
value = reader.ReadUInt32();
return true;
case NumericLeaf.LF_REAL32:
if (position + 4 > end)
return false;
value = reader.ReadSingle();
return true;
case NumericLeaf.LF_REAL64:
if (position + 8 > end)
return false;
value = reader.ReadDouble();
return true;
case NumericLeaf.LF_QUADWORD:
if (position + 8 > end)
return false;
value = reader.ReadInt64();
return true;
case NumericLeaf.LF_UQUADWORD:
if (position + 8 > end)
return false;
value = reader.ReadUInt64();
return true;
case NumericLeaf.LF_VARSTRING:
if (position + 2 > end)
return false;
int varStrLen = reader.ReadUInt16();
if (position + (uint)varStrLen > end)
return false;
value = reader.ReadUtf8String(varStrLen);
return true;
case NumericLeaf.LF_VARIANT:
if (position + 0x10 > end)
return false;
int v0 = reader.ReadInt32();
int v1 = reader.ReadInt32();
int v2 = reader.ReadInt32();
int v3 = reader.ReadInt32();
byte scale = (byte)(v0 >> 16);
if (scale <= 28)
value = new decimal(v2, v3, v1, v0 < 0, scale);
else
value = null;
return true;
default:
return false;
}
}
}
}