// Deserializes IList private object DeserializeList(Type objectType, int cacheID, ObjectMetaData metaData) { // implements IList int count = ReadInt32(); IList ilist = Activator.CreateInstance(objectType) as IList; if (cacheID > 0) { Cache.SetCachedObjectId(ilist, cacheID); } Type baseType = typeof(object); if (metaData.GenericParameters != null && metaData.GenericParameters.Length > 0) { baseType = metaData.GenericParameters[0]; } for (int i = 0; i < count; i++) { object deserializedObject = DeserializeElement(baseType); ilist.Add(deserializedObject); } return(ilist); }
// Serializes IList private void SerializeList(object genericObject, Type objectType, ObjectMetaData metaData) { IList ilist = genericObject as IList; if (ilist == null) { throw new AltSerializeException("The object type " + objectType.FullName + " does not implement IList."); } IEnumerator enumerator = ilist.GetEnumerator(); Write((int)ilist.Count); while (enumerator.MoveNext()) { SerializeElement(enumerator.Current, objectType); } }
// Serializes classes private void SerializeComplexType(object obj, Type objectType) { // Write complex object... ObjectMetaData metaData = GetMetaData(objectType); if (metaData.DynamicSerializer != null) { // use compiled serializer metaData.DynamicSerializer.Serialize(obj, this); return; } if (metaData.IsIAltSerializable) { // Call this object as an IAltSerializable and move on ((IAltSerializable)obj).Serialize(this); return; } // Check if the object implements any generic types. if (metaData.ImplementsIList) { SerializeList(obj, objectType, metaData); return; } else if (metaData.ImplementsIDictionary) { SerializeDictionary(obj, objectType); return; } if (metaData.IsISerializable) { // Object implements ISerializabe; use that interface for serialization. SerializationInfo info = new SerializationInfo(objectType, new AltFormatter()); StreamingContext context = new StreamingContext(StreamingContextStates.All); ((ISerializable)obj).GetObjectData(info, context); SerializationInfoEnumerator e = info.GetEnumerator(); Dictionary <string, object> sinfo = new Dictionary <string, object>(); while (e.MoveNext()) { sinfo[e.Name] = e.Value; } Serialize(sinfo, typeof(Dictionary <string, object>)); return; } if (metaData.IsGenericList) { // Optimizations for generic list. FieldInfo itemsField = (FieldInfo)metaData.Extra; object arrayObject = itemsField.GetValue(obj); int count = ((ICollection)obj).Count; SerializeArray(arrayObject, metaData.GenericParameters[0], count); return; } if (SerializePropertyNames) { // Write out the number of properties we're going to serialize Write((short)metaData.Values.Length); } foreach (ReflectedMemberInfo info in metaData.Values) { object objValue = info.GetValue(obj); if (SerializePropertyNames == true) { // Write the name of the property before serializing it Write(info.Name); } if (SerializeProperties == false && info.FieldType.IsSerializable == false) { // When serializing fields, skip the 'nonserializable' ones. continue; } SerializeElement(objValue, info.FieldType); } }
// Deserializes classes. private object DeserializeComplexType(Type objectType, int cacheID) { // Complex object ObjectMetaData metaData = GetMetaData(objectType); if (metaData.DynamicSerializer != null) { // use compiled deserializer object newObject = metaData.DynamicSerializer.Deserialize(this, cacheID); return(newObject); } if (metaData.IsIAltSerializable) { // Read complex object... object ialtobj = Activator.CreateInstance(objectType); if (cacheID > 0) { Cache.SetCachedObjectId(ialtobj, cacheID); } // Call this object as an IAltSerializable and move on ((IAltSerializable)ialtobj).Deserialize(this); return(ialtobj); } if (metaData.ImplementsIList) { // Implements IList, use special definition for this method return(DeserializeList(objectType, cacheID, metaData)); } else if (metaData.ImplementsIDictionary) { // Implements IDictionary; use special definition for this method .. return(DeserializeDictionary(objectType, cacheID)); } if (metaData.IsISerializable) { // Implements ISerializabe; use that interface for serialization/deserialization Dictionary <string, object> sinfo; SerializationInfo info = new SerializationInfo(objectType, new AltFormatter()); StreamingContext context = new StreamingContext(StreamingContextStates.All); sinfo = (Dictionary <string, object>)Deserialize(typeof(Dictionary <string, object>)); foreach (KeyValuePair <string, object> kvp in sinfo) { info.AddValue(kvp.Key, kvp.Value); } ConstructorInfo construct = (ConstructorInfo)metaData.Extra; return(construct.Invoke(new object[] { info, context })); } if (metaData.IsGenericList) { FieldInfo itemsField = (FieldInfo)metaData.Extra; Type arrayType = itemsField.FieldType; object arrayObject = DeserializeArray(arrayType, 0); //object newList = Activator.CreateInstance(objectType, new object[] { ((Array)arrayObject).Length }); object newList = Activator.CreateInstance(objectType, new object[] { arrayObject }); if (cacheID > 0) { Cache.SetCachedObjectId(newList, cacheID); } return(newList); } object obj = Activator.CreateInstance(objectType); // This object might be referenced by other objects // that it loads, so we need to cache it first! if (cacheID > 0) { Cache.SetCachedObjectId(obj, cacheID); } if (SerializePropertyNames) { // Deserialize each stored property int propertyCount = (int)((short)Deserialize(typeof(short))); for (int i = 0; i < propertyCount; i++) { string propertyName = ReadString(); ReflectedMemberInfo info = metaData.FindMemberInfoByName(propertyName); if (info == null) { // Ignore the field not found. //throw new AltSerializeException("Unable to find the property '" + propertyName + "' in object type '" + objectType.FullName + "'."); } else { // Deserialize the object into the property object desobj = DeserializeElement(info.FieldType); info.SetValue(obj, desobj); } } } else { // Reflect on each field, deserializing the data foreach (ReflectedMemberInfo info in metaData.Values) { if (SerializeProperties == false && info.FieldType.IsSerializable == false) { // When deserializing fields, skip the 'nonserializable' ones. continue; } object deserializedObject = DeserializeElement(info.FieldType); info.SetValue(obj, deserializedObject); } } return(obj); }
/// <summary> /// Gets the meta data for an object type. If the Type doesn't exist in /// the meta data hash, it is created. /// </summary> /// <param name="type">The object Type to get metadata for.</param> /// <returns>Returns an ObjectMetaData class representing the <paramref name="type"/> parameter.</returns> internal ObjectMetaData GetMetaData(Type type) { if (type == null) { throw new AltSerializeException("The serializer could not get meta data for the type."); } if (MetaDataHash.ContainsKey(type)) { return(MetaDataHash[type]); } #if false if (type.GetCustomAttributes(typeof(CompiledSerializerAttribute), true).Length != 0) { // Compiled Serializer flag specified. ObjectMetaData cmetadata = new ObjectMetaData(this); cmetadata.ObjectType = type; cmetadata.DynamicSerializer = (DynamicSerializer)DynamicSerializerFactory.GenerateSerializer(type); MetaDataHash[type] = cmetadata; return(cmetadata); } #endif if (type.GetInterface(typeof(IAltSerializable).Name) != null) { // This will only be called using interface methods ObjectMetaData imetaData = new ObjectMetaData(this); imetaData.ObjectType = type; imetaData.IsIAltSerializable = true; MetaDataHash[type] = imetaData; return(imetaData); } List <ReflectedMemberInfo> serializedProperties = new List <ReflectedMemberInfo>(); // Get all public and non-public properties. PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo info in props) { if (info.GetCustomAttributes(typeof(DoNotSerializeAttribute), true).Length > 0) { // Don't add it to the list if a nonserialized attribute is set continue; } if (info.GetIndexParameters().Length > 0) { continue; } if (info.CanRead == false || info.CanWrite == false) { // If its a read or write only property, don't bother with it continue; } //serializedFields.Add(new ReflectedMemberInfo(info)); InsertSortedMetaData(serializedProperties, new ReflectedMemberInfo(info)); } // Get all public and non-public fields. List <ReflectedMemberInfo> serializedFields = new List <ReflectedMemberInfo>(); List <FieldInfo> fields = new List <FieldInfo>(); GetAllFieldsOfType(type, fields); foreach (FieldInfo info in fields) { if (info.IsNotSerialized == true) { continue; } InsertSortedMetaData(serializedFields, new ReflectedMemberInfo(info)); } ObjectMetaData metaData = new ObjectMetaData(this); metaData.ObjectType = type; metaData.Fields = serializedFields.ToArray(); metaData.Properties = serializedProperties.ToArray(); #if false if (type.IsGenericType) { metaData.GenericTypeDefinition = type.GetGenericTypeDefinition(); metaData.GenericParameters = type.GetGenericArguments(); } #endif if (type.GetInterface(typeof(ISerializable).Name) != null) { // Indicate that the ISerializable interface is available. metaData.IsISerializable = true; // Store constructor info for ISerializables. metaData.Extra = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); } // Check for an IList implementation. Type iface = type.GetInterface("System.Collections.IList"); if (iface != null) { metaData.ImplementsIList = true; } // Check for an IDictionary implementation. iface = type.GetInterface("System.Collections.IDictionary"); if (iface != null) { metaData.ImplementsIDictionary = true; } // Check for a generic List<> implementation. if (metaData.GenericTypeDefinition == typeof(List <>)) { metaData.IsGenericList = true; metaData.ImplementsIList = false; metaData.Extra = type.GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic); metaData.SizeField = type.GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic); metaData.SerializeMethod = type.GetMethod("ToArray"); } // Store in hash and return the structure MetaDataHash[type] = metaData; return(metaData); }