Example #1
0
        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;
            }

            var collectionToken = new CollectionMetaToken(o.GetType());
            if(collectionToken.IsCollection)
            {
                // 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;
        }
Example #2
0
        private void WriteDictionary(CollectionMetaToken collectionToken, int count, object dictionary)
        {
            writer.Write(count);
            if(collectionToken.IsGeneric)
            {
                var enumeratorMethod = typeof(IEnumerable<>).MakeGenericType(typeof(KeyValuePair<,>).MakeGenericType(collectionToken.FormalKeyType, collectionToken.FormalValueType)).GetMethod("GetEnumerator");
                var enumerator = enumeratorMethod.Invoke(dictionary, null);
                var enumeratorType = enumeratorMethod.ReturnType;

                var moveNext = Helpers.GetMethodInfo<IEnumerator>(x => x.MoveNext());
                var currentField = enumeratorType.GetProperty("Current");
                var current = currentField.GetGetMethod();
                var currentType = current.ReturnType;
                var key = currentType.GetProperty("Key").GetGetMethod();
                var value = currentType.GetProperty("Value").GetGetMethod();
                while((bool)moveNext.Invoke(enumerator, null))
                {
                    var currentValue = current.Invoke(enumerator, null);
                    var keyValue = key.Invoke(currentValue, null);
                    var valueValue = value.Invoke(currentValue, null);
                    WriteField(collectionToken.FormalKeyType, keyValue);
                    WriteField(collectionToken.FormalValueType, valueValue);
                }
            }
            else
            {
                var castDictionary = (IDictionary)dictionary;
                foreach(DictionaryEntry element in castDictionary)
                {
                    WriteField(typeof(object), element.Key);
                    WriteField(typeof(object), element.Value);
                }
            }
        }