public static Delegate GetReadMethodInfo <T>()
        {
            Type[] args    = null;
            var    typeOfT = typeof(T);

            if (typeOfT.IsDictionary() && (args = typeOfT.GetGenericArguments()) != null && args.Length == 2)
            {
                var metadataToken = unchecked (((ulong)(uint)args[0].MetadataToken << 32) | (ulong)(uint)args[1].MetadataToken);
                if (_readCache.TryGetValue(metadataToken, out var dstMethod))
                {
                    return(dstMethod);
                }
                else
                {
                    var method = TypeSearcher.GetMethodsFromType(typeof(TBinaryExtendor), new Type[] { typeof(BinaryReader) }).FirstOrDefault();
                    dstMethod = method?.MakeGenericMethod(args).CreateDelegate(typeof(Func <BinaryReader, T>));

                    if (dstMethod != null)
                    {
                        _readCache[metadataToken] = dstMethod;
                        return(dstMethod);
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Static initializer;
        /// Basically searches for a method in the BinaryWriter/Reader class to automatically handle the given types
        /// </summary>
        static TBinaryAccessor()
        {
            var typeOfT = typeof(T);

            if (typeOfT == typeof(string))
            {
                //Looks a bit ugly, but ¯\_(ツ)_/¯
                //For reading:
                //	1.Read the len of the next string
                //	2.Read the amount of len of bytes and decode it to a string
                //For writing:
                //	1: Convert the given string to a byte[]
                //	2: Write the len of bytes in the array onto the stream
                //	3: Write the bytes onto the stream
                RegisterExtension(new Func <BinaryReader, string>(x => BaseEncoding.GetString(x.ReadBytes(x.ReadInt32()))) as Func <BinaryReader, T>, new Action <BinaryWriter, string>((m, x) =>
                {
                    var dstBytes = BaseEncoding.GetBytes(x);
                    m.Write(dstBytes.Length);
                    m.Write(dstBytes);
                }) as Action <BinaryWriter, T>
                                  );
            }
            else if (typeOfT.IsPrimitive)
            {
                //Search for a method to read the given type
                var readMethodInfo = TypeSearcher.GetMethodsFromType(typeof(BinaryReader), new Type[0], typeOfT).FirstOrDefault(m => m.Name.StartsWith("Read") && m.Name != "Read");
                if (readMethodInfo != null)
                {
                    //Create a delegate, so that we don't have to use Methodinfo.Invoke which slows down the whole process
                    _storReadFunc = (Func <BinaryReader, T>)readMethodInfo.CreateDelegate(typeof(Func <BinaryReader, T>));
                }

                //Search for a method to write the given type onto a stream
                var writeMethodInfo = TypeSearcher.GetMethodsFromType(typeof(BinaryWriter), new Type[] { typeOfT }).FirstOrDefault();
                if (writeMethodInfo != null)
                {
                    _storWriteAct = (Action <BinaryWriter, T>)writeMethodInfo.CreateDelegate(typeof(Action <BinaryWriter, T>));
                }
            }
            else
            {
                _storWriteAct = (bw, data) =>
                {
                    var serializer = (Func <T, byte[]>)MatroschkaResolve.GetWriteMethodInfo(data);
                    if (serializer != null)
                    {
                        bw.Write(serializer(data));
                    }
                };

                _storReadFunc = br =>
                {
                    var eval = (Func <BinaryReader, T>)MatroschkaResolve.GetReadMethodInfo <T>();
                    return(eval == null ? default(T) : eval(br));
                };
            }
        }