Ejemplo n.º 1
0
        public static TypeData GetTypeData(Type runtimeType, string xmlDataType)
        {
            Type type             = runtimeType;
            bool nullableOverride = false;

#if NET_2_0
            // Nullable<T> is serialized as T
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                nullableOverride = true;
                type             = type.GetGenericArguments() [0];

                TypeData pt = GetTypeData(type);                  // beware this recursive call btw ...
                if (pt != null)
                {
                    TypeData tt = (TypeData)nullableTypes [pt.XmlType];
#if TARGET_JVM
                    if (tt == null)
                    {
                        tt = (TypeData)AppDomain_nullableTypes [pt.XmlType];
                    }
#endif
                    if (tt == null)
                    {
                        tt            = new TypeData(type, pt.XmlType, false);
                        tt.IsNullable = true;
#if TARGET_JVM
                        AppDomain_nullableTypes [pt.XmlType] = tt;
#else
                        nullableTypes [pt.XmlType] = tt;
#endif
                    }
                    return(tt);
                }
            }
#endif

            if ((xmlDataType != null) && (xmlDataType.Length != 0))
            {
                // If the type is an array, xmlDataType specifies the type for the array elements,
                // not for the whole array. The exception is base64Binary, since it is a byte[],
                // that's why the following check is needed.
                TypeData at = GetPrimitiveTypeData(xmlDataType);
                if (type.IsArray && type != at.Type)
                {
                    TypeData tt = (TypeData)primitiveArrayTypes [xmlDataType];
                    if (tt != null)
                    {
                        return(tt);
                    }
                    if (at.Type == type.GetElementType())
                    {
                        tt = new TypeData(type, GetArrayName(at.XmlType), false);
                        primitiveArrayTypes [xmlDataType] = tt;
                        return(tt);
                    }
                    else
                    {
                        throw new InvalidOperationException("Cannot convert values of type '" + type.GetElementType() + "' to '" + xmlDataType + "'");
                    }
                }
                return(at);
            }

            TypeData typeData = nameCache[runtimeType] as TypeData;
            if (typeData != null)
            {
                return(typeData);
            }

#if TARGET_JVM
            Hashtable dynamicCache = AppDomain_nameCache;
            typeData = dynamicCache[runtimeType] as TypeData;
            if (typeData != null)
            {
                return(typeData);
            }
#endif

            string name;
            if (type.IsArray)
            {
                string sufix = GetTypeData(type.GetElementType()).XmlType;
                name = GetArrayName(sufix);
            }
#if NET_2_0
            else if (type.IsGenericType && !type.IsGenericTypeDefinition)
            {
                name = XmlConvert.EncodeLocalName(type.Name.Substring(0, type.Name.IndexOf('`'))) + "Of";
                foreach (Type garg in type.GetGenericArguments())
                {
                    name += garg.IsArray || garg.IsGenericType ?
                            GetTypeData(garg).XmlType :
                            CodeIdentifier.MakePascal(XmlConvert.EncodeLocalName(garg.Name));
                }
            }
#endif
            else
            {
                name = XmlConvert.EncodeLocalName(type.Name);
            }

            typeData = new TypeData(type, name, false);
            if (nullableOverride)
            {
                typeData.IsNullable = true;
            }
#if TARGET_JVM
            dynamicCache[runtimeType] = typeData;
#else
            nameCache[runtimeType] = typeData;
#endif
            return(typeData);
        }