Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        // 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();
        }