Пример #1
0
        /// <summary>
        /// Deserializes the next part in the BinaryReader and returns a KeyValuePair containing the property name as key van the deserialized object as value.
        /// </summary>
        /// <param name="br">The binary reader</param>
        /// <param name="cache">The cycle cache</param>
        /// <returns>A KeyValuePair containing the property name and the property value.</returns>
        private KeyValuePair <string, object> _Deserialize(BinaryReader br, CycleCache cache)
        {
            var propertyName = br.ReadString().Replace(PROPERTY_VALUE_SEPARATOR, string.Empty);

            if (propertyName == END_OF_INSTANCE)
            {
                return(new KeyValuePair <string, object>(END_OF_INSTANCE, END_OF_INSTANCE));
            }

            var typeName = _typeIndexer(br.ReadInt32());

            if (_DeserializeNull(br))
            {
                return(new KeyValuePair <string, object>(propertyName, null));
            }

            Type typeResolved = null;

            if (!_typeRef.TryGetValue(typeName, out typeResolved))
            {
                typeResolved = Type.GetType(typeName);

                lock (((ICollection)_typeRef).SyncRoot)
                {
                    if (!_typeRef.ContainsKey(typeName))
                    {
                        _typeRef.Add(typeName, typeResolved);
                    }
                }
            }

            if (_database.IsRegistered(typeResolved))
            {
                var keyType = _database.GetKeyType(typeResolved);
                var key     = _serializer.Deserialize(keyType, br);

                var cached = cache.CheckKey(keyType, key);
                if (cached != null)
                {
                    return(new KeyValuePair <string, object>(propertyName, cached));
                }

                cached = _database.Load(typeResolved, key, cache);
                cache.Add(typeResolved, cached, key);
                return(new KeyValuePair <string, object>(propertyName, cached));
            }

            if (_serializer.CanSerialize(typeResolved))
            {
                return(new KeyValuePair <string, object>(propertyName, _serializer.Deserialize(typeResolved, br)));
            }


            if (typeof(Array).IsAssignableFrom(typeResolved))
            {
                var count            = br.ReadInt32();
                var listWithoutNulls = new List <object>();
                for (var x = 0; x < count; x++)
                {
                    var item = _Deserialize(br, cache).Value;
                    if (item != null)
                    {
                        listWithoutNulls.Add(item);
                    }
                }

                var array = Array.CreateInstance(typeResolved.GetElementType(), listWithoutNulls.Count);
                for (var x = 0; x < listWithoutNulls.Count; x++)
                {
                    var item = listWithoutNulls[x];
                    array.SetValue(item, x);
                }

                return(new KeyValuePair <string, object>(propertyName, array));
            }

            if (typeof(IList).IsAssignableFrom(typeResolved))
            {
                var list = Activator.CreateInstance(typeResolved) as IList;
                return(new KeyValuePair <string, object>(propertyName, _LoadList(br, cache, list)));
            }

            if (typeof(IDictionary).IsAssignableFrom(typeResolved))
            {
                var dictionary = Activator.CreateInstance(typeResolved) as IDictionary;
                return(new KeyValuePair <string, object>(propertyName, _LoadDictionary(br, cache, dictionary)));
            }

            var instance = Activator.CreateInstance(typeResolved);

            // build the reflection cache);
            if (!_propertyCache.ContainsKey(typeResolved))
            {
                //_CacheProperties(type);
                _CacheProperties(typeResolved);
            }

            // now iterate until the end of the file was reached
            _IteratePropertiesUntilEndOfFileIsReached(br, cache, typeResolved, instance);
            return(new KeyValuePair <string, object>(propertyName, instance));
        }