Hi Eyal,

The patch looks mostly good. Please use the new interface 
IRequireResolving I've just commited for the changes in CustomAttribute.

Please also follow the coding guideline used in Cecil.

I would also prefer a patch using a parameter instead of the 
ForceResolving property.

Also please send me the patch once it's done instead of commiting, I 
have to check that everything works fine on the writing part.

Thanks a lot,

Jb

Eyal Alaluf wrote:
> Hi, JB.
> 
> I worked a bit further on the patch and implemented the ForceRead logic
> for custom attributes.
> I aded a ForceResolving property to SignatureReader (it was the easiest way
> with the previous patch I made). If the patch if acceptable I'll prepare a
> separate and smaller patch to simplify SignatureReader abit and remove this
> property (pass it as a parameter).
> Attached is the patch and slightly modified test case.
> 
> Eyal.
> 
> On Thu, 5 Oct 2006, Jb Evain wrote:
> 
>> Date: Thu, 05 Oct 2006 19:16:47 +0200
>> From: Jb Evain <[EMAIL PROTECTED]>
>> To: Eyal Alaluf <[EMAIL PROTECTED]>
>> Cc: mono-devel-list@lists.ximian.com
>> Subject: Re: [Mono-dev] Parch for Enum support in Custom attributes
>>
>> Hi Eyal,
>>
>> Thanks for working on this. I don't want to commit it as it is, but 
>> I'll surely use part of it. I don't want to load the assembly 
>> referenced only for reading a custom attribute body. Instead, I'll 
>> create an interface that CustomAttribute and SecurityDeclaration will 
>> share, and will allow one to load the content of something that needs 
>> to load a reference.
>>
>> Something like:
>>
>> CustomAttribute ca = ...;
>> if (!ca.Read) {
>>     ca.ForceRead ();
>> }
>>
>> Otherwise, for a lot of assemblies, Cecil will have to load the 
>> corelib while the user don't necessary need to read the content of the 
>> custom attribute.
>>
>> Jb
>>
>> Eyal Alaluf wrote:
>>> Hi, JB.
>>>
>>> Attached is patch for supporting enums in cutom attributes. Support 
>>> is added
>>> for enums as ctor parameters as fields and as properties.
>>>
>>> The main problem with Enums is to identify their underlying integral 
>>> type.
>>> Without this integral type the custom attribute cannot be read. The 
>>> patch
>>> uses the assembly resolver for this purpose.
>>>
>>> I have attached a simple test scenraio with 3 C# files.
>>>     * Test1.cs is a DLL defining enums and an attribute that has 
>>> enums as
>>>       field properties and ctor params.
>>>     * Test2.cs is another DLL that uses the attribute and enums from 
>>> Test1.
>>>       This exercise the new code that resolves enum types from 
>>> another DLL.
>>>     * ReadTest2.cs is an EXE written using Cecil that parses 
>>> test2.dll and
>>>       prints the custom attributes of its types. It gets as argument 
>>> the path
>>>       to the dll it parses.
>>> Note that Test1 uses ClassUsageAttaribute from mscorlib. For some 
>>> reason the
>>> assembly resolver didn't find mscorlib.dll from the GAC when I ran 
>>> ReadTest2
>>> on Test2 until I put mscorlib.dll in the same dir as Test2 & ReadTest2.
>>>
>>> Eyal.
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> Index: Mono.Cecil/ReflectionReader.cs
>>> ===================================================================
>>> --- Mono.Cecil/ReflectionReader.cs    (revision 66216)
>>> +++ Mono.Cecil/ReflectionReader.cs    (working copy)
>>> @@ -65,7 +65,24 @@
>>>          protected CodeReader m_codeReader;
>>>          protected ISymbolReader m_symbolReader;
>>>  -        public ModuleDefinition Module {
>>> +        internal AssemblyNameReference Corlib
>>> +        {
>>> +            get +            {
>>> +                if (m_corlib == null) {
>>> +                    foreach (AssemblyNameReference ar in 
>>> m_module.AssemblyReferences) {
>>> +                        if (ar.Name == Constants.Corlib) {
>>> +                            m_corlib = ar;
>>> +                            break;
>>> +                        }
>>> +                    }
>>> +                }
>>> +                return m_corlib;
>>> +            }            +        }
>>> +
>>> +        public ModuleDefinition Module +        {
>>>              get { return m_module; }
>>>          }
>>>  @@ -295,19 +312,11 @@
>>>               TypeReference coreType =  m_module.TypeReferences 
>>> [fullName];
>>>              if (coreType == null) {
>>> -                if (m_corlib == null) {
>>> -                    foreach (AssemblyNameReference ar in 
>>> m_module.AssemblyReferences) {
>>> -                        if (ar.Name == Constants.Corlib) {
>>> -                            m_corlib = ar;
>>> -                            break;
>>> -                        }
>>> -                    }
>>> -                }
>>>                   string [] parts = fullName.Split ('.');
>>>                  if (parts.Length != 2)
>>>                      throw new ReflectionException ("Unvalid core 
>>> type name");
>>> -                coreType = new TypeReference (parts [1], parts [0], 
>>> m_corlib);
>>> +                coreType = new TypeReference (parts [1], parts [0], 
>>> Corlib);
>>>                  m_module.TypeReferences.Add (coreType);
>>>              }
>>>              if (!coreType.IsValueType) {
>>> Index: ChangeLog
>>> ===================================================================
>>> --- ChangeLog    (revision 66226)
>>> +++ ChangeLog    (working copy)
>>> @@ -1,3 +1,11 @@
>>> +2006-10-05  Eyal Alaluf  <[EMAIL PROTECTED]>
>>> +
>>> +    Mono.Cecil/ReflectionReader.cs:
>>> +        Expose Corlib assembly refereice so SignatureReader can ise it.
>>> +    Mono.Cecil.Signatures/SignatureReader.cs:
>>> +        Added support for enums in custom attributes ctors, 
>>> properties and
>>> +        fields.
>>> +         2006-10-04  Eyal Alaluf  <[EMAIL PROTECTED]>
>>>       * Mono.Cecil/StructureReader.cs:
>>> @@ -2,3 +10,2 @@
>>>          Visit the module we load when a DLL has more then 1 module.
>>> -            Visit the module we load when a DLL has more then 1 module.
>>>        Mono.Cecil/AssemblyNameReference.cs:
>>> Index: Mono.Cecil.Signatures/SignatureReader.cs
>>> ===================================================================
>>> --- Mono.Cecil.Signatures/SignatureReader.cs    (revision 66216)
>>> +++ Mono.Cecil.Signatures/SignatureReader.cs    (working copy)
>>> @@ -587,7 +587,7 @@
>>>          }
>>>           CustomAttrib.FixedArg ReadFixedArg (byte [] data, 
>>> BinaryReader br,
>>> -            bool array, object param, ref bool read)
>>> +            bool array, TypeReference param, ref bool read)
>>>          {
>>>              CustomAttrib.FixedArg fa = new CustomAttrib.FixedArg ();
>>>              if (array) {
>>> @@ -596,6 +596,7 @@
>>>                   if (fa.NumElem == 0 || fa.NumElem == 0xffffffff) {
>>>                      fa.Elems = new CustomAttrib.Elem [0];
>>> +                    fa.NumElem = 0;
>>>                      return fa;
>>>                  }
>>>  @@ -611,6 +612,95 @@
>>>              return fa;
>>>          }
>>>  +        TypeReference CreateEnumTypeReference (string enumName)
>>> +        {
>>> +            string asmName = null;
>>> +            int asmStart = enumName.IndexOf (',');
>>> +            if (asmStart != -1) {
>>> +                asmName = enumName.Substring (asmStart + 1);
>>> +                enumName = enumName.Substring (0, asmStart);
>>> +            }
>>> +            // Inner class style is reflection style.
>>> +            enumName = enumName.Replace ('+', '/');
>>> +            AssemblyNameReference asm = null;
>>> +            if (asmName == null) {
>>> +                // If no assembly is given then the ECMA standard 
>>> says the
>>> +                // assembly is either the current one or mscorlib.
>>> +                if (m_reflectReader.Module.Types[enumName] != null)
>>> +                    return m_reflectReader.Module.Types[enumName];
>>> +                asm = m_reflectReader.Corlib;
>>> +            }
>>> +            else
>>> +                asm = AssemblyNameReference.Parse (asmName);
>>> +
>>> +            string[] outers = enumName.Split ('/');
>>> +            string outerfullname = outers[0];
>>> +            string ns = null;
>>> +            int nsIndex = outerfullname.LastIndexOf ('.');
>>> +            if (nsIndex != -1)
>>> +                ns = outerfullname.Substring(0, nsIndex);
>>> +            string name = outerfullname.Substring (nsIndex + 1);
>>> +            TypeReference decType = new TypeReference (name, ns, asm);
>>> +            for (int i = 1; i < outers.Length; i++)
>>> +            {
>>> +                TypeReference t = new TypeReference (outers[i], 
>>> null, asm);
>>> +                t.DeclaringType = decType;
>>> +                decType = t;
>>> +            }
>>> +            decType.IsValueType = true;
>>> +
>>> +            return decType;
>>> +        }
>>> +
>>> +        TypeReference ReadTypeReference (byte[] data, BinaryReader 
>>> br, out ElementType elemType, out bool array)
>>> +        {
>>> +            array = false;
>>> +            elemType = (ElementType) br.ReadByte ();
>>> +            if (elemType == ElementType.SzArray) + {
>>> +                elemType = (ElementType) br.ReadByte ();
>>> +                array = true;
>>> +            }
>>> +
>>> +            switch (elemType) {
>>> +            case ElementType.Enum :
>>> +                return CreateEnumTypeReference (ReadUTF8String 
>>> (data, br));
>>> +            case ElementType.Boxed :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Object);
>>> +            case ElementType.String :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.String);
>>> +            case ElementType.Type :
>>> +                return m_reflectReader.SearchCoreType (Constants.Type);
>>> +            case ElementType.Boolean :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Boolean);
>>> +            case ElementType.Char :
>>> +                return m_reflectReader.SearchCoreType (Constants.Char);
>>> +            case ElementType.R4 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Single);
>>> +            case ElementType.R8 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Double);
>>> +            case ElementType.I1 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.SByte);
>>> +            case ElementType.I2 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Int16);
>>> +            case ElementType.I4 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Int32);
>>> +            case ElementType.I8 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.Int64);
>>> +            case ElementType.U1 :
>>> +                return m_reflectReader.SearchCoreType (Constants.Byte);
>>> +            case ElementType.U2 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.UInt16);
>>> +            case ElementType.U4 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.UInt32);
>>> +            case ElementType.U8 :
>>> +                return m_reflectReader.SearchCoreType 
>>> (Constants.UInt64);
>>> +            default :
>>> +                throw new MetadataFormatException ("Non valid type 
>>> in CustomAttrib.Elem: 0x{0}",
>>> +                    ((byte) elemType).ToString("x2"));
>>> +            }
>>> +        }
>>> +
>>>          internal CustomAttrib.NamedArg ReadNamedArg (byte [] data, 
>>> BinaryReader br, ref bool read)
>>>          {
>>>              CustomAttrib.NamedArg na = new CustomAttrib.NamedArg ();
>>> @@ -625,42 +715,15 @@
>>>                  throw new MetadataFormatException ("Wrong kind of 
>>> namedarg found: 0x" + kind.ToString("x2"));
>>>               bool array = false;
>>> -            na.FieldOrPropType = (ElementType) br.ReadByte ();
>>> -            if (na.FieldOrPropType == ElementType.SzArray) {
>>> -                na.FieldOrPropType = (ElementType) br.ReadByte ();
>>> -                array = true;
>>> -            }
>>>  -            int next, length;
>>> +            TypeReference elemType = ReadTypeReference (data, br, 
>>> out na.FieldOrPropType, out array);
>>>  -            if (na.FieldOrPropType == ElementType.Enum) {
>>> -                read = false;
>>> -                return na;
>>> -            }
>>> +            na.FieldOrPropName = ReadUTF8String (data, br);
>>> +            na.FixedArg = ReadFixedArg (data, br, array, elemType, 
>>> ref read);
>>>  -            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);
>>> -            na.FieldOrPropName = Encoding.UTF8.GetString (bytes, 0, 
>>> bytes.Length);
>>> -
>>> -            na.FixedArg = ReadFixedArg (data, br, array, 
>>> na.FieldOrPropType, ref read);
>>> -
>>>              return na;
>>>          }
>>>  -        // i hate this construction, should find something better
>>> -        CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, 
>>> object param, ref bool read)
>>> -        {
>>> -            if (param is TypeReference)
>>> -                return ReadElem (data, br, param as TypeReference, 
>>> ref read);
>>> -            else if (param is ElementType)
>>> -                return ReadElem (data, br, (ElementType) param, ref 
>>> read);
>>> -            else
>>> -                throw new MetadataFormatException ("Wrong parameter 
>>> for ReadElem: " + param.GetType ().FullName);
>>> -        }
>>> -
>>>          CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, 
>>> TypeReference elemType, ref bool read)
>>>          {
>>>              CustomAttrib.Elem elem = new CustomAttrib.Elem ();
>>> @@ -668,11 +731,20 @@
>>>              string elemName = elemType.FullName;
>>>               if (elemName == Constants.Object) {
>>> -                ElementType elementType = (ElementType) br.ReadByte ();
>>> -                elem = ReadElem (data, br, elementType, ref read);
>>> +                bool array;
>>> +                elemType = ReadTypeReference (data, br, out 
>>> elem.FieldOrPropType, out array);
>>> +
>>> +                if (array) {
>>> +                    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);
>>>                  elem.String = elem.Simple = elem.Type = false;
>>>                  elem.BoxedValueType = true;
>>> -                elem.FieldOrPropType = elementType;
>>>                  return elem;
>>>              }
>>>  @@ -694,19 +766,45 @@
>>>                      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);
>>> +                    elem.Value = ReadUTF8String (data, br);
>>>                  }
>>> -
>>>                  return elem;
>>>              }
>>>               elem.String = elem.Type = elem.BoxedValueType = false;
>>> +            if (!readSimpleValue (br, ref elem, elem.ElemType)) {
>>> +                TypeReference typeRef = GetEnumUnderlyingType 
>>> (elem.ElemType);
>>> +                if (typeRef == null || !readSimpleValue (br, ref 
>>> elem, typeRef))
>>> +                    read = false;
>>> +            }
>>>  -            switch (elemName) {
>>> +            return elem;
>>> +        }
>>> +
>>> +        private IAssemblyResolver AssemblyResolver
>>> +        {
>>> +            get +            { + return 
>>> m_reflectReader.Module.Assembly.Resolver;
>>> +            }
>>> +        }
>>> +
>>> +        private TypeReference GetEnumUnderlyingType (TypeReference 
>>> enumType)
>>> +        {
>>> +            TypeDefinition type = enumType as TypeDefinition;
>>> +            if (type == null && AssemblyResolver != null) + {
>>> +                AssemblyDefinition asm = AssemblyResolver.Resolve 
>>> (enumType.Scope.Name);
>>> +                type = asm.MainModule.Types[enumType.FullName];
>>> +            }
>>> +            if (type != null && type.IsEnum)
>>> +                return type.Fields.GetField ("value__").FieldType;
>>> +            return null;
>>> +        }
>>> +
>>> +        bool readSimpleValue (BinaryReader br, ref CustomAttrib.Elem 
>>> elem, TypeReference type)
>>> +        {
>>> +            switch (type.FullName) {
>>>              case Constants.Boolean :
>>>                  elem.Value = br.ReadByte () == 1;
>>>                  break;
>>> @@ -744,120 +842,12 @@
>>>                  elem.Value = br.ReadUInt64 ();
>>>                  break;
>>>              default : // enum
>>> -                read = false;
>>> -                return elem;
>>> +                return false;
>>>              }
>>> -
>>>              elem.Simple = true;
>>> -            return elem;
>>> +            return true;
>>>          }
>>>  -        // 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"));
>>> -            }
>>> -
>>> -            read = true;
>>> -            elem.Simple = true;
>>> -            return elem;
>>> -        }
>>> -
>>>          MarshalSig ReadMarshalSig (byte [] data)
>>>          {
>>>              int start;
>>> @@ -905,14 +895,21 @@
>>>              return ms;
>>>          }
>>>  +        static internal string ReadUTF8String (byte [] data, 
>>> BinaryReader br)
>>> +        {
>>> +            int start = (int)br.BaseStream.Position;
>>> +            string val = ReadUTF8String (data, start, out start);
>>> +            br.BaseStream.Position = start;
>>> +            return val;
>>> +        }
>>> +
>>>          static internal string ReadUTF8String (byte [] data, int 
>>> pos, out int start)
>>>          {
>>>              int length = Utilities.ReadCompressedInteger (data, pos, 
>>> out start);
>>> -            byte [] str = new byte [length];
>>> -            Buffer.BlockCopy (data, start, str, 0, length);
>>> +            pos = start;
>>>              start += length;
>>> -            // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) is 
>>> not supported.
>>> -            return Encoding.UTF8.GetString (str, 0, str.Length);
>>> +            // COMPACT FRAMEWORK NOTE: Encoding.GetString (byte[]) 
>>> is not supported.
>>> +            return Encoding.UTF8.GetString (data, pos, length);
>>>          }
>>>      }
>>>  }
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> Mono-devel-list mailing list
>>> Mono-devel-list@lists.ximian.com
>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>
> 
> ------------------------------------------------------------------------
> 
> Index: Mono.Cecil/CustomAttribute.cs
> 
> ===================================================================
> 
> --- Mono.Cecil/CustomAttribute.cs     (revision 66447)
> 
> +++ Mono.Cecil/CustomAttribute.cs     (working copy)
> 
> @@ -102,6 +102,19 @@
> 
>                       set { m_blob = value; }
>               }
>  
> +             public bool ForceRead ()
> +             {
> +                     if (IsReadable)
> +                             return true;
> +
> +                     ReflectionReader r = 
> m_ctor.DeclaringType.Module.Controller.Reader;
> +                     CustomAttribute newCa = r.GetCustomAttribute (m_ctor, 
> Blob, true);
> +                     if (!newCa.IsReadable)
> +                             return false;
> +                     newCa.CopyTo (this);
> +                     return true;
> +             }
> +
>               public CustomAttribute (MethodReference ctor)
>               {
>                       m_ctor = ctor;
> @@ -135,6 +148,7 @@
> 
>  
>               static void Clone (IDictionary original, IDictionary target)
>               {
> +                     target.Clear ();
>                       foreach (DictionaryEntry entry in original)
>                               target.Add (entry.Key, entry.Value);
>               }
> @@ -142,19 +156,24 @@
> 
>               internal static CustomAttribute Clone (CustomAttribute 
> custattr, ImportContext context)
>               {
>                       CustomAttribute ca = new CustomAttribute 
> (context.Import (custattr.Constructor));
> -                     if (!custattr.IsReadable) {
> -                             ca.IsReadable = false;
> -                             ca.Blob = custattr.Blob;
> -                             return ca;
> +                     custattr.CopyTo(ca);
> +                     return ca;
> +             }
> +
> +             private void CopyTo (CustomAttribute target)
> +             {
> +                     target.IsReadable = IsReadable;
> +                     if (!IsReadable) {
> +                             target.Blob = Blob;
> +                             return;
>                       }
>  
> -                     foreach (object o in custattr.ConstructorParameters)
> -                             ca.ConstructorParameters.Add (o);
> -                     Clone (custattr.Fields, ca.Fields);
> -                     Clone (custattr.FieldTypes, ca.FieldTypes);
> -                     Clone (custattr.Properties, ca.Properties);
> -                     Clone (custattr.PropertyTypes, ca.PropertyTypes);
> -                     return ca;
> +                     foreach (object o in ConstructorParameters)
> +                             target.ConstructorParameters.Add (o);
> +                     Clone (Fields, target.Fields);
> +                     Clone (FieldTypes, target.FieldTypes);
> +                     Clone (Properties, target.Properties);
> +                     Clone (PropertyTypes, target.PropertyTypes);
>               }
>  
>               public void Accept (IReflectionVisitor visitor)
> Index: Mono.Cecil/ReflectionReader.cs
> 
> ===================================================================
> 
> --- Mono.Cecil/ReflectionReader.cs    (revision 66447)
> 
> +++ Mono.Cecil/ReflectionReader.cs    (working copy)
> 
> @@ -65,7 +65,24 @@
> 
>               protected CodeReader m_codeReader;
>               protected ISymbolReader m_symbolReader;
>  
> -             public ModuleDefinition Module {
> +             internal AssemblyNameReference Corlib
> +             {
> +                     get 
> +                     {
> +                             if (m_corlib == null) {
> +                                     foreach (AssemblyNameReference ar in 
> m_module.AssemblyReferences) {
> +                                             if (ar.Name == 
> Constants.Corlib) {
> +                                                     m_corlib = ar;
> +                                                     break;
> +                                             }
> +                                     }
> +                             }
> +                             return m_corlib;
> +                     }                       
> +             }
> +
> +             public ModuleDefinition Module 
> +             {
>                       get { return m_module; }
>               }
>  
> @@ -295,19 +312,11 @@
> 
>  
>                       TypeReference coreType =  m_module.TypeReferences 
> [fullName];
>                       if (coreType == null) {
> -                             if (m_corlib == null) {
> -                                     foreach (AssemblyNameReference ar in 
> m_module.AssemblyReferences) {
> -                                             if (ar.Name == 
> Constants.Corlib) {
> -                                                     m_corlib = ar;
> -                                                     break;
> -                                             }
> -                                     }
> -                             }
>  
>                               string [] parts = fullName.Split ('.');
>                               if (parts.Length != 2)
>                                       throw new ReflectionException ("Unvalid 
> core type name");
> -                             coreType = new TypeReference (parts [1], parts 
> [0], m_corlib);
> +                             coreType = new TypeReference (parts [1], parts 
> [0], Corlib);
>                               m_module.TypeReferences.Add (coreType);
>                       }
>                       if (!coreType.IsValueType) {
> @@ -355,12 +364,20 @@
> 
>                       }
>               }
>  
> -             public CustomAttribute GetCustomAttribute (MethodReference 
> ctor, byte [] data)
> +             public CustomAttribute GetCustomAttribute (MethodReference 
> ctor, byte [] data, bool forceResolving)
>               {
> +                     bool keepForceResolving = m_sigReader.ForceResolving;
> +                     m_sigReader.ForceResolving = forceResolving;
>                       CustomAttrib sig = m_sigReader.GetCustomAttrib (data, 
> ctor);
> +                     m_sigReader.ForceResolving = keepForceResolving;
>                       return BuildCustomAttribute (ctor, sig);
>               }
>  
> +             public CustomAttribute GetCustomAttribute (MethodReference 
> ctor, byte [] data)
> +             {
> +                     return GetCustomAttribute (ctor, data, false);
> +             }
> +
>               public override void VisitModuleDefinition (ModuleDefinition 
> mod)
>               {
>                       VisitTypeDefinitionCollection (mod.Types);
> Index: ChangeLog
> 
> ===================================================================
> 
> --- ChangeLog (revision 66447)
> 
> +++ ChangeLog (working copy)
> 
> @@ -1,3 +1,17 @@
> 
> +2006-10-09  Eyal Alaluf  <[EMAIL PROTECTED]>
> +
> +     Mono.Cecil.Signatures/SignatureReader.cs:
> +             Added support for enums in custom attributes ctors, properties 
> and
> +             fields.
> +     Mono.Cecil/CustomAttribute.cs:
> +             Add support for rereading custom attributes that contain 
> references
> +             to enum in other assemblies.
> +     Mono.Cecil/ReflectionReader.cs:
> +             Add support for reading custom attributes while resolving enums 
> from
> +             other assemblies then the current one.
> +     Mono.Cecil/ReflectionReader.cs:
> +             Expose Corlib assembly refereice so SignatureReader can ise it.
> +             
>  2006-10-09  Jb Evain  <[EMAIL PROTECTED]>
>  
>       * Mono.Cecil/SecurityDeclarationReader.cs:
> @@ -8,7 +22,6 @@
> 
>  
>       * Mono.Cecil/StructureReader.cs:
>               Visit the module we load when a DLL has more then 1 module.
> -                     Visit the module we load when a DLL has more then 1 
> module.
>         Mono.Cecil/AssemblyNameReference.cs:
>               Allow "PublicToken=null" when parsing an assembly full name.
>  
> Index: Mono.Cecil.Signatures/SignatureReader.cs
> 
> ===================================================================
> 
> --- Mono.Cecil.Signatures/SignatureReader.cs  (revision 66447)
> 
> +++ Mono.Cecil.Signatures/SignatureReader.cs  (working copy)
> 
> @@ -41,6 +41,7 @@
> 
>               MetadataRoot m_root;
>               ReflectionReader m_reflectReader;
>               byte [] m_blobData;
> +             bool m_forceResolving = false;
>  
>               IDictionary m_signatures;
>  
> @@ -54,6 +55,12 @@
> 
>                       m_signatures = new Hashtable ();
>               }
>  
> +             public bool ForceResolving
> +             {
> +                     get { return m_forceResolving; }
> +                     set { m_forceResolving = value; }
> +             }
> +
>               public FieldSig GetFieldSig (uint index)
>               {
>                       FieldSig f = m_signatures [index] as FieldSig;
> @@ -587,7 +594,7 @@
> 
>               }
>  
>               CustomAttrib.FixedArg ReadFixedArg (byte [] data, BinaryReader 
> br,
> -                     bool array, object param, ref bool read)
> +                     bool array, TypeReference param, ref bool read)
>               {
>                       CustomAttrib.FixedArg fa = new CustomAttrib.FixedArg ();
>                       if (array) {
> @@ -596,6 +603,7 @@
> 
>  
>                               if (fa.NumElem == 0 || fa.NumElem == 
> 0xffffffff) {
>                                       fa.Elems = new CustomAttrib.Elem [0];
> +                                     fa.NumElem = 0;
>                                       return fa;
>                               }
>  
> @@ -611,6 +619,95 @@
> 
>                       return fa;
>               }
>  
> +             TypeReference CreateEnumTypeReference (string enumName)
> +             {
> +                     string asmName = null;
> +                     int asmStart = enumName.IndexOf (',');
> +                     if (asmStart != -1) {
> +                             asmName = enumName.Substring (asmStart + 1);
> +                             enumName = enumName.Substring (0, asmStart);
> +                     }
> +                     // Inner class style is reflection style.
> +                     enumName = enumName.Replace ('+', '/');
> +                     AssemblyNameReference asm = null;
> +                     if (asmName == null) {
> +                             // If no assembly is given then the ECMA 
> standard says the
> +                             // assembly is either the current one or 
> mscorlib.
> +                             if (m_reflectReader.Module.Types[enumName] != 
> null)
> +                                     return 
> m_reflectReader.Module.Types[enumName];
> +                             asm = m_reflectReader.Corlib;
> +                     }
> +                     else
> +                             asm = AssemblyNameReference.Parse (asmName);
> +
> +                     string[] outers = enumName.Split ('/');
> +                     string outerfullname = outers[0];
> +                     string ns = null;
> +                     int nsIndex = outerfullname.LastIndexOf ('.');
> +                     if (nsIndex != -1)
> +                             ns = outerfullname.Substring(0, nsIndex);
> +                     string name = outerfullname.Substring (nsIndex + 1);
> +                     TypeReference decType = new TypeReference (name, ns, 
> asm);
> +                     for (int i = 1; i < outers.Length; i++)
> +                     {
> +                             TypeReference t = new TypeReference (outers[i], 
> null, asm);
> +                             t.DeclaringType = decType;
> +                             decType = t;
> +                     }
> +                     decType.IsValueType = true;
> +
> +                     return decType;
> +             }
> +
> +             TypeReference ReadTypeReference (byte[] data, BinaryReader br, 
> out ElementType elemType, out bool array)
> +             {
> +                     array = false;
> +                     elemType = (ElementType) br.ReadByte ();
> +                     if (elemType == ElementType.SzArray) 
> +                     {
> +                             elemType = (ElementType) br.ReadByte ();
> +                             array = true;
> +                     }
> +
> +                     switch (elemType) {
> +                     case ElementType.Enum :
> +                             return CreateEnumTypeReference (ReadUTF8String 
> (data, br));
> +                     case ElementType.Boxed :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Object);
> +                     case ElementType.String :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.String);
> +                     case ElementType.Type :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Type);
> +                     case ElementType.Boolean :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Boolean);
> +                     case ElementType.Char :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Char);
> +                     case ElementType.R4 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Single);
> +                     case ElementType.R8 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Double);
> +                     case ElementType.I1 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.SByte);
> +                     case ElementType.I2 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Int16);
> +                     case ElementType.I4 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Int32);
> +                     case ElementType.I8 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Int64);
> +                     case ElementType.U1 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.Byte);
> +                     case ElementType.U2 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.UInt16);
> +                     case ElementType.U4 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.UInt32);
> +                     case ElementType.U8 :
> +                             return m_reflectReader.SearchCoreType 
> (Constants.UInt64);
> +                     default :
> +                             throw new MetadataFormatException ("Non valid 
> type in CustomAttrib.Elem: 0x{0}",
> +                                     ((byte) elemType).ToString("x2"));
> +                     }
> +             }
> +
>               internal CustomAttrib.NamedArg ReadNamedArg (byte [] data, 
> BinaryReader br, ref bool read)
>               {
>                       CustomAttrib.NamedArg na = new CustomAttrib.NamedArg ();
> @@ -625,42 +722,15 @@
> 
>                               throw new MetadataFormatException ("Wrong kind 
> of namedarg found: 0x" + kind.ToString("x2"));
>  
>                       bool array = false;
> -                     na.FieldOrPropType = (ElementType) br.ReadByte ();
> -                     if (na.FieldOrPropType == ElementType.SzArray) {
> -                             na.FieldOrPropType = (ElementType) br.ReadByte 
> ();
> -                             array = true;
> -                     }
>  
> -                     int next, length;
> +                     TypeReference elemType = ReadTypeReference (data, br, 
> out na.FieldOrPropType, out array);
>  
> -                     if (na.FieldOrPropType == ElementType.Enum) {
> -                             read = false;
> -                             return na;
> -                     }
> +                     na.FieldOrPropName = ReadUTF8String (data, br);
> +                     na.FixedArg = ReadFixedArg (data, br, array, elemType, 
> ref read);
>  
> -                     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);
> -                     na.FieldOrPropName = Encoding.UTF8.GetString (bytes, 0, 
> bytes.Length);
> -
> -                     na.FixedArg = ReadFixedArg (data, br, array, 
> na.FieldOrPropType, ref read);
> -
>                       return na;
>               }
>  
> -             // i hate this construction, should find something better
> -             CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, 
> object param, ref bool read)
> -             {
> -                     if (param is TypeReference)
> -                             return ReadElem (data, br, param as 
> TypeReference, ref read);
> -                     else if (param is ElementType)
> -                             return ReadElem (data, br, (ElementType) param, 
> ref read);
> -                     else
> -                             throw new MetadataFormatException ("Wrong 
> parameter for ReadElem: " + param.GetType ().FullName);
> -             }
> -
>               CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, 
> TypeReference elemType, ref bool read)
>               {
>                       CustomAttrib.Elem elem = new CustomAttrib.Elem ();
> @@ -668,11 +738,20 @@
> 
>                       string elemName = elemType.FullName;
>  
>                       if (elemName == Constants.Object) {
> -                             ElementType elementType = (ElementType) 
> br.ReadByte ();
> -                             elem = ReadElem (data, br, elementType, ref 
> read);
> +                             bool array;
> +                             elemType = ReadTypeReference (data, br, out 
> elem.FieldOrPropType, out array);
> +
> +                             if (array) {
> +                                     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);
>                               elem.String = elem.Simple = elem.Type = false;
>                               elem.BoxedValueType = true;
> -                             elem.FieldOrPropType = elementType;
>                               return elem;
>                       }
>  
> @@ -694,19 +773,45 @@
> 
>                                       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);
> +                                     elem.Value = ReadUTF8String (data, br);
>                               }
> -
>                               return elem;
>                       }
>  
>                       elem.String = elem.Type = elem.BoxedValueType = false;
> +                     if (!readSimpleValue (br, ref elem, elem.ElemType)) {
> +                             TypeReference typeRef = GetEnumUnderlyingType 
> (elem.ElemType);
> +                             if (typeRef == null || !readSimpleValue (br, 
> ref elem, typeRef))
> +                                     read = false;
> +                     }
>  
> -                     switch (elemName) {
> +                     return elem;
> +             }
> +
> +             private IAssemblyResolver AssemblyResolver
> +             {
> +                     get 
> +                     { 
> +                             return m_reflectReader.Module.Assembly.Resolver;
> +                     }
> +             }
> +
> +             private TypeReference GetEnumUnderlyingType (TypeReference 
> enumType)
> +             {
> +                     TypeDefinition type = enumType as TypeDefinition;
> +                     if (type == null && ForceResolving && AssemblyResolver 
> != null) 
> +                     {
> +                             AssemblyDefinition asm = 
> AssemblyResolver.Resolve (enumType.Scope.Name);
> +                             type = asm.MainModule.Types[enumType.FullName];
> +                     }
> +                     if (type != null && type.IsEnum)
> +                             return type.Fields.GetField 
> ("value__").FieldType;
> +                     return null;
> +             }
> +
> +             bool readSimpleValue (BinaryReader br, ref CustomAttrib.Elem 
> elem, TypeReference type)
> +             {
> +                     switch (type.FullName) {
>                       case Constants.Boolean :
>                               elem.Value = br.ReadByte () == 1;
>                               break;
> @@ -744,120 +849,12 @@
> 
>                               elem.Value = br.ReadUInt64 ();
>                               break;
>                       default : // enum
> -                             read = false;
> -                             return elem;
> +                             return false;
>                       }
> -
>                       elem.Simple = true;
> -                     return elem;
> +                     return true;
>               }
>  
> -             // 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"));
> -                     }
> -
> -                     read = true;
> -                     elem.Simple = true;
> -                     return elem;
> -             }
> -
>               MarshalSig ReadMarshalSig (byte [] data)
>               {
>                       int start;
> @@ -905,14 +902,21 @@
> 
>                       return ms;
>               }
>  
> +             static internal string ReadUTF8String (byte [] data, 
> BinaryReader br)
> +             {
> +                     int start = (int)br.BaseStream.Position;
> +                     string val = ReadUTF8String (data, start, out start);
> +                     br.BaseStream.Position = start;
> +                     return val;
> +             }
> +
>               static internal string ReadUTF8String (byte [] data, int pos, 
> out int start)
>               {
>                       int length = Utilities.ReadCompressedInteger (data, 
> pos, out start);
> -                     byte [] str = new byte [length];
> -                     Buffer.BlockCopy (data, start, str, 0, length);
> +                     pos = start;
>                       start += length;
> -                     // COMPACT FRAMEWORK NOTE: Encoding.GetString(byte[]) 
> is not supported.
> -                     return Encoding.UTF8.GetString (str, 0, str.Length);
> +                     // COMPACT FRAMEWORK NOTE: Encoding.GetString (byte[]) 
> is not supported.
> +                     return Encoding.UTF8.GetString (data, pos, length);
>               }
>       }
>  }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to