示例#1
0
        static Tuple <PropertyInfo, StarSerializeAttribute> GetMember(PropertyInfo pInfo)
        {
            StarSerializeAttribute soa = pInfo.GetCustomAttribute <StarSerializeAttribute>();

            if (soa == null)
            {
                return(null);
            }

            return(Tuple.Create(pInfo, soa));
        }
示例#2
0
        static BlockExpression ReadMaybeType(Expression member, Expression stream, StarSerializeAttribute attrib)
        {
            var maybeType = member.Type.GetGenericArguments().First();

            var hasAny    = Expression.Variable(typeof(byte), "hasAny");
            var valueProp = member.Type.GetProperty("Value");

            var newExpr = Expression.Block(new[] { hasAny },
                                           Expression.Assign(member, Expression.New(member.Type)),
                                           Expression.Assign(hasAny, Expression.Invoke(Expression.Constant(_serializables[typeof(byte)].Deserializer), stream)),
                                           Expression.IfThen(Expression.Equal(hasAny, Expression.Constant((byte)1)),
                                                             ReadOne(stream, Expression.Property(member, valueProp), maybeType, null)
                                                             ),
                                           member
                                           );

            return(newExpr);
        }
示例#3
0
        static BlockExpression GetListReader(Expression stream, MemberExpression member, Expression reader, Type genericType, StarSerializeAttribute serializeAttrib)
        {
            var length   = Expression.Variable(typeof(int), "length");
            var listType = typeof(List <>).MakeGenericType(genericType);
            var list     = Expression.Variable(listType, "list");
            var exit     = Expression.Label();
            var block    = Expression.Block(new[] { length, list },
                                            Expression.Assign(list, Expression.New(listType)),
                                            ReadLengthIfNotGreedy(stream, member, length, serializeAttrib.Length),
                                            Expression.Loop(
                                                Expression.IfThenElse(ShouldReadMore(stream, member, GetListCount(list, genericType), length),
                                                                      Expression.Call(list, "Add", null, reader),
                                                                      Expression.Break(exit)),
                                                exit),
                                            list);

            return(block);
        }
示例#4
0
        static BlockExpression GetListWriter(Expression stream, MemberExpression member, Type genericType, Expression func, StarSerializeAttribute serializeAttrib)
        {
            var counter     = Expression.Variable(typeof(int), "counter");
            var exit        = Expression.Label();
            var listLength  = GetListCount(member, genericType);
            var currentItem = Expression.Property(member, "Item", counter);
            var block       = Expression.Block(new[] { counter },
                                               WriteLengthIfNotGreedy(stream, member, listLength, serializeAttrib != null ? serializeAttrib.Length : 0),
                                               Expression.Loop(
                                                   Expression.IfThenElse(Expression.LessThan(counter, listLength),
                                                                         Expression.Block(
                                                                             Expression.Invoke(func, stream, currentItem),
                                                                             Expression.Assign(counter, Expression.Increment(counter))),
                                                                         Expression.Break(exit)),
                                                   exit));

            return(block);
        }
示例#5
0
        static Expression ReadOne(Expression stream, MemberExpression dest, Type destType, StarSerializeAttribute serializeAttrib, bool toObj = false)
        {
            //If we're dealing with a collection, take the generic parameter type.
            var type = GetCollectionTypeOrSelf(destType);
            //If the type is complex, deserialize recursively, else read primitives.
            var func = IsComplex(type)
                ? PacketDeserializers.ContainsKey(type)
                ? PacketDeserializers[type]
                : BuildDeserializer(type)
                : GetSerializableType(type).Deserializer;

            var reader = Expression.Convert(Expression.Invoke(Expression.Constant(func), stream), type) as Expression;

            if (IsList(destType))
            {
                return(Expression.Assign(dest, GetListReader(stream, dest, reader, type, serializeAttrib)));
            }
            else if (IsDictionary(destType))
            {
                Type[] kvTypes = destType.GetGenericArguments();
                Type   valType = kvTypes[1];

                var valFunc = IsComplex(valType)
                ? PacketDeserializers.ContainsKey(valType)
                ? PacketDeserializers[valType]
                : BuildDeserializer(valType)
                : GetSerializableType(valType).Deserializer;

                var valReader = Expression.Convert(Expression.Invoke(Expression.Constant(valFunc), stream), valType) as Expression;

                return(Expression.Assign(dest, GetDictionaryReader(stream, reader, valReader, type, valType)));
            }

            return(Expression.Assign(dest, toObj ? Expression.Convert(reader, typeof(object)) : reader));
        }
示例#6
0
        static Expression WriteOne(Expression stream, MemberExpression source, Type sourceType, StarSerializeAttribute serializeAttrib)
        {
            try
            {
                var type      = GetCollectionTypeOrSelf(sourceType);
                var isComplex = IsComplex(type);
                var func      = isComplex
                    ? PacketSerializers.ContainsKey(type)
                    ? PacketSerializers[type]
                    : BuildSerializer(type)
                    : GetSerializableType(type).Serializer;

                if (IsList(sourceType))
                {
                    var w = GetListWriter(stream, source, type, Expression.Constant(func), serializeAttrib);

                    return(w);
                }
                else if (IsDictionary(sourceType))
                {
                    Type[] kvTypes = sourceType.GetGenericArguments();
                    Type   valType = kvTypes[1];

                    var valFunc = IsComplex(valType)
                    ? PacketSerializers.ContainsKey(valType)
                    ? PacketSerializers[valType]
                    : BuildSerializer(valType)
                    : GetSerializableType(valType).Serializer;

                    return(GetDictionaryWriter(stream, source, type, valType, func, valFunc));
                }

                var funcType = GetFuncType(func); //We need to downcast the member because of contravariance with enums or Complex type boxing.
                var writer   = Expression.Invoke(Expression.Constant(func), stream, Expression.Convert(source, funcType));

                return(writer);
            }
            catch (Exception ex)
            {
                ex.LogError();
                throw;
            }
        }
示例#7
0
        //TODO: FIX ME
        //static BlockExpression ReadEitherType(MemberExpression member, Expression stream, StarSerializeAttribute attrib)
        //{
        //	Type[] eitherTypes = member.Type.GetGenericArguments();

        //	Type leftType = eitherTypes.First();
        //	Type maybeLeftType = typeof(Maybe<>).MakeGenericType(leftType);

        //	var maybeLeft = Expression.Variable(maybeLeftType, "maybe");
        //	var maybeVal = maybeLeftType.GetProperty("Value");
        //	var eitherLeft = member.Type.GetProperty("Left");
        //	var eitherRight = member.Type.GetProperty("Right");

        //	var newExpr = Expression.Block(new[] { maybeLeft },
        //		ReadMaybeType(Expression.Property(member, eitherLeft), stream, null),
        //			//Expression.IfThen(Expression.Equal(Expression.Property(maybeLeft, maybeVal), Expression.Constant(null)),
        //			ReadMaybeType(Expression.Property(member, eitherRight), stream, null)
        //	//)
        //	);

        //	return newExpr;
        //}

        static BlockExpression ReadAnyType(MemberExpression member, Expression stream, StarSerializeAttribute attrib)
        {
            var index             = Expression.Property(member, "Index");
            var value             = Expression.Property(member, "Value");
            var types             = Expression.Constant(member.Type.GetGenericArguments());
            var deserializeMethod = typeof(PacketSerializer).GetMethod("Deserialize", new[] { typeof(StarReader), typeof(Type) });
            var indexAsInt        = Expression.Decrement(Expression.Convert(index, typeof(int)));
            var actualType        = Expression.ArrayIndex(types, indexAsInt);
            var body = Expression.Block(
                Expression.Assign(member, Expression.New(member.Type)),
                ReadOne(stream, index, typeof(byte), attrib),
                Expression.IfThen(Expression.Not(Expression.Or(
                                                     Expression.LessThan(indexAsInt, Expression.Constant(0)),
                                                     Expression.GreaterThanOrEqual(indexAsInt, Expression.ArrayLength(types))
                                                     )),
                                  Expression.Assign(value, Expression.Call(deserializeMethod, stream, actualType))));

            return(body);
        }