102 lines
2.2 KiB
C#
102 lines
2.2 KiB
C#
|
// 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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|