Пример #1
0
        public static void BuildHashCodesTable(Type type, out int[] values, out ulong[] hashCodes)
        {
            var fields       = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            var enumValues   = fields.Select(field => ConvertToInt(Enum.Parse(type, field.Name), type.GetEnumUnderlyingType())).ToArray();
            var uniqueValues = new HashSet <int>(enumValues).ToArray();
            var nameHashes   = GroBufHelpers.CalcHashesAndCheck(fields.Select(DataMember.Create));
            var hashSet      = new HashSet <uint>();

            for (var x = (uint)enumValues.Length;; ++x)
            {
                hashSet.Clear();
                var ok = true;
                foreach (var value in uniqueValues)
                {
                    var item = ((uint)value) % x;
                    if (hashSet.Contains(item))
                    {
                        ok = false;
                        break;
                    }
                    hashSet.Add(item);
                }
                if (!ok)
                {
                    continue;
                }
                hashCodes = new ulong[x];
                values    = new int[x];
                for (var i = 0; i < x; ++i)
                {
                    values[i] = -1;
                }
                for (var i = 0; i < enumValues.Length; i++)
                {
                    var value = enumValues[i];
                    var index = ((uint)value) % x;
                    hashCodes[index] = nameHashes[i];
                    values[index]    = value;
                }
                break;
            }
        }
Пример #2
0
        public IGroBufCustomSerializer Get(Type declaredType, Func <Type, IGroBufCustomSerializer> factory, IGroBufCustomSerializer baseSerializer)
        {
            var attribute = declaredType.GetCustomAttributes(typeof(GroBufCustomSerializationAttribute), false).FirstOrDefault() as GroBufCustomSerializationAttribute;

            if (attribute == null)
            {
                return(null);
            }
            Type       customSerializerType = attribute.CustomSerializerType ?? declaredType;
            MethodInfo customSizeCounter    = GroBufHelpers.GetMethod <GroBufSizeCounterAttribute>(customSerializerType);

            if (customSizeCounter == null)
            {
                throw new MissingMethodException("Missing grobuf custom size counter for type '" + customSerializerType + "'");
            }
            MethodInfo writer = GroBufHelpers.GetMethod <GroBufWriterAttribute>(customSerializerType);

            if (writer == null)
            {
                throw new MissingMethodException("Missing grobuf custom writer for type '" + customSerializerType + "'");
            }
            MethodInfo reader = GroBufHelpers.GetMethod <GroBufReaderAttribute>(customSerializerType);

            if (reader == null)
            {
                throw new MissingMethodException("Missing grobuf custom reader for type '" + customSerializerType + "'");
            }
            var sizeCounterDelegate = (SizeCounterDelegate)customSizeCounter.Invoke(
                null,
                new object[] { (Func <Type, SizeCounterDelegate>)(type => ((o, empty, context) => factory(type).CountSize(o, empty, context))), (SizeCounterDelegate)(baseSerializer.CountSize) });
            var writerDelegate = (WriterDelegate)writer.Invoke(
                null,
                new object[] { (Func <Type, WriterDelegate>)(type => ((object o, bool empty, IntPtr result, ref int index, WriterContext context) => factory(type).Write(o, empty, result, ref index, context))), (WriterDelegate)(baseSerializer.Write) });
            var readerDelegate = (ReaderDelegate)reader.Invoke(
                null,
                new object[] { (Func <Type, ReaderDelegate>)(type => ((IntPtr data, ref int index, ref object result, ReaderContext context) => factory(type).Read(data, ref index, ref result, context))), (ReaderDelegate)(baseSerializer.Read) });

            return(new GroBufCustomSerializerByAttribute(sizeCounterDelegate, writerDelegate, readerDelegate));
        }
Пример #3
0
        public static void BuildValuesTable(Type type, out int[] values, out ulong[] hashCodes)
        {
            var fields  = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            var arr     = fields.Select(field => ConvertToInt(Enum.Parse(type, field.Name), type.GetEnumUnderlyingType())).ToArray();
            var hashes  = GroBufHelpers.CalcHashesAndCheck(fields.Select(DataMember.Create));
            var hashSet = new HashSet <uint>();

            for (var x = (uint)hashes.Length;; ++x)
            {
                hashSet.Clear();
                var ok = true;
                foreach (var hash in hashes)
                {
                    var item = (uint)(hash % x);
                    if (hashSet.Contains(item))
                    {
                        ok = false;
                        break;
                    }
                    hashSet.Add(item);
                }
                if (!ok)
                {
                    continue;
                }
                hashCodes = new ulong[x];
                values    = new int[x];
                for (var i = 0; i < hashes.Length; i++)
                {
                    var hash  = hashes[i];
                    var index = (int)(hash % x);
                    hashCodes[index] = hash;
                    values[index]    = (int)arr.GetValue(i);
                }
                return;
            }
        }