public HLArguments DecodeArgs(ArgEncoding encoding) { switch (encoding) { case ArgEncoding.None: throw new ArgumentException(); case ArgEncoding.I8: return new HLArguments((int)m_reader.ReadSByte()); case ArgEncoding.I16: return new HLArguments((int)m_reader.ReadInt16()); case ArgEncoding.I32: return new HLArguments(m_reader.ReadInt32()); case ArgEncoding.I64: return new HLArguments(m_reader.ReadInt64()); case ArgEncoding.U8: return new HLArguments((uint)m_reader.ReadByte()); case ArgEncoding.U16: return new HLArguments((uint)m_reader.ReadUInt16()); case ArgEncoding.U32: return new HLArguments(m_reader.ReadUInt32()); case ArgEncoding.U64: return new HLArguments(m_reader.ReadUInt64()); case ArgEncoding.F32: return new HLArguments(m_reader.ReadSingle()); case ArgEncoding.F64: return new HLArguments(m_reader.ReadDouble()); case ArgEncoding.No: return HLArguments.CreateNo(m_reader.ReadByte()); case ArgEncoding.MethodDefOrRefOrSpec: case ArgEncoding.MethodDefOrRef: case ArgEncoding.TypeDefOrRefOrSpec: case ArgEncoding.LoadToken: case ArgEncoding.Field: return new HLArguments(ReadMetaToken(encoding)); case ArgEncoding.Switch: // III.3.66 { uint numCases = m_reader.ReadUInt32(); int[] caseTargets = new int[numCases]; for (uint i=0; i<numCases; i++) caseTargets[i] = m_reader.ReadInt32(); return HLArguments.CreateSwitch(caseTargets); } case ArgEncoding.String: { // III.1.9 List<char> chars = new List<char>(); uint rawToken = m_reader.ReadUInt32(); if (rawToken >> 24 != 0x70) throw new ParseFailedException("Unexpected string token"); ArraySegment<byte> utf16string = CLRMetaDataParser.ReadBlobOrUS(m_binData.USData, rawToken & 0x00ffffff); // II.24.2.4 // US strings are UTF-16, terminator is 1 if any code point is non-ASCII byte terminator = utf16string.Array[utf16string.Offset + utf16string.Count - 1]; if ((utf16string.Count & 1) != 1 || (terminator != 0 && terminator != 1)) throw new ParseFailedException("Invalid inline string"); for (int offset = 0; offset < utf16string.Count - 1; offset += 2) { int trueOffset = offset + utf16string.Offset; int codePoint = utf16string.Array[trueOffset] | (utf16string.Array[trueOffset + 1] << 8); chars.Add((char)codePoint); } return new HLArguments(new string(chars.ToArray())); } default: break; } throw new NotImplementedException(); }
// III.1.9 public CLRTableRow ReadMetaToken(ArgEncoding argRestriction) { uint rawToken = m_reader.ReadUInt32(); uint tableIndex = rawToken >> 24; uint rowIndex = rawToken & 0x00ffffff; if (rowIndex == 0) return null; CLRTableRow row = m_tables.GetTable((int)tableIndex).GetRow(rowIndex - 1); switch (argRestriction) { case ArgEncoding.LoadToken: if (!s_LoadTokenTypes.Contains(row.GetType())) throw new ParseFailedException("Invalid ldtoken token"); return row; case ArgEncoding.MethodDefOrRef: if (!s_MethodDefOrRefTypes.Contains(row.GetType())) throw new ParseFailedException("Invalid token"); if (row.GetType() == typeof(CLRMemberRefRow) && ((CLRMemberRefRow)row).MethodSig == null) throw new ParseFailedException("Invalid token)"); return row; case ArgEncoding.MethodDefOrRefOrSpec: if (!s_MethodDefOrRefOrSpecTypes.Contains(row.GetType())) throw new ParseFailedException("Invalid token"); if (row.GetType() == typeof(CLRMemberRefRow) && ((CLRMemberRefRow)row).MethodSig == null) throw new ParseFailedException("Invalid token)"); return row; case ArgEncoding.TypeDefOrRefOrSpec: if (!s_TypeDefOrRefOrSpecTypes.Contains(row.GetType())) throw new ParseFailedException("Invalid token"); return row; case ArgEncoding.Field: if (!s_FieldDefOrRefTypes.Contains(row.GetType())) throw new ParseFailedException("Invalid token"); if (row.GetType() == typeof(CLRMemberRefRow) && ((CLRMemberRefRow)row).FieldSig == null) throw new ParseFailedException("Invalid token)"); return row; } throw new NotImplementedException(); }