Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / Serialization / Models.cs / 3 / Models.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Serialization { using System; using System.Reflection; using System.Collections; using System.Diagnostics; // These classes define the abstract serialization model, e.g. the rules for WHAT is serialized. // The answer of HOW the values are serialized is answered by a particular reflection importer // by looking for a particular set of custom attributes specific to the serialization format // and building an appropriate set of accessors/mappings. internal class ModelScope { TypeScope typeScope; Hashtable models = new Hashtable(); Hashtable arrayModels = new Hashtable(); internal ModelScope(TypeScope typeScope) { this.typeScope = typeScope; } internal TypeScope TypeScope { get { return typeScope; } } internal TypeModel GetTypeModel(Type type) { return GetTypeModel(type, true); } internal TypeModel GetTypeModel(Type type, bool directReference) { TypeModel model = (TypeModel)models[type]; if (model != null) return model; TypeDesc typeDesc = typeScope.GetTypeDesc(type, null, directReference); switch (typeDesc.Kind) { case TypeKind.Enum: model = new EnumModel(type, typeDesc, this); break; case TypeKind.Primitive: model = new PrimitiveModel(type, typeDesc, this); break; case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: model = new ArrayModel(type, typeDesc, this); break; case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: model = new StructModel(type, typeDesc, this); break; default: if (!typeDesc.IsSpecial) throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedTypeKind, type.FullName)); model = new SpecialModel(type, typeDesc, this); break; } models.Add(type, model); return model; } internal ArrayModel GetArrayModel(Type type) { TypeModel model = (TypeModel) arrayModels[type]; if (model == null) { model = GetTypeModel(type); if (!(model is ArrayModel)) { TypeDesc typeDesc = typeScope.GetArrayTypeDesc(type); model = new ArrayModel(type, typeDesc, this); } arrayModels.Add(type, model); } return (ArrayModel) model; } } internal abstract class TypeModel { TypeDesc typeDesc; Type type; ModelScope scope; protected TypeModel(Type type, TypeDesc typeDesc, ModelScope scope) { this.scope = scope; this.type = type; this.typeDesc = typeDesc; } internal Type Type { get { return type; } } internal ModelScope ModelScope { get { return scope; } } internal TypeDesc TypeDesc { get { return typeDesc; } } } internal class ArrayModel : TypeModel { internal ArrayModel(Type type, TypeDesc typeDesc, ModelScope scope) : base(type, typeDesc, scope) { } internal TypeModel Element { get { return ModelScope.GetTypeModel(TypeScope.GetArrayElementType(Type, null)); } } } internal class PrimitiveModel : TypeModel { internal PrimitiveModel(Type type, TypeDesc typeDesc, ModelScope scope) : base(type, typeDesc, scope) { } } internal class SpecialModel : TypeModel { internal SpecialModel(Type type, TypeDesc typeDesc, ModelScope scope) : base(type, typeDesc, scope) { } } internal class StructModel : TypeModel { internal StructModel(Type type, TypeDesc typeDesc, ModelScope scope) : base(type, typeDesc, scope) { } internal MemberInfo[] GetMemberInfos() { // we use to return Type.GetMembers() here, the members were returned in a different order: fields first, properties last // Current System.Reflection code returns members in oposite order: properties first, then fields. // This code make sure that returns members in the Everett order. MemberInfo[] members = Type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); MemberInfo[] fieldsAndProps = new MemberInfo[members.Length]; int cMember = 0; // first copy all non-property members over for (int i = 0; i < members.Length; i++) { if ((members[i].MemberType & MemberTypes.Property) == 0) { fieldsAndProps[cMember++] = members[i]; } } // now copy all property members over for (int i = 0; i < members.Length; i++) { if ((members[i].MemberType & MemberTypes.Property) != 0) { fieldsAndProps[cMember++] = members[i]; } } return fieldsAndProps; } internal FieldModel GetFieldModel(MemberInfo memberInfo) { FieldModel model = null; if (memberInfo is FieldInfo) model = GetFieldModel((FieldInfo)memberInfo); else if (memberInfo is PropertyInfo) model = GetPropertyModel((PropertyInfo)memberInfo); if (model != null) { if (model.ReadOnly && model.FieldTypeDesc.Kind != TypeKind.Collection && model.FieldTypeDesc.Kind != TypeKind.Enumerable) return null; } return model; } void CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) { if (typeDesc == null) return; if (typeDesc.IsUnsupported) { if (typeDesc.Exception == null) { typeDesc.Exception = new NotSupportedException(Res.GetString(Res.XmlSerializerUnsupportedType, typeDesc.FullName)); } throw new InvalidOperationException(Res.GetString(Res.XmlSerializerUnsupportedMember,member.DeclaringType.FullName + "." + member.Name, type.FullName), typeDesc.Exception); } CheckSupportedMember(typeDesc.BaseTypeDesc, member, type); CheckSupportedMember(typeDesc.ArrayElementTypeDesc, member, type); } FieldModel GetFieldModel(FieldInfo fieldInfo) { if (fieldInfo.IsStatic) return null; if (fieldInfo.DeclaringType != Type) return null; TypeDesc typeDesc = ModelScope.TypeScope.GetTypeDesc(fieldInfo.FieldType, fieldInfo, true, false); if (fieldInfo.IsInitOnly && typeDesc.Kind != TypeKind.Collection && typeDesc.Kind != TypeKind.Enumerable) return null; CheckSupportedMember(typeDesc, fieldInfo, fieldInfo.FieldType); return new FieldModel(fieldInfo, fieldInfo.FieldType, typeDesc); } FieldModel GetPropertyModel(PropertyInfo propertyInfo) { if (propertyInfo.DeclaringType != Type) return null; if (CheckPropertyRead(propertyInfo)) { TypeDesc typeDesc = ModelScope.TypeScope.GetTypeDesc(propertyInfo.PropertyType, propertyInfo, true, false); if (!propertyInfo.CanWrite && typeDesc.Kind != TypeKind.Collection && typeDesc.Kind != TypeKind.Enumerable) return null; CheckSupportedMember(typeDesc, propertyInfo, propertyInfo.PropertyType); return new FieldModel(propertyInfo, propertyInfo.PropertyType, typeDesc); } return null; } //CheckProperty internal static bool CheckPropertyRead(PropertyInfo propertyInfo) { if (!propertyInfo.CanRead) return false; MethodInfo getMethod = propertyInfo.GetGetMethod(); if (getMethod.IsStatic) return false; ParameterInfo[] parameters = getMethod.GetParameters(); if (parameters.Length > 0) return false; return true; } } internal enum SpecifiedAccessor { None, ReadOnly, ReadWrite, } internal class FieldModel { SpecifiedAccessor checkSpecified = SpecifiedAccessor.None; bool checkShouldPersist; bool readOnly = false; bool isProperty = false; Type fieldType; string name; TypeDesc fieldTypeDesc; internal FieldModel(string name, Type fieldType, TypeDesc fieldTypeDesc, bool checkSpecified, bool checkShouldPersist) : this(name, fieldType, fieldTypeDesc, checkSpecified, checkShouldPersist, false) { } internal FieldModel(string name, Type fieldType, TypeDesc fieldTypeDesc, bool checkSpecified, bool checkShouldPersist, bool readOnly) { this.fieldTypeDesc = fieldTypeDesc; this.name = name; this.fieldType = fieldType; this.checkSpecified = checkSpecified ? SpecifiedAccessor.ReadWrite : SpecifiedAccessor.None; this.checkShouldPersist = checkShouldPersist; this.readOnly = readOnly; } internal FieldModel(MemberInfo memberInfo, Type fieldType, TypeDesc fieldTypeDesc) { this.name = memberInfo.Name; this.fieldType = fieldType; this.fieldTypeDesc = fieldTypeDesc; this.checkShouldPersist = memberInfo.DeclaringType.GetMethod("ShouldSerialize" + memberInfo.Name, new Type[0]) != null; FieldInfo specifiedField = memberInfo.DeclaringType.GetField(memberInfo.Name + "Specified"); if (specifiedField != null) { if (specifiedField.FieldType != typeof(bool)) { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSpecifiedType, specifiedField.Name, specifiedField.FieldType.FullName, typeof(bool).FullName)); } this.checkSpecified = specifiedField.IsInitOnly ? SpecifiedAccessor.ReadOnly : SpecifiedAccessor.ReadWrite; } else { PropertyInfo specifiedProperty = memberInfo.DeclaringType.GetProperty(memberInfo.Name + "Specified"); if (specifiedProperty != null) { if (StructModel.CheckPropertyRead(specifiedProperty)) { this.checkSpecified = specifiedProperty.CanWrite ? SpecifiedAccessor.ReadWrite : SpecifiedAccessor.ReadOnly; } if (this.checkSpecified != SpecifiedAccessor.None && specifiedProperty.PropertyType != typeof(bool)) { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSpecifiedType, specifiedProperty.Name, specifiedProperty.PropertyType.FullName, typeof(bool).FullName)); } } } if (memberInfo is PropertyInfo) { readOnly = !((PropertyInfo)memberInfo).CanWrite; isProperty = true; } else if (memberInfo is FieldInfo) { readOnly = ((FieldInfo)memberInfo).IsInitOnly; } } internal string Name { get { return name; } } internal Type FieldType { get { return fieldType; } } internal TypeDesc FieldTypeDesc { get { return fieldTypeDesc; } } internal bool CheckShouldPersist { get { return checkShouldPersist; } } internal SpecifiedAccessor CheckSpecified { get { return checkSpecified; } } internal bool ReadOnly { get { return readOnly; } } internal bool IsProperty { get { return isProperty; } } } internal class ConstantModel { FieldInfo fieldInfo; long value; internal ConstantModel(FieldInfo fieldInfo, long value) { this.fieldInfo = fieldInfo; this.value = value; } internal string Name { get { return fieldInfo.Name; } } internal long Value { get { return value; } } internal FieldInfo FieldInfo { get { return fieldInfo; } } } internal class EnumModel : TypeModel { ConstantModel[] constants; internal EnumModel(Type type, TypeDesc typeDesc, ModelScope scope) : base(type, typeDesc, scope) { } internal ConstantModel[] Constants { get { if (constants == null) { ArrayList list = new ArrayList(); FieldInfo[] fields = Type.GetFields(); for (int i = 0; i < fields.Length; i++) { FieldInfo field = fields[i]; ConstantModel constant = GetConstantModel(field); if (constant != null) list.Add(constant); } constants = (ConstantModel[])list.ToArray(typeof(ConstantModel)); } return constants; } } ConstantModel GetConstantModel(FieldInfo fieldInfo) { if (fieldInfo.IsSpecialName) return null; return new ConstantModel(fieldInfo, ((IConvertible)fieldInfo.GetValue(null)).ToInt64(null)); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EditableRegion.cs
- FrameworkElementFactory.cs
- DataObjectCopyingEventArgs.cs
- GroupBoxDesigner.cs
- TablePattern.cs
- KeyedQueue.cs
- RightsManagementSuppressedStream.cs
- XPathScanner.cs
- Storyboard.cs
- MetafileHeader.cs
- AppDomainShutdownMonitor.cs
- RenderDataDrawingContext.cs
- LingerOption.cs
- TcpClientSocketManager.cs
- CommandPlan.cs
- InternalConfigEventArgs.cs
- BitmapCodecInfoInternal.cs
- _DomainName.cs
- ThreadAttributes.cs
- ProviderManager.cs
- CodePrimitiveExpression.cs
- Hex.cs
- WpfKnownMember.cs
- CodeGotoStatement.cs
- ObjectPropertyMapping.cs
- HScrollProperties.cs
- SqlCacheDependencyDatabaseCollection.cs
- UseManagedPresentationBindingElementImporter.cs
- SqlDataSourceSelectingEventArgs.cs
- DataSourceXmlClassAttribute.cs
- Win32MouseDevice.cs
- UniqueIdentifierService.cs
- NameSpaceExtractor.cs
- WebExceptionStatus.cs
- WorkflowServiceHost.cs
- DSASignatureFormatter.cs
- PieceDirectory.cs
- SecurityListenerSettingsLifetimeManager.cs
- TemplatePropertyEntry.cs
- BitVec.cs
- XmlObjectSerializerWriteContext.cs
- ObjectStateFormatter.cs
- DataGridViewControlCollection.cs
- XmlHierarchicalDataSourceView.cs
- StructuredTypeEmitter.cs
- FileDialogCustomPlacesCollection.cs
- SecuritySessionClientSettings.cs
- RangeValuePattern.cs
- _NestedMultipleAsyncResult.cs
- GeneralTransform3DGroup.cs
- PrintPageEvent.cs
- Route.cs
- SystemColors.cs
- XmlSchemaComplexContentRestriction.cs
- AppearanceEditorPart.cs
- Process.cs
- EventLogTraceListener.cs
- DictionaryKeyPropertyAttribute.cs
- QueryContinueDragEventArgs.cs
- DerivedKeyCachingSecurityTokenSerializer.cs
- TableItemProviderWrapper.cs
- HwndHostAutomationPeer.cs
- MILUtilities.cs
- CustomErrorCollection.cs
- RedistVersionInfo.cs
- PreservationFileWriter.cs
- DataGridViewCellLinkedList.cs
- UpdateCompiler.cs
- XmlLoader.cs
- OleDbSchemaGuid.cs
- BamlTreeUpdater.cs
- RelationshipType.cs
- CompoundFileDeflateTransform.cs
- ContainerAction.cs
- DataGridColumn.cs
- Stacktrace.cs
- SqlDataRecord.cs
- WebContext.cs
- RichTextBoxAutomationPeer.cs
- PathFigureCollection.cs
- SystemDiagnosticsSection.cs
- ErrorTableItemStyle.cs
- WebHeaderCollection.cs
- SqlConnectionFactory.cs
- BookmarkScopeManager.cs
- PersonalizableTypeEntry.cs
- Int16AnimationUsingKeyFrames.cs
- ProcessActivityTreeOptions.cs
- DataGridViewColumnConverter.cs
- FrameworkContentElement.cs
- ToolboxComponentsCreatedEventArgs.cs
- PermissionSet.cs
- IODescriptionAttribute.cs
- ImportContext.cs
- ByteAnimationBase.cs
- HttpRuntimeSection.cs
- EmptyElement.cs
- TaskFormBase.cs
- CannotUnloadAppDomainException.cs
- ArraySortHelper.cs