public TypeInfo(DeserializationContext context, String name, String[] fieldNames, BinaryTypeTag[] tt, TypeSpecification[] ts, Assembly assembly) { mConverter = context.Formatter.converter; mFieldNames = fieldNames; mTypeTag = tt; mTypeSpec = ts; // lookup our type in the right assembly if(assembly == null) { mObjectType = Type.GetType(name, true); } else { mObjectType = assembly.GetType(name, true); } if(typeof(ISerializable).IsAssignableFrom(mObjectType)) { mIsIserializable = true; } else { mIsIserializable = false; // lookup all members once mMembers = new MemberInfo[NumMembers]; for(int i = 0; i < NumMembers; i++) { // ms and mono have their values for boxed primitive types called 'm_value', we need a fix for that if(mObjectType.IsPrimitive && (mFieldNames[i] == "m_value")) { mFieldNames[i] = "value_"; } else if (mObjectType == typeof(DateTime) && (mFieldNames[i] == "ticks")) { // this is for DateTime mFieldNames[i] = "value_"; } else if (mObjectType == typeof(TimeSpan) && (mFieldNames[i] == "_ticks")) { // this is for TimeSpan mFieldNames[i] = "value_"; } else if (mObjectType == typeof(Decimal)) { switch(mFieldNames[i]) { case "hi": { mFieldNames[i] = "high"; } break; case "lo": { mFieldNames[i] = "low"; } break; case "mid": { mFieldNames[i] = "middle"; } break; } } Type memberType; String memberName; int classSeparator = mFieldNames[i].IndexOf('+'); if(classSeparator != -1) { /* * TODO: check if there are constraints in which assembly * the Type may be looked up! for now just look it up * generally */ String baseName = mFieldNames[i].Substring(0, classSeparator); memberName = mFieldNames[i].Substring(classSeparator+1, mFieldNames[i].Length-classSeparator-1); memberType = mObjectType; // MS does NOT store the FullQualifiedTypename if there // is no collision but only the Typename :-( while(!memberType.FullName.EndsWith(baseName)) { // check if we reached System.Object if(memberType == memberType.BaseType || memberType == null) { // TODO : I18n throw new SerializationException("Can't find member "+mFieldNames[i]); } memberType = memberType.BaseType; } } else { memberType = mObjectType; memberName = mFieldNames[i]; } // get member from object MemberInfo[] members = memberType.GetMember(memberName, MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if((members == null) || (members.Length < 1)) { // TODO: I18n throw new SerializationException("Can't find member "+mFieldNames[i]); } else { mMembers[i] = members[0]; } } } }
public bool Read(DeserializationContext context, out Object outVal, bool external) { uint id = context.Reader.ReadUInt32(); String name = context.Reader.ReadString(); uint fieldCount = context.Reader.ReadUInt32(); // collect the names of the fields String[] fieldNames = new String[fieldCount]; for(int i = 0; i < fieldCount; i++) { fieldNames[i] = context.Reader.ReadString(); } // collect the type-tags of the fields BinaryTypeTag[] typeTags = new BinaryTypeTag[fieldCount]; for(int i = 0; i < fieldCount; i++) { typeTags[i] = (BinaryTypeTag) context.Reader.ReadByte(); } // collect the type-specifications of the fields if necessary TypeSpecification[] typeSpecs = new TypeSpecification[fieldCount]; for(int i = 0; i < fieldCount; i++) { typeSpecs[i] = ReadTypeSpec(context, typeTags[i]); } // read assembly-id if this is no runtime object Assembly assembly = null; if(external) { assembly = context.GetAssembly(context.Reader.ReadUInt32()); } // store type-information for later usage TypeInfo typeInfo = new TypeInfo(context, name, fieldNames, typeTags, typeSpecs, assembly); context.SetTypeInfo(id, typeInfo); // let our parent read the inlined values return Read(context, out outVal, id, typeInfo); }