/// <summary> /// Writes the named argument to the provided output stream. /// </summary> /// <param name="writer">The output stream.</param> /// <param name="provider">The object to use for obtaining metadata tokens for members in the tables stream.</param> public void Write(IBinaryStreamWriter writer, ITypeCodedIndexProvider provider) { writer.WriteByte((byte)MemberType); TypeSignature.WriteFieldOrPropType(writer, ArgumentType); writer.WriteSerString(MemberName); Argument.Write(writer, provider); }
/// <summary> /// Writes the named argument to the provided output stream. /// </summary> public void Write(BlobSerializationContext context) { var writer = context.Writer; writer.WriteByte((byte)MemberType); TypeSignature.WriteFieldOrPropType(writer, ArgumentType); writer.WriteSerString(MemberName); Argument.Write(context); }
private void WriteValue(IBinaryStreamWriter writer, TypeSignature argumentType, ITypeCodedIndexProvider provider, object value) { if (argumentType.IsTypeOf("System", "Type")) { writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName((TypeSignature)value)); return; } switch (argumentType.ElementType) { case ElementType.Boolean: writer.WriteByte((byte)((bool)value ? 1 : 0)); break; case ElementType.Char: writer.WriteUInt16((char)value); break; case ElementType.I1: writer.WriteSByte((sbyte)value); break; case ElementType.U1: writer.WriteByte((byte)value); break; case ElementType.I2: writer.WriteInt16((short)value); break; case ElementType.U2: writer.WriteUInt16((ushort)value); break; case ElementType.I4: writer.WriteInt32((int)value); break; case ElementType.U4: writer.WriteUInt32((uint)value); break; case ElementType.I8: writer.WriteInt64((long)value); break; case ElementType.U8: writer.WriteUInt64((ulong)value); break; case ElementType.R4: writer.WriteSingle((float)value); break; case ElementType.R8: writer.WriteDouble((double)value); break; case ElementType.String: writer.WriteSerString(value as string); break; case ElementType.Object: var valueType = value.GetType(); var innerTypeSig = argumentType.Module.CorLibTypeFactory.FromName(valueType.Namespace, valueType.Name); TypeSignature.WriteFieldOrPropType(writer, innerTypeSig); WriteValue(writer, innerTypeSig, provider, value); break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = argumentType.Resolve(); if (enumTypeDef != null && enumTypeDef.IsEnum) { WriteValue(writer, enumTypeDef.GetEnumUnderlyingType(), provider, Value); } else { throw new NotImplementedException(); } break; default: throw new ArgumentOutOfRangeException(); } }
private void WriteElement(TypeSignature argumentType, object element) { var writer = _context.Writer; if (argumentType.IsTypeOf("System", "Type")) { writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName((TypeSignature)element)); return; } switch (argumentType.ElementType) { case ElementType.Boolean: writer.WriteByte((byte)((bool)element ? 1 : 0)); break; case ElementType.Char: writer.WriteUInt16((char)element); break; case ElementType.I1: writer.WriteSByte((sbyte)element); break; case ElementType.U1: writer.WriteByte((byte)element); break; case ElementType.I2: writer.WriteInt16((short)element); break; case ElementType.U2: writer.WriteUInt16((ushort)element); break; case ElementType.I4: writer.WriteInt32((int)element); break; case ElementType.U4: writer.WriteUInt32((uint)element); break; case ElementType.I8: writer.WriteInt64((long)element); break; case ElementType.U8: writer.WriteUInt64((ulong)element); break; case ElementType.R4: writer.WriteSingle((float)element); break; case ElementType.R8: writer.WriteDouble((double)element); break; case ElementType.String: writer.WriteSerString(element as string); break; case ElementType.Object: TypeSignature innerTypeSig; object value; if (element is null) { // Most efficient way to store "null" is writing null as a string (two bytes). innerTypeSig = argumentType.Module.CorLibTypeFactory.String; value = null; } else if (element is BoxedArgument boxedArgument) { // Write the boxed argument. innerTypeSig = boxedArgument.Type; value = boxedArgument.Value; } else { _context.DiagnosticBag.RegisterException(new NotSupportedException( $"Object elements in a custom attribute signature should be either 'null' or an instance of {nameof(BoxedArgument)}.")); // Write null as a recovery. innerTypeSig = argumentType.Module.CorLibTypeFactory.String; value = null; } TypeSignature.WriteFieldOrPropType(writer, innerTypeSig); WriteElement(innerTypeSig, value); break; case ElementType.SzArray: WriteArrayElement( (SzArrayTypeSignature)argumentType, element as IList <object> ?? new object[0], element == null); break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: WriteEnumValue(argumentType, element); break; default: UnsupportedArgumentType(argumentType); break; } }