private void UpdateElements(Type type, int objectId) { var obj = deserializedObjects[objectId]; var speciallyDeserializable = obj as ISpeciallySerializable; if (speciallyDeserializable != null) { LoadAndVerifySpeciallySerializableAndVerify(speciallyDeserializable, reader); return; } CollectionMetaToken token; if (!CollectionMetaToken.TryGetCollectionMetaToken(type, out token)) { throw new InvalidOperationException(InternalErrorMessage); } if (token.IsDictionary) { FillDictionary(token, obj); return; } // so we can assume it is ICollection<T> or ICollection FillCollection(token.FormalElementType, obj); }
private bool WriteSpecialObject(object o, bool checkForCollections) { // if the object here is value type, it is in fact boxed // value type - the reference layout is fine, we should // write it using WriteField var type = o.GetType(); if (type.IsValueType) { WriteField(type, o); return(true); } var mDelegate = o as MulticastDelegate; if (mDelegate != null) { // if the target is trasient, we omit associated delegate entry var invocationList = GetDelegatesWithNonTransientTargets(mDelegate); writer.Write(invocationList.Length); foreach (var del in invocationList) { WriteField(typeof(object), del.Target); Methods.TouchAndWriteId(new MethodDescriptor(del.Method)); } return(true); } if (type.IsArray) { var elementType = type.GetElementType(); var array = o as Array; WriteArray(elementType, array); return(true); } if (checkForCollections) { CollectionMetaToken collectionToken; if (CollectionMetaToken.TryGetCollectionMetaToken(o.GetType(), out collectionToken)) { // here we can have normal or extension method that needs to be treated differently int count = collectionToken.CountMethod.IsStatic ? (int)collectionToken.CountMethod.Invoke(null, new[] { o }) : (int)collectionToken.CountMethod.Invoke(o, null); WriteEnumerable(collectionToken.FormalElementType, count, (IEnumerable)o); return(true); } } return(false); }
private bool WriteSpecialObject(object o) { // if the object here is value type, it is in fact boxed // value type - the reference layout is fine, we should // write it using WriteField var type = o.GetType(); if (type.IsValueType) { WriteField(type, o); return(true); } var speciallySerializable = o as ISpeciallySerializable; if (speciallySerializable != null) { var startingPosition = writer.Position; speciallySerializable.Save(writer); writer.Write(writer.Position - startingPosition); return(true); } if (type.IsArray) { var elementType = type.GetElementType(); var array = o as Array; var rank = array.Rank; writer.Write(rank); WriteArray(elementType, array); return(true); } var mDelegate = o as MulticastDelegate; if (mDelegate != null) { // if the target is trasient, we omit associated delegate entry var invocationList = GetDelegatesWithNonTransientTargets(mDelegate); writer.Write(invocationList.Length); foreach (var del in invocationList) { WriteField(typeof(object), del.Target); TouchAndWriteMethodId(del.Method); } return(true); } var str = o as string; if (str != null) { writer.Write(str); return(true); } if (!treatCollectionAsUserObject) { CollectionMetaToken collectionToken; if (CollectionMetaToken.TryGetCollectionMetaToken(o.GetType(), out collectionToken)) { // here we can have normal or extension method that needs to be treated differently int count = collectionToken.CountMethod.IsStatic ? (int)collectionToken.CountMethod.Invoke(null, new[] { o }) : (int)collectionToken.CountMethod.Invoke(o, null); if (collectionToken.IsDictionary) { WriteDictionary(collectionToken, count, o); } else { WriteEnumerable(collectionToken.FormalElementType, count, (IEnumerable)o); } return(true); } } return(false); }