bool ReadSimpleValue(BinaryReader br, ref CustomAttrib.Elem elem, TypeReference type) { switch (type.FullName) { case Constants.Boolean: elem.Value = br.ReadByte() == 1; break; case Constants.Char: elem.Value = (char)br.ReadUInt16(); break; case Constants.Single: elem.Value = br.ReadSingle(); break; case Constants.Double: elem.Value = br.ReadDouble(); break; case Constants.Byte: elem.Value = br.ReadByte(); break; case Constants.Int16: elem.Value = br.ReadInt16(); break; case Constants.Int32: elem.Value = br.ReadInt32(); break; case Constants.Int64: elem.Value = br.ReadInt64(); break; case Constants.SByte: elem.Value = br.ReadSByte(); break; case Constants.UInt16: elem.Value = br.ReadUInt16(); break; case Constants.UInt32: elem.Value = br.ReadUInt32(); break; case Constants.UInt64: elem.Value = br.ReadUInt64(); break; default: // enum return(false); } elem.Simple = true; return(true); }
CustomAttrib.Elem CreateElem(TypeReference type, object value) { CustomAttrib.Elem elem = new CustomAttrib.Elem (); elem.Value = value; elem.ElemType = type; elem.FieldOrPropType = GetCorrespondingType (type.FullName); switch (elem.FieldOrPropType) { case ElementType.Boolean : case ElementType.Char : case ElementType.R4 : case ElementType.R8 : case ElementType.I1 : case ElementType.I2 : case ElementType.I4 : case ElementType.I8 : case ElementType.U1 : case ElementType.U2 : case ElementType.U4 : case ElementType.U8 : elem.Simple = true; break; case ElementType.String: elem.String = true; break; case ElementType.Type: elem.Type = true; break; case ElementType.Object: elem.BoxedValueType = true; if (value == null) elem.FieldOrPropType = ElementType.String; else elem.FieldOrPropType = GetCorrespondingType ( GetObjectTypeName (value)); break; } return elem; }
// elem in named args, only have an ElementType CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, ElementType elemType, ref bool read) { CustomAttrib.Elem elem = new CustomAttrib.Elem(); if (elemType == ElementType.Boxed) { ElementType elementType = (ElementType)br.ReadByte(); elem = ReadElem(data, br, elementType, ref read); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; elem.FieldOrPropType = elementType; return(elem); } if (elemType == ElementType.Type || elemType == ElementType.String) // type or string { switch (elemType) { case ElementType.String: elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; elem.ElemType = m_reflectReader.SearchCoreType(Constants.String); break; case ElementType.Type: elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; elem.ElemType = m_reflectReader.SearchCoreType(Constants.Type); break; } if (data [br.BaseStream.Position] == 0xff) // null { elem.Value = null; br.BaseStream.Position++; } else { int next, length = Utilities.ReadCompressedInteger(data, (int)br.BaseStream.Position, out next); br.BaseStream.Position = next; // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) is not supported. byte [] bytes = br.ReadBytes(length); elem.Value = Encoding.UTF8.GetString(bytes, 0, bytes.Length); } return(elem); } elem.String = elem.Type = elem.BoxedValueType = false; switch (elemType) { case ElementType.Boolean: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Boolean); elem.Value = br.ReadByte() == 1; break; case ElementType.Char: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Char); elem.Value = (char)br.ReadUInt16(); break; case ElementType.R4: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Single); elem.Value = br.ReadSingle(); break; case ElementType.R8: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Double); elem.Value = br.ReadDouble(); break; case ElementType.I1: elem.ElemType = m_reflectReader.SearchCoreType(Constants.SByte); elem.Value = br.ReadSByte(); break; case ElementType.I2: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Int16); elem.Value = br.ReadInt16(); break; case ElementType.I4: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Int32); elem.Value = br.ReadInt32(); break; case ElementType.I8: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Int64); elem.Value = br.ReadInt64(); break; case ElementType.U1: elem.ElemType = m_reflectReader.SearchCoreType(Constants.Byte); elem.Value = br.ReadByte(); break; case ElementType.U2: elem.ElemType = m_reflectReader.SearchCoreType(Constants.UInt16); elem.Value = br.ReadUInt16(); break; case ElementType.U4: elem.ElemType = m_reflectReader.SearchCoreType(Constants.UInt32); elem.Value = br.ReadUInt32(); break; case ElementType.U8: elem.ElemType = m_reflectReader.SearchCoreType(Constants.UInt64); elem.Value = br.ReadUInt64(); break; case ElementType.Enum: read = false; return(elem); default: throw new MetadataFormatException("Non valid type in CustomAttrib.Elem: 0x{0}", ((byte)elemType).ToString("x2")); } elem.Simple = true; return(elem); }
CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, TypeReference elemType, ref bool read) { CustomAttrib.Elem elem = new CustomAttrib.Elem(); string elemName = elemType.FullName; if (elemName == Constants.Object) { ElementType elementType = (ElementType)br.ReadByte(); elem = ReadElem(data, br, elementType, ref read); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; elem.FieldOrPropType = elementType; return(elem); } elem.ElemType = elemType; if (elemName == Constants.Type || elemName == Constants.String) { switch (elemType.FullName) { case Constants.String: elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; break; case Constants.Type: elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; break; } if (data [br.BaseStream.Position] == 0xff) // null { elem.Value = null; br.BaseStream.Position++; } else { int next, length = Utilities.ReadCompressedInteger(data, (int)br.BaseStream.Position, out next); br.BaseStream.Position = next; // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) is not supported. byte [] bytes = br.ReadBytes(length); elem.Value = Encoding.UTF8.GetString(bytes, 0, bytes.Length); } return(elem); } elem.String = elem.Type = elem.BoxedValueType = false; switch (elemName) { case Constants.Boolean: elem.Value = br.ReadByte() == 1; break; case Constants.Char: elem.Value = (char)br.ReadUInt16(); break; case Constants.Single: elem.Value = br.ReadSingle(); break; case Constants.Double: elem.Value = br.ReadDouble(); break; case Constants.Byte: elem.Value = br.ReadByte(); break; case Constants.Int16: elem.Value = br.ReadInt16(); break; case Constants.Int32: elem.Value = br.ReadInt32(); break; case Constants.Int64: elem.Value = br.ReadInt64(); break; case Constants.SByte: elem.Value = br.ReadSByte(); break; case Constants.UInt16: elem.Value = br.ReadUInt16(); break; case Constants.UInt32: elem.Value = br.ReadUInt32(); break; case Constants.UInt64: elem.Value = br.ReadUInt64(); break; default: // enum read = false; return(elem); } elem.Simple = true; return(elem); }
void Write(CustomAttrib.Elem elem, MemoryBinaryWriter writer) { if (elem.String) { elem.FieldOrPropType = ElementType.String; } else if (elem.Type) { elem.FieldOrPropType = ElementType.Type; } if (elem.FieldOrPropType == ElementType.Class) // an enum in fact { elem.FieldOrPropType = GetElementTypeFromTypeCode(Type.GetTypeCode(elem.Value.GetType())); } if (elem.BoxedValueType) { Write(elem.FieldOrPropType); } switch (elem.FieldOrPropType) { case ElementType.Boolean: writer.Write((byte)((bool)elem.Value ? 1 : 0)); break; case ElementType.Char: writer.Write((ushort)(char)elem.Value); break; case ElementType.R4: writer.Write((float)elem.Value); break; case ElementType.R8: writer.Write((double)elem.Value); break; case ElementType.I1: writer.Write((sbyte)elem.Value); break; case ElementType.I2: writer.Write((short)elem.Value); break; case ElementType.I4: writer.Write((int)elem.Value); break; case ElementType.I8: writer.Write((long)elem.Value); break; case ElementType.U1: writer.Write((byte)elem.Value); break; case ElementType.U2: writer.Write((ushort)elem.Value); break; case ElementType.U4: writer.Write((uint)elem.Value); break; case ElementType.U8: writer.Write((ulong)elem.Value); break; case ElementType.String: case ElementType.Type: string s = elem.Value as string; if (s == null) { writer.Write((byte)0xff); } else if (s.Length == 0) { writer.Write((byte)0x00); } else { Write(s); } break; case ElementType.Object: if (elem.Value != null) { throw new NotSupportedException("Unknown state"); } writer.Write((byte)0xff); break; default: throw new NotImplementedException("WriteElem " + elem.FieldOrPropType.ToString()); } }
CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, TypeReference elemType, ref bool read, bool resolve) { CustomAttrib.Elem elem = new CustomAttrib.Elem(); string elemName = elemType.FullName; if (elemName == Constants.Object) { elemType = ReadTypeReference(data, br, out elem.FieldOrPropType); if (elemType is ArrayType) { read = false; // Don't know how to represent arrays as an object value. return(elem); } else if (elemType.FullName == Constants.Object) { throw new MetadataFormatException("Non valid type in CustomAttrib.Elem after boxed prefix: 0x{0}", ((byte)elem.FieldOrPropType).ToString("x2")); } elem = ReadElem(data, br, elemType, ref read, resolve); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; return(elem); } elem.ElemType = elemType; if (elemName == Constants.Type || elemName == Constants.String) { switch (elemType.FullName) { case Constants.String: elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; break; case Constants.Type: elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; break; } if (data [br.BaseStream.Position] == 0xff) // null { elem.Value = null; br.BaseStream.Position++; } else { elem.Value = ReadUTF8String(data, br); } return(elem); } elem.String = elem.Type = elem.BoxedValueType = false; if (!ReadSimpleValue(br, ref elem, elem.ElemType)) { if (!resolve) // until enums writing is implemented { read = false; return(elem); } TypeReference typeRef = GetEnumUnderlyingType(elem.ElemType, resolve); if (typeRef == null || !ReadSimpleValue(br, ref elem, typeRef)) { read = false; } } return(elem); }
CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, TypeReference elemType, ref bool read, bool resolve) { CustomAttrib.Elem elem = new CustomAttrib.Elem (); string elemName = elemType.FullName; if (elemName == Constants.Object) { elemType = ReadTypeReference (data, br, out elem.FieldOrPropType); if (elemType is ArrayType) { read = false; // Don't know how to represent arrays as an object value. return elem; } else if (elemType.FullName == Constants.Object) throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem after boxed prefix: 0x{0}", ((byte) elem.FieldOrPropType).ToString ("x2")); elem = ReadElem (data, br, elemType, ref read, resolve); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; return elem; } elem.ElemType = elemType; if (elemName == Constants.Type || elemName == Constants.String) { switch (elemType.FullName) { case Constants.String: elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; break; case Constants.Type: elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; break; } if (data [br.BaseStream.Position] == 0xff) { // null elem.Value = null; br.BaseStream.Position++; } else { elem.Value = ReadUTF8String (data, br); } return elem; } elem.String = elem.Type = elem.BoxedValueType = false; if (!ReadSimpleValue (br, ref elem, elem.ElemType)) { if (!resolve) { // until enums writing is implemented read = false; return elem; } TypeReference typeRef = GetEnumUnderlyingType (elem.ElemType, resolve); if (typeRef == null || !ReadSimpleValue (br, ref elem, typeRef)) read = false; } return elem; }
// elem in named args, only have an ElementType CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, ElementType elemType, ref bool read) { CustomAttrib.Elem elem = new CustomAttrib.Elem (); if (elemType == ElementType.Boxed) { ElementType elementType = (ElementType) br.ReadByte (); elem = ReadElem (data, br, elementType, ref read); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; elem.FieldOrPropType = elementType; return elem; } if (elemType == ElementType.Type || elemType == ElementType.String) { // type or string switch (elemType) { case ElementType.String : elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; elem.ElemType = m_reflectReader.SearchCoreType (Constants.String); break; case ElementType.Type : elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; elem.ElemType = m_reflectReader.SearchCoreType (Constants.Type); break; } if (data [br.BaseStream.Position] == 0xff) { // null elem.Value = null; br.BaseStream.Position++; } else { int next, length = Utilities.ReadCompressedInteger (data, (int) br.BaseStream.Position, out next); br.BaseStream.Position = next; // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) is not supported. byte [] bytes = br.ReadBytes (length); elem.Value = Encoding.UTF8.GetString (bytes, 0, bytes.Length); } return elem; } elem.String = elem.Type = elem.BoxedValueType = false; switch (elemType) { case ElementType.Boolean : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Boolean); elem.Value = br.ReadByte () == 1; break; case ElementType.Char : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Char); elem.Value = (char) br.ReadUInt16 (); break; case ElementType.R4 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Single); elem.Value = br.ReadSingle (); break; case ElementType.R8 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Double); elem.Value = br.ReadDouble (); break; case ElementType.I1 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.SByte); elem.Value = br.ReadSByte (); break; case ElementType.I2 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Int16); elem.Value = br.ReadInt16 (); break; case ElementType.I4 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Int32); elem.Value = br.ReadInt32 (); break; case ElementType.I8 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Int64); elem.Value = br.ReadInt64 (); break; case ElementType.U1 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.Byte); elem.Value = br.ReadByte (); break; case ElementType.U2 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.UInt16); elem.Value = br.ReadUInt16 (); break; case ElementType.U4 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.UInt32); elem.Value = br.ReadUInt32 (); break; case ElementType.U8 : elem.ElemType = m_reflectReader.SearchCoreType (Constants.UInt64); elem.Value = br.ReadUInt64 (); break; case ElementType.Enum : read = false; return elem; default : throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem: 0x{0}", ((byte) elemType).ToString("x2")); } elem.Simple = true; return elem; }
CustomAttrib.Elem ReadElem(byte [] data, BinaryReader br, TypeReference elemType, ref bool read) { CustomAttrib.Elem elem = new CustomAttrib.Elem (); string elemName = elemType.FullName; if (elemName == Constants.Object) { ElementType elementType = (ElementType) br.ReadByte (); elem = ReadElem (data, br, elementType, ref read); elem.String = elem.Simple = elem.Type = false; elem.BoxedValueType = true; elem.FieldOrPropType = elementType; return elem; } elem.ElemType = elemType; if (elemName == Constants.Type || elemName == Constants.String) { switch (elemType.FullName) { case Constants.String: elem.String = true; elem.BoxedValueType = elem.Simple = elem.Type = false; break; case Constants.Type: elem.Type = true; elem.BoxedValueType = elem.Simple = elem.String = false; break; } if (data [br.BaseStream.Position] == 0xff) { // null elem.Value = null; br.BaseStream.Position++; } else { int next, length = Utilities.ReadCompressedInteger (data, (int) br.BaseStream.Position, out next); br.BaseStream.Position = next; // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) is not supported. byte [] bytes = br.ReadBytes (length); elem.Value = Encoding.UTF8.GetString (bytes, 0, bytes.Length); } return elem; } elem.String = elem.Type = elem.BoxedValueType = false; switch (elemName) { case Constants.Boolean : elem.Value = br.ReadByte () == 1; break; case Constants.Char : elem.Value = (char) br.ReadUInt16 (); break; case Constants.Single : elem.Value = br.ReadSingle (); break; case Constants.Double : elem.Value = br.ReadDouble (); break; case Constants.Byte : elem.Value = br.ReadByte (); break; case Constants.Int16 : elem.Value = br.ReadInt16 (); break; case Constants.Int32 : elem.Value = br.ReadInt32 (); break; case Constants.Int64 : elem.Value = br.ReadInt64 (); break; case Constants.SByte : elem.Value = br.ReadSByte (); break; case Constants.UInt16 : elem.Value = br.ReadUInt16 (); break; case Constants.UInt32 : elem.Value = br.ReadUInt32 (); break; case Constants.UInt64 : elem.Value = br.ReadUInt64 (); break; default : // enum read = false; return elem; } elem.Simple = true; return elem; }
void Write(CustomAttrib.Elem elem, MemoryBinaryWriter writer) // TODO { if (elem.String) { elem.FieldOrPropType = ElementType.String; } else if (elem.Type) { elem.FieldOrPropType = ElementType.Type; } else if (elem.BoxedValueType) { Write(elem.FieldOrPropType); } switch (elem.FieldOrPropType) { case ElementType.Boolean: writer.Write((byte)((bool)elem.Value ? 1 : 0)); break; case ElementType.Char: writer.Write((ushort)(char)elem.Value); break; case ElementType.R4: writer.Write((float)elem.Value); break; case ElementType.R8: writer.Write((double)elem.Value); break; case ElementType.I1: writer.Write((sbyte)elem.Value); break; case ElementType.I2: writer.Write((short)elem.Value); break; case ElementType.I4: writer.Write((int)elem.Value); break; case ElementType.I8: writer.Write((long)elem.Value); break; case ElementType.U1: writer.Write((byte)elem.Value); break; case ElementType.U2: writer.Write((ushort)elem.Value); break; case ElementType.U4: writer.Write((uint)elem.Value); break; case ElementType.U8: writer.Write((long)elem.Value); break; case ElementType.String: string s = elem.Value as string; if (s == null) { writer.Write((byte)0xff); } else if (s.Length == 0) { writer.Write((byte)0x00); } else { Write(s); } break; case ElementType.Type: string t = elem.Value as string; if (t == null || t.Length == 0) { throw new NotSupportedException("Null types not allowed in custom attributes"); } Write(t); break; case ElementType.Object: if (elem.Value != null) { throw new NotSupportedException("Unknown state"); } writer.Write((byte)0xff); break; default: throw new NotImplementedException("WriteElem " + elem.FieldOrPropType.ToString()); } }