Exemple #1
0
        private static object ReadValue(BufferedBinaryReader reader, SystemTypeCode type)
        {
            switch (type)
            {
            case SystemTypeCode.Boolean:
                return(reader.ReadBoolean());

            case SystemTypeCode.Int8:
                return(reader.ReadInt8());

            case SystemTypeCode.UInt8:
                return(reader.ReadUInt8());

            case SystemTypeCode.Int16:
                return(reader.ReadInt16());

            case SystemTypeCode.UInt16:
                return(reader.ReadUInt16());

            case SystemTypeCode.Int32:
                return(reader.ReadInt32());

            case SystemTypeCode.UInt32:
                return(reader.ReadUInt32());

            case SystemTypeCode.Int64:
                return(reader.ReadInt64());

            case SystemTypeCode.UInt64:
                return(reader.ReadUInt64());

            case SystemTypeCode.Single:
                return(reader.ReadSingle());

            case SystemTypeCode.Double:
                return(reader.ReadDouble());

            case SystemTypeCode.Decimal:
                throw new NotImplementedException();

            case SystemTypeCode.DateTime:
                throw new NotImplementedException();

            case SystemTypeCode.Char:
                return(reader.ReadChar());

            case SystemTypeCode.String:
                return(reader.ReadCountedUtf8());

            case SystemTypeCode.Enum:
                throw new NotImplementedException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #2
0
        private static object ReadValue(ElementType type, BufferedBinaryReader reader)
        {
            switch (type)
            {
            case ElementType.Boolean:
                return(reader.ReadBoolean());

            case ElementType.Char:
                return(reader.ReadChar());

            case ElementType.Int8:
                return(reader.ReadSByte());

            case ElementType.UInt8:
                return(reader.ReadByte());

            case ElementType.Int16:
                return(reader.ReadInt16());

            case ElementType.UInt16:
                return(reader.ReadUInt16());

            case ElementType.Int32:
                return(reader.ReadInt32());

            case ElementType.UInt32:
                return(reader.ReadUInt32());

            case ElementType.Int64:
                return(reader.ReadInt64());

            case ElementType.UInt64:
                return(reader.ReadUInt64());

            case ElementType.Single:
                return(reader.ReadSingle());

            case ElementType.Double:
                return(reader.ReadDouble());

            case ElementType.String:
                return(Encoding.Unicode.GetString(reader.ToArray()));

            case ElementType.Class:
                return(null);

            default:
                return(reader.ToArray());
            }
        }
Exemple #3
0
        /// <summary>
        /// Obtains the value of this field from the specified <see cref="BufferedBinaryReader"/>.
        /// </summary>
        /// <param name="br">The <see cref="BufferedBinaryReader"/> to read from.</param>
        /// <returns>The object that was read.</returns>
        /// <remarks>
        /// While it may technically be possible to remove this boxing by doing the switch statement
        /// outside of the class (where this method is being used), the result goes directly into
        /// a DataRow which boxes anyway.
        /// </remarks>
        internal object GetValue(ref BufferedBinaryReader br)
        {
            //IMPLEMENT: Support for DBT files. https://en.wikipedia.org/wiki/.dbf#Level_5_DOS_headers
            try
            {
                switch (FieldType)
                {
                case EFieldType.Memo:
                case EFieldType.Character:
                    //TODO: Can we do this without allocation of another string that trims the 0-bytes? Is it safe to remove trailing 0 bytes?
                    return(Encoding.GetString(br.ReadBytes(FieldLength)).Trim('\0'));

                case EFieldType.Binary:
                case EFieldType.General:
                    // We do not support DBT tables.
                    return(DBNull.Value);

                case EFieldType.Float:
                case EFieldType.Numeric:
                    // We cannot simply assume it takes up 4 or 8 bytes for a float or double respectively.
                    return(double.Parse(Encoding.GetString(br.ReadBytes(FieldLength)), NumericCulture));

                case EFieldType.Logical:
                {
                    string value = Encoding.GetString(br.ReadBytes(FieldLength));

                    return(value == "Y" || value == "y"
                            ? true
                            : value == "?"
                                ? (object)DBNull.Value
                                : false);
                }

                case EFieldType.Date: return(DateTime.TryParseExact(Encoding.GetString(br.ReadBytes(FieldLength)), "yyyyMMdd", DateCulture, DateTimeStyles.None, out var result) ? result : (object)DBNull.Value);

                case EFieldType.DateTime: return(DateTime.FromOADate(br.ReadInt64() - 2415018.5));

                default: return(DBNull.Value);
                }
            }
            catch (FormatException e)
            {
                throw new FormatException($"Input string was not in a correct format [DbType = {FieldType}].", e);
            }
        }
Exemple #4
0
		private object ReadValue(BufferedBinaryReader reader, IType type)
		{
			var st = type.SystemType();
			if (st != null)
			{
				switch (st.Code)
				{
					case SystemTypeCode.Boolean:
						return reader.ReadBoolean();
					case SystemTypeCode.Int8:
						return reader.ReadInt8();
					case SystemTypeCode.UInt8:
						return reader.ReadUInt8();
					case SystemTypeCode.Int16:
						return reader.ReadInt16();
					case SystemTypeCode.UInt16:
						return reader.ReadUInt16();
					case SystemTypeCode.Int32:
						return reader.ReadInt32();
					case SystemTypeCode.UInt32:
						return reader.ReadUInt32();
					case SystemTypeCode.Int64:
						return reader.ReadInt64();
					case SystemTypeCode.UInt64:
						return reader.ReadUInt64();
					case SystemTypeCode.Single:
						return reader.ReadSingle();
					case SystemTypeCode.Double:
						return reader.ReadDouble();
					case SystemTypeCode.Char:
						return reader.ReadChar();
					case SystemTypeCode.String:
						return reader.ReadCountedUtf8();
					case SystemTypeCode.Object:
						//boxed value type
						var e = (ElementType)reader.ReadInt8();
						return ReadValue(reader, e);
					case SystemTypeCode.Type:
						return ReadType(reader);
				}
			}

			if (type.TypeKind == TypeKind.Enum)
			{
				return ReadValue(reader, type.ValueType);
			}

			if (type.IsArray)
			{
				int numElem = reader.ReadInt32();
				Array arr = null;
				for (int i = 0; i < numElem; ++i)
				{
					var val = ReadValue(reader, type.ElementType);
					if (arr == null)
						arr = Array.CreateInstance(val.GetType(), numElem);
					arr.SetValue(val, i);
				}
				return arr;
			}

			return null;
		}
Exemple #5
0
		private object ReadValue(BufferedBinaryReader reader, ElementType e)
		{
			switch (e)
			{
				case ElementType.Boolean:
					return reader.ReadBoolean();

				case ElementType.Char:
					return reader.ReadChar();

				case ElementType.Int8:
					return reader.ReadSByte();

				case ElementType.UInt8:
					return reader.ReadByte();

				case ElementType.Int16:
					return reader.ReadInt16();

				case ElementType.UInt16:
					return reader.ReadUInt16();

				case ElementType.Int32:
					return reader.ReadInt32();

				case ElementType.UInt32:
					return reader.ReadUInt32();

				case ElementType.Int64:
					return reader.ReadInt64();

				case ElementType.UInt64:
					return reader.ReadUInt64();

				case ElementType.Single:
					return reader.ReadSingle();

				case ElementType.Double:
					return reader.ReadDouble();

				case ElementType.String:
					return reader.ReadCountedUtf8();

				case ElementType.Object:
				case ElementType.CustomArgsBoxedObject:
					{
						var elem = (ElementType)reader.ReadInt8();
						return ReadValue(reader, elem);
					}

				case ElementType.CustomArgsEnum:
					{
						string enumTypeName = reader.ReadCountedUtf8();
						var enumType = FindType(enumTypeName);
						if (enumType == null)
						{
							//TODO:
							throw new BadMetadataException();
						}
						return ReadValue(reader, enumType);
					}

				case ElementType.CustomArgsType:
					return ReadType(reader);

				case ElementType.ArraySz:
					{
						var arrElemType = (ElementType)reader.ReadInt8();
						return ReadArray(reader, arrElemType);
					}

				default:
					throw new ArgumentOutOfRangeException();
			}
		}
Exemple #6
0
        private static Instruction ReadInstruction(IMethod method, IMethodContext context, BufferedBinaryReader reader, long startPosition)
        {
            var instr = new Instruction
            {
                Offset = (int)(reader.Position - startPosition),
                OpCode = OpCodes.Nop
            };

            byte   op = reader.ReadUInt8();
            OpCode?opCode;

            if (op != CIL.MultiBytePrefix)
            {
                opCode = CIL.GetShortOpCode(op);
            }
            else
            {
                op     = reader.ReadUInt8();
                opCode = CIL.GetLongOpCode(op);
            }

            if (!opCode.HasValue)
            {
                throw new BadImageFormatException(string.Format("The format of instruction with code {0} is invalid", op));
            }

            instr.OpCode = opCode.Value;

            //Read operand
            switch (instr.OpCode.OperandType)
            {
            case OperandType.InlineI:
                instr.Value = reader.ReadInt32();
                break;

            case OperandType.ShortInlineI:
                instr.Value = (int)reader.ReadSByte();
                break;

            case OperandType.InlineI8:
                instr.Value = reader.ReadInt64();
                break;

            case OperandType.InlineR:
                instr.Value = reader.ReadDouble();
                break;

            case OperandType.ShortInlineR:
                instr.Value = reader.ReadSingle();
                break;

            case OperandType.InlineBrTarget:
            {
                int offset = reader.ReadInt32();
                instr.Value = (int)(offset + reader.Position - startPosition);
            }
            break;

            case OperandType.ShortInlineBrTarget:
            {
                int offset = reader.ReadSByte();
                instr.Value = (int)(offset + reader.Position - startPosition);
            }
            break;

            case OperandType.InlineSwitch:
            {
                int casesCount     = reader.ReadInt32();
                var switchBranches = new int[casesCount];
                for (int k = 0; k < casesCount; k++)
                {
                    switchBranches[k] = reader.ReadInt32();
                }

                int shift = (int)(reader.Position - startPosition);
                for (int k = 0; k < casesCount; k++)
                {
                    switchBranches[k] += shift;
                }

                instr.Value = switchBranches;
            }
            break;

            case OperandType.InlineVar:
                instr.Value = (int)reader.ReadUInt16();
                break;

            case OperandType.ShortInlineVar:
                instr.Value = reader.ReadByte();
                break;

            case OperandType.InlineString:
            {
                int token = reader.ReadInt32();
                instr.Value = context.ResolveMetadataToken(method, token);
            }
            break;

            case OperandType.InlineField:
            case OperandType.InlineMethod:
            case OperandType.InlineSig:
            case OperandType.InlineTok:
            case OperandType.InlineType:
            {
                int token = reader.ReadInt32();
                instr.MetadataToken = token;

                object val = context.ResolveMetadataToken(method, token);
                if (val is ITypeMember)
                {
                }

                if (val == null)
                {
#if DEBUG
                    if (DebugHooks.BreakInvalidMetadataToken)
                    {
                        Debugger.Break();
                        val = context.ResolveMetadataToken(method, token);
                    }
#endif
                    throw new BadTokenException(token);
                }

                instr.Value = val;
            }
            break;

            case OperandType.InlineNone:
                // no operand
                break;

            case OperandType.InlinePhi:
                throw new BadImageFormatException(@"Obsolete. The InlinePhi operand is reserved and should not be used!");
            }

            return(instr);
        }