Exemple #1
0
        public DataToStringTransformer(DataType dataType, IFormatProvider[] providers, char[] delimiters)
        {
            bool supported = dataType.IsPrimitive || (dataType.IsSlotes && dataType.AreAllTypesPrimitive);

            if (!supported)
            {
                throw new NotSupportedException(dataType.ToString());
            }

            if (dataType.IsPrimitive && providers.Length != 1)
            {
                throw new ArgumentException("providers");
            }
            if (dataType.IsSlotes && providers.Length != dataType.TypesCount)
            {
                throw new ArgumentException("providers");
            }

            DataType   = dataType;
            Providers  = providers;
            Delimiters = delimiters;

            Type = DataTypeUtils.GetDataType(dataType);

            //prepare toIData
            LambdaToIData = CreateToIDataMethod();
            toIData       = LambdaToIData.Compile();

            //prepare fromIData
            LambdaFromIData = CreateFromIDataMethod();
            fromIData       = LambdaFromIData.Compile();
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="membersOrder">Defines the declaration order of each property and field (because it is not guaranteed by the typeof(T).GetMembers() method)</param>
        public DataTransformer(Func <Type, MemberInfo, int> membersOrder)
        {
            if (!DataType.IsPrimitiveType(typeof(T)) && typeof(T).IsClass && typeof(T).GetConstructor(new Type[] { }) == null)
            {
                throw new NotSupportedException(String.Format("Type '{0}' does not have a default constructor", typeof(T)));
            }

            MembersOrder = membersOrder;

            List <Type> list = new List <Type>();

            BuildSlotTypes(list, typeof(T), new HashSet <Type>());
            slotTypes = list.ToArray();

            if (slotTypes.Length == 0)
            {
                throw new ArgumentException(String.Format("No public read/write properties/fields available for mapping."));
            }

            Type     = DataTypeUtils.GetDataType(slotTypes);
            DataType = DataTypeUtils.FromPrimitiveTypes(slotTypes);

            LambdaToIData = CreateToIDataMethod();
            toIData       = LambdaToIData.Compile();

            LambdaFromIData = CreateFromIDataMethod();
            fromIData       = LambdaFromIData.Compile();
        }
        private Expression <Func <IData, int> > CreateGetHashCodeMethod()
        {
            var obj = Expression.Parameter(typeof(IData), "obj");

            var idataType = DataTypeUtils.GetDataType(DataType);

            var x       = Expression.Variable(idataType, "x");
            var assign1 = Expression.Assign(x, Expression.Convert(obj, idataType));

            Expression[] values = new Expression[DataType.IsPrimitive ? 1 : DataType.TypesCount];

            if (DataType.IsPrimitive)
            {
                values[0] = GetHashCodeCommand(x, DataType, 0);
            }
            else
            {
                for (int i = 0; i < DataType.TypesCount; i++)
                {
                    values[i] = GetHashCodeCommand(x, DataType[i], i);
                }
            }

            var result = Expression.Variable(typeof(int), "result");

            var xor = values[0];

            if (DataType.IsSlotes)
            {
                for (int i = 1; i < DataType.TypesCount; i++)
                {
                    xor = Expression.ExclusiveOr(xor, values[i]);
                }
            }

            var assign2 = Expression.Assign(result, xor);

            List <Expression> list = new List <Expression>();

            var exitPoint = Expression.Label(typeof(int));

            list.Add(assign1);
            list.Add(assign2);
            list.Add(Expression.Label(exitPoint, result));

            var body = Expression.Block(typeof(int), new ParameterExpression[] { x, result }, list);

            var lambda = Expression.Lambda <Func <IData, int> >(body, obj);

            //public int GetHashCode(IData obj)
            //{
            //    var x = (Data<byte[], string, double>)obj;
            //    return BigEndianByteArrayEqualityComparer.Instance.GetHashCode(x.Slot0) ^ x.Slot1.GetHashCode() ^ x.Slot2.GetHashCode();
            //}

            return(lambda);
        }
Exemple #4
0
        public Expression <Action <BinaryReader, Action <int, IData>, int> > CreateLoadMethodSingleSlot()
        {
            var reader = Expression.Parameter(typeof(BinaryReader), "reader");
            var values = Expression.Parameter(typeof(Action <int, IData>), "values");
            var count  = Expression.Parameter(typeof(int), "count");

            List <Expression> list = new List <Expression>();

            //byte[] buffer = reader.ReadBytes((int)CountCompression.Deserialize(reader));

            var buffer          = Expression.Variable(typeof(byte[]), "buffer");
            var ReadBytes       = typeof(BinaryReader).GetMethod("ReadBytes");
            var counter         = Expression.Convert(Expression.Call(typeof(CountCompression).GetMethod("Deserialize"), reader), typeof(int));
            var ReadBytesCaller = Expression.Call(reader, ReadBytes, counter);

            list.Add(Expression.Assign(buffer, ReadBytesCaller));

            var ms    = Expression.Variable(typeof(MemoryStream), "ms");
            var newMs = Expression.New(typeof(MemoryStream).GetConstructor(new Type[] { typeof(byte[]) }), buffer);

            //((IIndexerPersist<string>)persist[0]).Load(new BinaryReader(ms), (idx, value) => { values(idx, new Data<string>(value)); }, count);

            var castPersist = Expression.Convert(Expression.Constant(Persists[0]), Persists[0].GetType());
            var loadMethod  = Persists[0].GetType().GetMethod("Load");

            var binaryReader = Expression.New(typeof(BinaryReader).GetConstructor(new Type[] { typeof(MemoryStream) }), ms);

            var idx          = Expression.Variable(typeof(int), "idx");
            var value        = Expression.Variable(DataType.PrimitiveType, "value");
            var newData      = Expression.New(DataTypeUtils.GetDataType(DataType).GetConstructor(new Type[] { DataType.PrimitiveType }), value);
            var internalCall = Expression.Call(values, values.Type.GetMethod("Invoke"), idx, newData);

            var func     = Expression.Lambda(internalCall, idx, value);
            var loadCall = Expression.Call(castPersist, loadMethod, binaryReader, func, count);

            //byte[] buffer = reader.ReadBytes((int)CountCompression.Deserialize(reader));

            //using (MemoryStream ms = new MemoryStream(buffer))
            //((IIndexerPersist<string>)persist[0]).Load(new BinaryReader(ms), (idx, value) => { values(idx, new Data<string>(value)); }, count);

            var usingBody = ms.Using(newMs, loadCall);

            list.Add(usingBody);

            var lambda = Expression.Lambda <Action <BinaryReader, Action <int, IData>, int> >(Expression.Block(new ParameterExpression[] { buffer }, list), new ParameterExpression[] { reader, values, count });

            return(lambda);
        }
Exemple #5
0
        private Expression <Func <IData, IData, int> > CreateCompareMethod()
        {
            var x = Expression.Parameter(typeof(IData), "x");
            var y = Expression.Parameter(typeof(IData), "y");

            var idataType = DataTypeUtils.GetDataType(DataType);

            var data1 = Expression.Variable(idataType, "data1");
            var data2 = Expression.Variable(idataType, "data2");
            var cmp   = Expression.Variable(typeof(int), "cmp");

            List <Expression> list = new List <Expression>();

            list.Add(Expression.Assign(data1, Expression.Convert(x, idataType)));
            list.Add(Expression.Assign(data2, Expression.Convert(y, idataType)));

            var exitPoint = Expression.Label(typeof(int));

            if (DataType.IsPrimitive)
            {
                foreach (var command in GetCompareCommands(data1, data2, cmp, exitPoint, DataType, 0, CompareOptions[0], true))
                {
                    list.Add(command);
                }
            }
            else
            {
                for (int i = 0; i < DataType.TypesCount; i++)
                {
                    foreach (var command in GetCompareCommands(data1, data2, cmp, exitPoint, DataType[i], i, CompareOptions[i], i == DataType.TypesCount - 1))
                    {
                        list.Add(command);
                    }
                }
            }

            list.Add(Expression.Label(exitPoint, Expression.Constant(0)));

            var body   = Expression.Block(typeof(int), (new ParameterExpression[] { data1, data2, cmp }), list);
            var lambda = Expression.Lambda <Func <IData, IData, int> >(body, x, y);

            return(lambda);
        }
Exemple #6
0
        public DataPersist(DataType dataType)
        {
            bool supported = dataType.IsPrimitive || (dataType.IsSlotes && dataType.AreAllTypesPrimitive);

            if (!supported)
            {
                throw new NotSupportedException(dataType.ToString());
            }

            DataType = dataType;
            Type     = DataTypeUtils.GetDataType(dataType);

            //prepare Write
            LambdaWrite = CreateWriteMethod();
            write       = LambdaWrite.Compile();

            //prepare Read
            LambdaRead = CreateReadMethod();
            read       = LambdaRead.Compile();
        }
Exemple #7
0
        public DataToObjectsTransformer(DataType dataType)
        {
            bool supported = dataType.IsPrimitive || (dataType.IsSlotes && dataType.AreAllTypesPrimitive);

            if (!supported)
            {
                throw new NotSupportedException(dataType.ToString());
            }

            DataType = dataType;
            Type     = DataTypeUtils.GetDataType(DataType);

            //prepare toIData
            LambdaToIData = CreateToIDataMethod();
            toIData       = LambdaToIData.Compile();

            //prepare fromIData
            LambdaFromIData = CreateFromIDataMethod();
            fromIData       = LambdaFromIData.Compile();
        }
Exemple #8
0
        private Expression GetStorePersistCall(IIndexerPersist persist, int slotIndex, Expression msAccess, ParameterExpression values, ParameterExpression count)
        {
            var castPersist = Expression.Convert(Expression.Constant(Persists[slotIndex]), Persists[slotIndex].GetType());

            var binaryWriter = Expression.New(typeof(BinaryWriter).GetConstructor(new Type[] { typeof(MemoryStream) }), msAccess);

            var idx      = Expression.Variable(typeof(int), "idx");
            var callFunc = Expression.Call(values, values.Type.GetMethod("Invoke"), idx);

            var cast  = Expression.Convert(callFunc, DataTypeUtils.GetDataType(DataType));
            var field = Expression.Field(cast, String.Format("Slot{0}", slotIndex));

            var storeMethod = persist.GetType().GetMethod("Store");

            var func      = Expression.Lambda(field, idx);
            var storeCall = Expression.Call(castPersist, storeMethod, new Expression[] { binaryWriter, func, count });

            //((IIndexerPersist<Int32>)persist[0]).Store(new BinaryWriter(streams[0]), (idx) => { return ((Data<int, string, double>)values(idx)).Slot0; }, count);

            return(storeCall);
        }
Exemple #9
0
        private Expression <Action <BinaryWriter, Func <int, IData>, int> > CreateStoreMethod()
        {
            List <Expression> list = new List <Expression>();

            var writer = Expression.Parameter(typeof(BinaryWriter), "writer");
            var values = Expression.Parameter(typeof(Func <int, IData>), "values");
            var count  = Expression.Parameter(typeof(int), "count");

            var idataType = DataTypeUtils.GetDataType(DataType);

            //Action[] actions = new Action[DataType.TypesCount];

            var actions       = Expression.Variable(typeof(Action[]), "actions");
            var newActions    = Expression.NewArrayBounds(typeof(Action), Expression.Constant(DataType.TypesCount, typeof(int)));
            var assignActions = Expression.Assign(actions, newActions);

            list.Add(assignActions);

            //MemoryStream[] streams = new MemoryStream[DataType.TypesCount];

            var streams       = Expression.Variable(typeof(MemoryStream[]), "streams");
            var newStreams    = Expression.NewArrayBounds(typeof(MemoryStream), Expression.Constant(DataType.TypesCount, typeof(int)));
            var assignStreams = Expression.Assign(streams, newStreams);

            list.Add(assignStreams);

            ////Int
            //actions[0] = () =>
            //{
            //    ms[0] = new MemoryStream();
            //    ((IIndexerPersist<Int32>)persist[0]).Store(new BinaryWriter(streams[0]), (idx) => { return ((Data<int, string, double>)values(idx)).Slot0; }, count);
            //};

            for (int j = 0; j < DataType.TypesCount; j++)
            {
                //actions[0] = ()=> { task body }

                var slotType      = idataType.GetField("Slot" + j).FieldType;
                var storeTaskBody = GetStoreActionBody(Persists[j], j, values, count, streams);
                var taskAssign    = Expression.Assign(Expression.ArrayAccess(actions, Expression.Constant(j)), storeTaskBody);

                list.Add(taskAssign);
            }

            //Parallel.Invoke(actions);

            var InvokeMethod = typeof(Parallel).GetMethod("Invoke", new Type[] { typeof(Action[]) });

            list.Add(Expression.Call(InvokeMethod, actions));

            //for (int i = 0; i < DataType.TypesCount; i++)
            //{
            //    var stream = streams[i];
            //    using (stream)
            //    {
            //        CountCompression.Serialize(writer, checked((ulong)stream.Length));
            //        writer.Write(stream.GetBuffer(), 0, (int)stream.Length);
            //    }
            //}

            var i              = Expression.Variable(typeof(int), "i");
            var msIndex        = Expression.ArrayAccess(streams, i);
            var stream         = Expression.Variable(typeof(MemoryStream), "stream");
            var assignStream   = Expression.Assign(stream, msIndex);
            var streamLength   = Expression.Property(stream, "Length");
            var writeByteArray = typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(byte[]), typeof(int), typeof(int) });

            LabelTarget returnPoint = Expression.Label("RETURN_POINT");

            var GetSerialize = Expression.Call(typeof(CountCompression).GetMethod("Serialize"), writer, Expression.ConvertChecked(streamLength, typeof(ulong)));
            var GetBuffer    = Expression.Call(stream, typeof(MemoryStream).GetMethod("GetBuffer"));
            var GetWrite     = Expression.Call(writer, writeByteArray, GetBuffer, Expression.Constant(0), Expression.Convert(streamLength, typeof(int)));

            var usingBody = Expression.Block(assignStream,
                                             GetSerialize,  //CountCompression.Serialize(writer, checked((ulong)stream.Length));
                                             GetWrite       // writer.Write(stream.GetBuffer(), 0, (int)stream.Length);
                                             );

            var streamUsing = stream.Using(usingBody);

            var counterAssign = Expression.Assign(i, Expression.Constant(0));

            list.Add(counterAssign);

            var loopBody = Expression.Block( //assignStream,       //var stream = ms[i];
                streamUsing,                 //using (stream) {...}
                Expression.AddAssign(i, Expression.Constant(1)));

            var loop = Expression.Loop(Expression.IfThenElse(Expression.LessThan(i, Expression.Constant(DataType.TypesCount, typeof(int))),
                                                             loopBody,
                                                             Expression.Break(returnPoint)), returnPoint);

            list.Add(loop);

            var lambdaBody = Expression.Block(new ParameterExpression[] { actions, i, streams }, list);
            var lambda     = Expression.Lambda <Action <BinaryWriter, Func <int, IData>, int> >(lambdaBody, new ParameterExpression[] { writer, values, count });

            return(lambda);
        }
Exemple #10
0
        private Expression <Action <BinaryReader, Action <int, IData>, int> > CreateLoadMethod()
        {
            List <Expression> list = new List <Expression>();

            var reader = Expression.Parameter(typeof(BinaryReader), "reader");
            var values = Expression.Parameter(typeof(Action <int, IData>), "values");
            var count  = Expression.Parameter(typeof(int), "count");

            var idataType = DataTypeUtils.GetDataType(DataType);

            //Data<int, string, double>[] array = new Data<int, string, double>[count];

            var array       = Expression.Variable(idataType.MakeArrayType(), "array");
            var newArray    = Expression.NewArrayBounds(idataType, count);
            var assignArray = Expression.Assign(array, newArray);

            list.Add(assignArray);

            //for (int i = 0; i < count; i++)
            //{
            //    var data = new Data<int, string, double>();
            //    array[i] = data;
            //    values(i, data);
            //}

            var i             = Expression.Variable(typeof(int), "i");
            var counterAssign = Expression.Assign(i, Expression.Constant(0));

            list.Add(counterAssign);

            var data       = Expression.Variable(idataType, "data");
            var callAction = Expression.Call(values, values.Type.GetMethod("Invoke"), i, data);

            LabelTarget returnPoint = Expression.Label("RETURN_POINT");

            var loopBody = Expression.Block(new ParameterExpression[] { data },
                                            Expression.Assign(data, Expression.New(idataType)),
                                            Expression.Assign(Expression.ArrayAccess(array, i), data),
                                            callAction,
                                            Expression.AddAssign(i, Expression.Constant(1))
                                            );

            var loop = Expression.Loop(Expression.IfThenElse(Expression.LessThan(i, count),
                                                             loopBody,
                                                             Expression.Break(returnPoint)), returnPoint);

            list.Add(loop);

            //Action[] actions = new Action[DataType.TypesCount];

            var actions       = Expression.Variable(typeof(Action[]), "actions");
            var newActions    = Expression.NewArrayBounds(typeof(Action), Expression.Constant(DataType.TypesCount));
            var assignActions = Expression.Assign(actions, newActions);

            list.Add(assignActions);

            //byte[][] buffers = new byte[DataType.TypesCount][];

            var buffers       = Expression.Variable(typeof(byte[][]), "buffers");
            var newBuffers    = Expression.NewArrayBounds(typeof(byte[]), Expression.Constant(DataType.TypesCount));
            var assignBuffers = Expression.Assign(buffers, newBuffers);

            list.Add(assignBuffers);

            //for (int j = 0; j < DataType.TypesCount; j++)
            //    buffers[j] = reader.ReadBytes((int)CountCompression.Deserialize(reader));

            var counterAssign2 = Expression.Assign(i, Expression.Constant(0));

            list.Add(counterAssign2);

            var ReadBytes   = typeof(BinaryReader).GetMethod("ReadBytes", new Type[] { typeof(int) });
            var Deserialize = typeof(CountCompression).GetMethod("Deserialize");

            var callDeserialize = Expression.Convert(Expression.Call(Deserialize, reader), typeof(int));
            var callReadBytes   = Expression.Call(reader, ReadBytes, callDeserialize);

            var loopBody2 = Expression.Block(
                Expression.Assign(Expression.ArrayAccess(buffers, i), callReadBytes),
                Expression.AddAssign(i, Expression.Constant(1)));

            var loop2 = Expression.Loop(Expression.IfThenElse(Expression.LessThan(i, Expression.Constant(DataType.TypesCount, typeof(int))),
                                                              loopBody2,
                                                              Expression.Break(returnPoint)), returnPoint);

            list.Add(loop2);

            //Int32
            //actions[0] = () =>
            //{
            //    using (MemoryStream ms = new MemoryStream(buffers[0]))
            //        new Int32IndexerPersist().Load(new BinaryReader(ms), (idx, value) => { array[idx].Slot0 = value; }, count);
            //};

            for (int k = 0; k < DataType.TypesCount; k++)
            {
                var slotType = idataType.GetField("Slot" + k).FieldType;
                var loadBody = GetLoadActionBody(slotType, k, array, buffers, values, count);
                var action   = Expression.Assign(Expression.ArrayAccess(actions, Expression.Constant(k)), loadBody);

                list.Add(action);
            }

            //Parallel.Invoke(actions);

            var Invoke = typeof(Parallel).GetMethod("Invoke", new Type[] { typeof(Action[]) });

            list.Add(Expression.Call(Invoke, actions));

            var lambdaBody = Expression.Block(new ParameterExpression[] { array, actions, buffers, i }, list);
            var lambda     = Expression.Lambda <Action <BinaryReader, Action <int, IData>, int> >(lambdaBody, new ParameterExpression[] { reader, values, count });

            return(lambda);
        }
Exemple #11
0
        private Expression <Action <BinaryWriter, Func <int, IData>, int> > CreateStoreMethodSingleSlot()
        {
            var writer = Expression.Parameter(typeof(BinaryWriter), "writer");
            var values = Expression.Parameter(typeof(Func <int, IData>), "values");
            var count  = Expression.Parameter(typeof(int), "count");

            var idataType = DataTypeUtils.GetDataType(DataType);

            List <Expression> list = new List <Expression>();

            //MemoryStream ms = new MemoryStream()

            var ms       = Expression.Variable(typeof(MemoryStream), "ms");
            var newMs    = Expression.New(typeof(MemoryStream).GetConstructor(new Type[] { }));
            var msLength = Expression.Property(ms, "Length");

            //((IIndexerPersist<Int32>)persist[0]).Store(new BinaryWriter(streams[0]), (idx) => { return ((Data<int, string, double>)values(idx)).Slot0; }, count);

            var castPersist = Expression.Convert(Expression.Constant(Persists[0]), Persists[0].GetType());
            var storeMethod = Persists[0].GetType().GetMethod("Store");

            var binaryWriter = Expression.New(typeof(BinaryWriter).GetConstructor(new Type[] { typeof(MemoryStream) }), ms);

            var idx          = Expression.Variable(typeof(int), "idx");
            var internalCall = Expression.Call(values, values.Type.GetMethod("Invoke"), idx);
            var cast         = Expression.Convert(internalCall, idataType);
            var field        = Expression.Field(cast, String.Format("Slot{0}", 0));
            var func         = Expression.Lambda(field, idx);

            var storeCall = Expression.Call(castPersist, storeMethod, new Expression[] { binaryWriter, func, count });

            list.Add(storeCall);

            //CountCompression.Serialize(writer, checked((ulong)ms.Length));

            var callCompression = Expression.Call(typeof(CountCompression), "Serialize", null, new Expression[] { writer, Expression.ConvertChecked(msLength, typeof(ulong)) });

            list.Add(callCompression);

            //writer.Write(ms.GetBuffer(), 0, (int)ms.Length);

            var writeByteArray = typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(byte[]), typeof(int), typeof(int) });

            var GetBufferCaller = Expression.Call(ms, typeof(MemoryStream).GetMethod("GetBuffer"));
            var GetWriteCaller  = Expression.Call(writer, writeByteArray, GetBufferCaller, Expression.Constant(0), Expression.Convert(msLength, typeof(int)));

            list.AddRange(new Expression[] { GetWriteCaller });

            //using (MemoryStream ms = new MemoryStream())
            //{
            //    ((IIndexerPersist<String>)persist[0]).Store(new BinaryWriter(ms), (idx) => { return ((Data<string>)values(idx)).Slot0; }, count);
            //    CountCompression.Serialize(writer, checked((ulong)ms.Length));
            //    writer.Write(ms.GetBuffer(), 0, (int)ms.Length);
            //}

            var usingBody  = Expression.Block(list);
            var methodbody = ms.Using(newMs, usingBody);

            var parameters = new ParameterExpression[] { writer, values, count };

            var lambda = Expression.Lambda <Action <BinaryWriter, Func <int, IData>, int> >(methodbody, parameters);

            return(lambda);
        }