Esempio n. 1
0
        void Pack(MsgPackWriter writer, object o)
        {
            if (o == null)
            {
                writer.WriteNil();
                return;
            }

            Type t = o.GetType();

            if (t.IsPrimitive)
            {
                if (t.Equals(typeof(int)))
                {
                    writer.Write((int)o);
                }
                else if (t.Equals(typeof(uint)))
                {
                    writer.Write((uint)o);
                }
                else if (t.Equals(typeof(float)))
                {
                    writer.Write((float)o);
                }
                else if (t.Equals(typeof(double)))
                {
                    writer.Write((double)o);
                }
                else if (t.Equals(typeof(long)))
                {
                    writer.Write((long)o);
                }
                else if (t.Equals(typeof(ulong)))
                {
                    writer.Write((ulong)o);
                }
                else if (t.Equals(typeof(bool)))
                {
                    writer.Write((bool)o);
                }
                else if (t.Equals(typeof(byte)))
                {
                    writer.Write((byte)o);
                }
                else if (t.Equals(typeof(sbyte)))
                {
                    writer.Write((sbyte)o);
                }
                else if (t.Equals(typeof(short)))
                {
                    writer.Write((short)o);
                }
                else if (t.Equals(typeof(ushort)))
                {
                    writer.Write((ushort)o);
                }
                else if (t.Equals(typeof(char)))
                {
                    writer.Write((ushort)(char)o);
                }
                else
                {
                    throw new NotSupportedException();
                }
                return;
            }

            PackDelegate packer;

            if (PackerMapping.TryGetValue(t, out packer))
            {
                packer(this, writer, o);
                return;
            }

            if (t.IsArray)
            {
                Array ary = (Array)o;
                writer.WriteArrayHeader(ary.Length);
                for (int i = 0; i < ary.Length; i++)
                {
                    Pack(writer, ary.GetValue(i));
                }
                return;
            }

            ReflectionCacheEntry entry = ReflectionCache.Lookup(t);

            writer.WriteMapHeader(entry.FieldMap.Count);
            foreach (KeyValuePair <string, FieldInfo> pair in entry.FieldMap)
            {
                writer.Write(pair.Key, _buf);
                object v = pair.Value.GetValue(o);
                if (pair.Value.FieldType.IsInterface && v != null)
                {
                    writer.WriteArrayHeader(2);
                    writer.Write(v.GetType().FullName);
                }
                Pack(writer, v);
            }
        }
Esempio n. 2
0
        private void Pack(MsgPackWriter writer, object o)
        {
            if (o == null)
            {
                writer.WriteNil();
                return;
            }
            Type         type = o.GetType();
            PackDelegate value;

            if (type.IsPrimitive)
            {
                if (type.Equals(typeof(int)))
                {
                    writer.Write((int)o);
                    return;
                }
                if (type.Equals(typeof(uint)))
                {
                    writer.Write((uint)o);
                    return;
                }
                if (type.Equals(typeof(float)))
                {
                    writer.Write((float)o);
                    return;
                }
                if (type.Equals(typeof(double)))
                {
                    writer.Write((double)o);
                    return;
                }
                if (type.Equals(typeof(long)))
                {
                    writer.Write((long)o);
                    return;
                }
                if (type.Equals(typeof(ulong)))
                {
                    writer.Write((ulong)o);
                    return;
                }
                if (type.Equals(typeof(bool)))
                {
                    writer.Write((bool)o);
                    return;
                }
                if (type.Equals(typeof(byte)))
                {
                    writer.Write((byte)o);
                    return;
                }
                if (type.Equals(typeof(sbyte)))
                {
                    writer.Write((sbyte)o);
                    return;
                }
                if (type.Equals(typeof(short)))
                {
                    writer.Write((short)o);
                    return;
                }
                if (type.Equals(typeof(ushort)))
                {
                    writer.Write((ushort)o);
                    return;
                }
                if (!type.Equals(typeof(char)))
                {
                    throw new NotSupportedException();
                }
                writer.Write((ushort)(char)o);
            }
            else if (PackerMapping.TryGetValue(type, out value))
            {
                value(this, writer, o);
            }
            else if (type.IsArray)
            {
                Array array = (Array)o;
                writer.WriteArrayHeader(array.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    Pack(writer, array.GetValue(i));
                }
            }
            else
            {
                ReflectionCacheEntry reflectionCacheEntry = ReflectionCache.Lookup(type);
                writer.WriteMapHeader(reflectionCacheEntry.FieldMap.Count);
                foreach (KeyValuePair <string, FieldInfo> item in reflectionCacheEntry.FieldMap)
                {
                    writer.Write(item.Key, _buf);
                    object value2 = item.Value.GetValue(o);
                    if (item.Value.FieldType.IsInterface && value2 != null)
                    {
                        writer.WriteArrayHeader(2);
                        writer.Write(value2.GetType().FullName);
                    }
                    Pack(writer, value2);
                }
            }
        }
Esempio n. 3
0
        object Unpack(MsgPackReader reader, Type t)
        {
            if (t.IsPrimitive)
            {
                if (!reader.Read())
                {
                    throw new FormatException();
                }
                if (t.Equals(typeof(int)) && reader.IsSigned())
                {
                    return(reader.ValueSigned);
                }
                else if (t.Equals(typeof(uint)) && reader.IsUnsigned())
                {
                    return(reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(float)) && reader.Type == TypePrefixes.Float)
                {
                    return(reader.ValueFloat);
                }
                else if (t.Equals(typeof(double)) && reader.Type == TypePrefixes.Double)
                {
                    return(reader.ValueDouble);
                }
                else if (t.Equals(typeof(long)))
                {
                    if (reader.IsSigned64())
                    {
                        return(reader.ValueSigned64);
                    }
                    if (reader.IsSigned())
                    {
                        return((long)reader.ValueSigned);
                    }
                }
                else if (t.Equals(typeof(ulong)))
                {
                    if (reader.IsUnsigned64())
                    {
                        return(reader.ValueUnsigned64);
                    }
                    if (reader.IsUnsigned())
                    {
                        return((ulong)reader.ValueUnsigned);
                    }
                }
                else if (t.Equals(typeof(bool)) && reader.IsBoolean())
                {
                    return(reader.Type == TypePrefixes.True);
                }
                else if (t.Equals(typeof(byte)) && reader.IsUnsigned())
                {
                    return((byte)reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(sbyte)) && reader.IsSigned())
                {
                    return((sbyte)reader.ValueSigned);
                }
                else if (t.Equals(typeof(short)) && reader.IsSigned())
                {
                    return((short)reader.ValueSigned);
                }
                else if (t.Equals(typeof(ushort)) && reader.IsUnsigned())
                {
                    return((ushort)reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(char)) && reader.IsUnsigned())
                {
                    return((char)reader.ValueUnsigned);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }

            UnpackDelegate unpacker;

            if (UnpackerMapping.TryGetValue(t, out unpacker))
            {
                return(unpacker(this, reader));
            }

            if (t.IsArray)
            {
                if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                {
                    throw new FormatException();
                }
                if (reader.Type == TypePrefixes.Nil)
                {
                    return(null);
                }
                Type  et  = t.GetElementType();
                Array ary = Array.CreateInstance(et, (int)reader.Length);
                for (int i = 0; i < ary.Length; i++)
                {
                    ary.SetValue(Unpack(reader, et), i);
                }
                return(ary);
            }

            if (!reader.Read())
            {
                throw new FormatException();
            }
            if (reader.Type == TypePrefixes.Nil)
            {
                return(null);
            }
            if (t.IsInterface)
            {
                if (reader.Type != TypePrefixes.FixArray && reader.Length != 2)
                {
                    throw new FormatException();
                }
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                t = Type.GetType(Encoding.UTF8.GetString(_buf, 0, (int)reader.Length));
                if (!reader.Read() || reader.Type == TypePrefixes.Nil)
                {
                    throw new FormatException();
                }
            }
            if (!reader.IsMap())
            {
                throw new FormatException();
            }

            object o = FormatterServices.GetUninitializedObject(t);
            ReflectionCacheEntry entry = ReflectionCache.Lookup(t);
            int members = (int)reader.Length;

            for (int i = 0; i < members; i++)
            {
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                string    name = Encoding.UTF8.GetString(_buf, 0, (int)reader.Length);
                FieldInfo f;
                if (!entry.FieldMap.TryGetValue(name, out f))
                {
                    throw new FormatException();
                }
                f.SetValue(o, Unpack(reader, f.FieldType));
            }

            IDeserializationCallback callback = o as IDeserializationCallback;

            if (callback != null)
            {
                callback.OnDeserialization(this);
            }
            return(o);
        }
Esempio n. 4
0
        private object Unpack(MsgPackReader reader, Type t)
        {
            if (t.IsPrimitive)
            {
                if (!reader.Read())
                {
                    throw new FormatException();
                }
                if (t.Equals(typeof(int)) && reader.IsSigned())
                {
                    return(reader.ValueSigned);
                }
                if (t.Equals(typeof(uint)) && reader.IsUnsigned())
                {
                    return(reader.ValueUnsigned);
                }
                if (t.Equals(typeof(float)) && reader.Type == TypePrefixes.Float)
                {
                    return(reader.ValueFloat);
                }
                if (t.Equals(typeof(double)) && reader.Type == TypePrefixes.Double)
                {
                    return(reader.ValueDouble);
                }
                if (t.Equals(typeof(long)))
                {
                    if (reader.IsSigned64())
                    {
                        return(reader.ValueSigned64);
                    }
                    if (reader.IsSigned())
                    {
                        return((long)reader.ValueSigned);
                    }
                }
                else
                {
                    if (!t.Equals(typeof(ulong)))
                    {
                        if (t.Equals(typeof(bool)) && reader.IsBoolean())
                        {
                            return(reader.Type == TypePrefixes.True);
                        }
                        if (t.Equals(typeof(byte)) && reader.IsUnsigned())
                        {
                            return((byte)reader.ValueUnsigned);
                        }
                        if (t.Equals(typeof(sbyte)) && reader.IsSigned())
                        {
                            return((sbyte)reader.ValueSigned);
                        }
                        if (t.Equals(typeof(short)) && reader.IsSigned())
                        {
                            return((short)reader.ValueSigned);
                        }
                        if (t.Equals(typeof(ushort)) && reader.IsUnsigned())
                        {
                            return((ushort)reader.ValueUnsigned);
                        }
                        if (t.Equals(typeof(char)) && reader.IsUnsigned())
                        {
                            return((char)reader.ValueUnsigned);
                        }
                        throw new NotSupportedException();
                    }
                    if (reader.IsUnsigned64())
                    {
                        return(reader.ValueUnsigned64);
                    }
                    if (reader.IsUnsigned())
                    {
                        return((ulong)reader.ValueUnsigned);
                    }
                }
            }
            if (UnpackerMapping.TryGetValue(t, out UnpackDelegate value))
            {
                return(value(this, reader));
            }
            if (t.IsArray)
            {
                if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                {
                    throw new FormatException();
                }
                if (reader.Type == TypePrefixes.Nil)
                {
                    return(null);
                }
                Type  elementType = t.GetElementType();
                Array array       = Array.CreateInstance(elementType, (int)reader.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    array.SetValue(Unpack(reader, elementType), i);
                }
                return(array);
            }
            if (!reader.Read())
            {
                throw new FormatException();
            }
            if (reader.Type == TypePrefixes.Nil)
            {
                return(null);
            }
            if (t.IsInterface)
            {
                if (reader.Type != TypePrefixes.FixArray && reader.Length != 2)
                {
                    throw new FormatException();
                }
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                t = Type.GetType(Encoding.UTF8.GetString(_buf, 0, (int)reader.Length));
                if (!reader.Read() || reader.Type == TypePrefixes.Nil)
                {
                    throw new FormatException();
                }
            }
            if (!reader.IsMap())
            {
                throw new FormatException();
            }
            object uninitializedObject = FormatterServices.GetUninitializedObject(t);
            ReflectionCacheEntry reflectionCacheEntry = ReflectionCache.Lookup(t);
            int length = (int)reader.Length;

            for (int j = 0; j < length; j++)
            {
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                string @string = Encoding.UTF8.GetString(_buf, 0, (int)reader.Length);
                if (!reflectionCacheEntry.FieldMap.TryGetValue(@string, out FieldInfo value2))
                {
                    throw new FormatException();
                }
                value2.SetValue(uninitializedObject, Unpack(reader, value2.FieldType));
            }
            (uninitializedObject as IDeserializationCallback)?.OnDeserialization(this);
            return(uninitializedObject);
        }
Esempio n. 5
0
        void Pack(MsgPackWriter writer, object o)
        {
            if (o == null)
            {
                writer.WriteNil();
                return;
            }

            Type t = o.GetType();

            if (t.IsPrimitive)
            {
                if (t.Equals(typeof(int)))
                {
                    writer.Write((int)o);
                }
                else if (t.Equals(typeof(uint)))
                {
                    writer.Write((uint)o);
                }
                else if (t.Equals(typeof(float)))
                {
                    writer.Write((float)o);
                }
                else if (t.Equals(typeof(double)))
                {
                    writer.Write((double)o);
                }
                else if (t.Equals(typeof(long)))
                {
                    writer.Write((long)o);
                }
                else if (t.Equals(typeof(ulong)))
                {
                    writer.Write((ulong)o);
                }
                else if (t.Equals(typeof(bool)))
                {
                    writer.Write((bool)o);
                }
                else if (t.Equals(typeof(byte)))
                {
                    writer.Write((byte)o);
                }
                else if (t.Equals(typeof(sbyte)))
                {
                    writer.Write((sbyte)o);
                }
                else if (t.Equals(typeof(short)))
                {
                    writer.Write((short)o);
                }
                else if (t.Equals(typeof(ushort)))
                {
                    writer.Write((ushort)o);
                }
                else if (t.Equals(typeof(char)))
                {
                    writer.Write((ushort)(char)o);
                }
                else
                {
                    throw new NotSupportedException();
                }
                return;
            }

            PackDelegate packer;

            if (PackerMapping.TryGetValue(t, out packer))
            {
                packer(this, writer, o);
                return;
            }

            if (o is Packable)
            {
                Packable p = o as Packable;
                p.Pack(this, writer);
                return;
            }

            if (t.IsArray)
            {
                Array ary = (Array)o;
                writer.WriteArrayHeader(ary.Length);
                for (int i = 0; i < ary.Length; i++)
                {
                    Pack(writer, ary.GetValue(i));
                }
                return;
            }

            if (typeof(IList).IsAssignableFrom(t))
            {
                IList list = (IList)o;
                writer.WriteArrayHeader(list.Count);

                for (int i = 0; i < list.Count; i++)
                {
                    Pack(writer, list[i]);
                }
                return;
            }

            if (t.IsGenericType)
            {
                var setType = typeof(ISet <>).MakeGenericType(t.GetGenericArguments()[0]);
                if (setType.IsAssignableFrom(t))
                {
                    IEnumerable list = (IEnumerable)o;
                    writer.WriteArrayHeader((int)t.GetProperty("Count").GetValue(o, null));

                    foreach (object e in list)
                    {
                        Pack(writer, e);
                    }
                    return;
                }
            }

            if (typeof(IDictionary).IsAssignableFrom(t))
            {
                IDictionary dict = (IDictionary)o;
                writer.WriteArrayHeader(dict.Count);

                IDictionaryEnumerator enumerator = dict.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    Pack(writer, enumerator.Key);
                    Pack(writer, enumerator.Value);
                }

                return;
            }

            ReflectionCacheEntry entry = ReflectionCache.Lookup(t);

            writer.WriteMapHeader(entry.FieldMap.Count);
            foreach (KeyValuePair <string, FieldInfo> pair in entry.FieldMap)
            {
                writer.Write(pair.Key, _buf);
                object v = pair.Value.GetValue(o);
                if (pair.Value.FieldType.IsInterface && v != null)
                {
                    writer.WriteArrayHeader(2);
                    writer.Write(v.GetType().FullName);
                }
                Pack(writer, v);
            }
        }
Esempio n. 6
0
        object Unpack(MsgPackReader reader, Type t)
        {
            if (t.IsPrimitive)
            {
                if (!reader.Read())
                {
                    throw new FormatException();
                }
                if (t.Equals(typeof(int)) && reader.IsSigned())
                {
                    return(reader.ValueSigned);
                }
                else if (t.Equals(typeof(uint)) && reader.IsUnsigned())
                {
                    return(reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(float)) && reader.Type == TypePrefixes.Float)
                {
                    return(reader.ValueFloat);
                }
                else if (t.Equals(typeof(double)) && reader.Type == TypePrefixes.Double)
                {
                    return(reader.ValueDouble);
                }
                else if (t.Equals(typeof(long)))
                {
                    if (reader.IsSigned64())
                    {
                        return(reader.ValueSigned64);
                    }
                    if (reader.IsSigned())
                    {
                        return((long)reader.ValueSigned);
                    }
                }
                else if (t.Equals(typeof(ulong)))
                {
                    if (reader.IsUnsigned64())
                    {
                        return(reader.ValueUnsigned64);
                    }
                    if (reader.IsUnsigned())
                    {
                        return((ulong)reader.ValueUnsigned);
                    }
                }
                else if (t.Equals(typeof(bool)) && reader.IsBoolean())
                {
                    return(reader.Type == TypePrefixes.True);
                }
                else if (t.Equals(typeof(byte)) && reader.IsUnsigned())
                {
                    return((byte)reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(sbyte)) && reader.IsSigned())
                {
                    return((sbyte)reader.ValueSigned);
                }
                else if (t.Equals(typeof(short)) && reader.IsSigned())
                {
                    return((short)reader.ValueSigned);
                }
                else if (t.Equals(typeof(ushort)) && reader.IsUnsigned())
                {
                    return((ushort)reader.ValueUnsigned);
                }
                else if (t.Equals(typeof(char)) && reader.IsUnsigned())
                {
                    return((char)reader.ValueUnsigned);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }

            UnpackDelegate unpacker;

            if (UnpackerMapping.TryGetValue(t, out unpacker))
            {
                return(unpacker(this, reader));
            }

            if (typeof(Packable).IsAssignableFrom(t))
            {
                Packable p = Activator.CreateInstance(t) as Packable;
                return(p.Unpack(this, reader));
            }

            if (t.IsArray)
            {
                if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                {
                    throw new FormatException();
                }
                if (reader.Type == TypePrefixes.Nil)
                {
                    return(null);
                }
                Type  et  = t.GetElementType();
                Array ary = Array.CreateInstance(et, (int)reader.Length);
                for (int i = 0; i < ary.Length; i++)
                {
                    ary.SetValue(Unpack(reader, et), i);
                }
                return(ary);
            }

            // IEnumerable 型の場合
            // 現在は IList, ISet, IDictionary をサポート
            if (typeof(IEnumerable).IsAssignableFrom(t) && t.IsGenericType)
            {
                Type[] generics = t.GetGenericArguments();

                // IList 型の場合
                if (typeof(IList).IsAssignableFrom(t))
                {
                    if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                    {
                        throw new FormatException();
                    }
                    if (reader.Type == TypePrefixes.Nil)
                    {
                        return(null);
                    }

                    Type  et    = generics.Single();
                    int   count = (int)reader.Length;
                    Array ary   = Array.CreateInstance(et, count);

                    for (int i = 0; i < count; i++)
                    {
                        ary.SetValue(Unpack(reader, et), i);
                    }
                    return(Activator.CreateInstance(t, new object[] { ary }));
                }

                // ISet 型の場合
                var setType = typeof(ISet <>).MakeGenericType(generics[0]);
                if (setType.IsAssignableFrom(t))
                {
                    if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                    {
                        throw new FormatException();
                    }
                    if (reader.Type == TypePrefixes.Nil)
                    {
                        return(null);
                    }

                    Type et    = generics.Single();
                    int  count = (int)reader.Length;

                    Array ary = Array.CreateInstance(et, count);

                    for (int i = 0; i < count; i++)
                    {
                        ary.SetValue(Unpack(reader, et), i);
                    }
                    return(Activator.CreateInstance(t, new object[] { ary }));
                }

                if (typeof(IDictionary).IsAssignableFrom(t))
                {
                    if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                    {
                        throw new FormatException();
                    }
                    if (reader.Type == TypePrefixes.Nil)
                    {
                        return(null);
                    }

                    Type kt = generics[0];
                    Type vt = generics[1];

                    IDictionary dict  = (IDictionary)Activator.CreateInstance(t);
                    int         count = (int)reader.Length;

                    for (int i = 0; i < count; i++)
                    {
                        dict[Unpack(reader, kt)] = Unpack(reader, vt);
                    }
                    return(dict);
                }
            }

            if (!reader.Read())
            {
                throw new FormatException();
            }
            if (reader.Type == TypePrefixes.Nil)
            {
                return(null);
            }
            if (t.IsInterface)
            {
                if (reader.Type != TypePrefixes.FixArray && reader.Length != 2)
                {
                    throw new FormatException();
                }
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                t = Type.GetType(Encoding.UTF8.GetString(_buf, 0, (int)reader.Length));
                if (!reader.Read() || reader.Type == TypePrefixes.Nil)
                {
                    throw new FormatException();
                }
            }
            if (!reader.IsMap())
            {
                throw new FormatException();
            }

            object o = FormatterServices.GetUninitializedObject(t);
            ReflectionCacheEntry entry = ReflectionCache.Lookup(t);
            int members = (int)reader.Length;

            for (int i = 0; i < members; i++)
            {
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                string    name = Encoding.UTF8.GetString(_buf, 0, (int)reader.Length);
                FieldInfo f;

                if (!entry.FieldMap.TryGetValue(name, out f))
                {
                    throw new FormatException();
                }
                f.SetValue(o, Unpack(reader, f.FieldType));
            }

            IDeserializationCallback callback = o as IDeserializationCallback;

            if (callback != null)
            {
                callback.OnDeserialization(this);
            }
            return(o);
        }
        object Unpack(MsgPackReader reader, string name, Type type)
        {
            if (!reader.Read())
            {
                throw GenerateFormatException(type, name);
            }

            if (reader.Type == TypePrefixes.Nil)
            {
                return(null);
            }

            if (type.IsPrimitive)
            {
                return(ValueAsPrimitive(reader, type));
            }

            if (type.IsEnum)
            {
                return(ValueAsPrimitive(reader, typeof(int)));
            }

            Type nullableType = Nullable.GetUnderlyingType(type);

            if (nullableType != null && nullableType.IsPrimitive)
            {
                return(ValueAsPrimitive(reader, nullableType));
            }

            if (type.IsArray)
            {
                if ((!reader.IsArray()))
                {
                    throw GenerateFormatException(type, name);
                }

                Type  elementType = type.GetElementType();
                Array array       = Array.CreateInstance(elementType, (int)reader.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    array.SetValue(Unpack(reader, name, elementType), i);
                }
                return(array);
            }

            if (type.IsInterface)
            {
                if (reader.Type != TypePrefixes.FixArray && reader.Length != 2)
                {
                    throw GenerateFormatException(type, name);
                }
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw GenerateFormatException(type, name);
                }
                var nextType = Type.GetType(reader.ReadRawString());
                return(Unpack(reader, name, nextType));
            }

            if (reader.IsMap())
            {
                object obj = FormatterServices.GetUninitializedObject(type);
                ReflectionCacheEntry entry = ReflectionCache.Lookup(type);
                int members = (int)reader.Length;
                for (int i = 0; i < members; i++)
                {
                    if (!reader.Read() || !reader.IsRaw())
                    {
                        throw GenerateFormatException(type, name);
                    }
                    FieldInfo fieldInfo;
                    string    nextFieldName = reader.ReadRawString();
                    if (!entry.FieldMap.TryGetValue(nextFieldName, out fieldInfo))
                    {
                        reader.Skip();                         // skip to next if field name is missing.
                        continue;
                    }
                    fieldInfo.SetValue(obj, Unpack(reader, nextFieldName, fieldInfo.FieldType));
                }
                return(obj);
            }

            UnpackDelegate unpacker;

            if (UnpackerMapping.TryGetValue(type, out unpacker))
            {
                return(unpacker(this, reader));
            }

            throw GenerateFormatException(type, name);
        }
        private object Unpack(MsgPackReader reader, Type t)
        {
            //IL_0591: Unknown result type (might be due to invalid IL or missing references)
            //IL_0596: Expected O, but got Unknown
            if (t.IsPrimitive)
            {
                if (!reader.Read())
                {
                    throw new FormatException();
                }
                if (t.Equals(typeof(int)) && reader.IsSigned())
                {
                    return(reader.ValueSigned);
                }
                if (t.Equals(typeof(int)) && reader.IsUnsigned())
                {
                    return((int)reader.ValueUnsigned);
                }
                if (t.Equals(typeof(uint)) && reader.IsUnsigned())
                {
                    return(reader.ValueUnsigned);
                }
                if (t.Equals(typeof(float)))
                {
                    if (reader.Type == TypePrefixes.Float)
                    {
                        return(reader.ValueFloat);
                    }
                    if (reader.Type == TypePrefixes.Double)
                    {
                        return((float)reader.ValueDouble);
                    }
                    if (reader.IsUnsigned())
                    {
                        return((float)(double)reader.ValueUnsigned);
                    }
                    if (reader.IsSigned())
                    {
                        return((float)reader.ValueSigned);
                    }
                }
                else
                {
                    if (t.Equals(typeof(double)) && reader.Type == TypePrefixes.Double)
                    {
                        return(reader.ValueDouble);
                    }
                    if (t.Equals(typeof(long)))
                    {
                        if (reader.IsSigned64())
                        {
                            return(reader.ValueSigned64);
                        }
                        if (reader.IsSigned())
                        {
                            return((long)reader.ValueSigned);
                        }
                        if (reader.IsUnsigned64())
                        {
                            return((long)reader.ValueUnsigned64);
                        }
                        if (reader.IsUnsigned())
                        {
                            return((long)reader.ValueUnsigned);
                        }
                    }
                    else
                    {
                        if (!t.Equals(typeof(ulong)))
                        {
                            if (t.Equals(typeof(bool)) && reader.IsBoolean())
                            {
                                return(reader.Type == TypePrefixes.True);
                            }
                            if (t.Equals(typeof(byte)) && reader.IsUnsigned())
                            {
                                return((byte)reader.ValueUnsigned);
                            }
                            if (t.Equals(typeof(sbyte)) && reader.IsSigned())
                            {
                                return((sbyte)reader.ValueSigned);
                            }
                            if (t.Equals(typeof(short)) && reader.IsSigned())
                            {
                                return((short)reader.ValueSigned);
                            }
                            if (t.Equals(typeof(ushort)) && reader.IsUnsigned())
                            {
                                return((ushort)reader.ValueUnsigned);
                            }
                            if (t.Equals(typeof(char)) && reader.IsUnsigned())
                            {
                                return((char)reader.ValueUnsigned);
                            }
                            throw new NotSupportedException();
                        }
                        if (reader.IsUnsigned64())
                        {
                            return(reader.ValueUnsigned64);
                        }
                        if (reader.IsUnsigned())
                        {
                            return((ulong)reader.ValueUnsigned);
                        }
                    }
                }
            }
            if (UnpackerMapping.TryGetValue(t, out UnpackDelegate value))
            {
                return(value(this, reader));
            }
            if (t.IsArray)
            {
                if (!reader.Read() || (!reader.IsArray() && reader.Type != TypePrefixes.Nil))
                {
                    throw new FormatException();
                }
                if (reader.Type == TypePrefixes.Nil)
                {
                    return(null);
                }
                Type  elementType = t.GetElementType();
                Array array       = Array.CreateInstance(elementType, (int)reader.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    array.SetValue(Unpack(reader, elementType), i);
                }
                return(array);
            }
            if (t.IsEnum)
            {
                if (!reader.Read())
                {
                    throw new FormatException();
                }
                if (reader.IsSigned())
                {
                    return(Enum.ToObject(t, reader.ValueSigned));
                }
                if (reader.IsSigned64())
                {
                    return(Enum.ToObject(t, reader.ValueSigned64));
                }
                if (reader.IsUnsigned())
                {
                    return(Enum.ToObject(t, reader.ValueUnsigned));
                }
                if (reader.IsUnsigned64())
                {
                    return(Enum.ToObject(t, reader.ValueUnsigned64));
                }
                if (reader.IsRaw())
                {
                    CheckBufferSize((int)reader.Length);
                    reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                    string @string = Encoding.UTF8.GetString(_buf, 0, (int)reader.Length);
                    return(Enum.Parse(t, @string));
                }
                throw new FormatException();
            }
            if (!reader.Read())
            {
                throw new FormatException();
            }
            if (reader.Type == TypePrefixes.Nil)
            {
                return(null);
            }
            if (t.IsInterface)
            {
                if (reader.Type != TypePrefixes.FixArray && reader.Length != 2)
                {
                    throw new FormatException();
                }
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                t = Type.GetType(Encoding.UTF8.GetString(_buf, 0, (int)reader.Length));
                if (!reader.Read() || reader.Type == TypePrefixes.Nil)
                {
                    throw new FormatException();
                }
            }
            if (!reader.IsMap())
            {
                throw new FormatException();
            }
            object obj = (!typeof(ScriptableObject).IsAssignableFrom(t)) ? FormatterServices.GetUninitializedObject(t) : ((object)ScriptableObject.CreateInstance(t));
            ReflectionCacheEntry reflectionCacheEntry = ReflectionCache.Lookup(t);
            int length = (int)reader.Length;

            for (int j = 0; j < length; j++)
            {
                if (!reader.Read() || !reader.IsRaw())
                {
                    throw new FormatException();
                }
                CheckBufferSize((int)reader.Length);
                reader.ReadValueRaw(_buf, 0, (int)reader.Length);
                string string2 = Encoding.UTF8.GetString(_buf, 0, (int)reader.Length);
                if (!reflectionCacheEntry.FieldMap.TryGetValue(string2, out FieldInfo value2))
                {
                    new BoxingPacker().Unpack(reader);
                }
                else
                {
                    value2.SetValue(obj, Unpack(reader, value2.FieldType));
                }
            }
            (obj as IDeserializationCallback)?.OnDeserialization(this);
            return(obj);
        }