private bool Deserialize(byte[] source, int baseIndex, object target, out int writtenBytes)
        {
            if (target == null)
            {
                writtenBytes = 0;
                return(false);
            }
            Type type = target.GetType();

            FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            int         num    = baseIndex;

            FieldInfo[] array = fields;
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo fieldInfo = array[i];
                if (!RawSerializer.IsIngoreField(fieldInfo))
                {
                    Type   fieldType = fieldInfo.FieldType;
                    object obj       = null;
                    if (fieldType.IsArray)
                    {
                        Array           array2          = null;
                        LengthAttribute lengthAttribute = Attribute.GetCustomAttribute(fieldInfo, typeof(LengthAttribute)) as LengthAttribute;
                        if (lengthAttribute != null)
                        {
                            if (lengthAttribute.LengthField != null)
                            {
                                FieldInfo lengthField = this.GetLengthField(fields, lengthAttribute.LengthField);
                                if (lengthField != null)
                                {
                                    object value = lengthField.GetValue(target);
                                    Type   type2 = value.GetType();
                                    if (type2 == typeof(byte))
                                    {
                                        lengthAttribute.Length = (int)((byte)value);
                                    }
                                    else if (type2 == typeof(short))
                                    {
                                        lengthAttribute.Length = (int)((short)value);
                                    }
                                    else if (type2 == typeof(int))
                                    {
                                        lengthAttribute.Length = (int)value;
                                    }
                                }
                            }
                            array2 = (fieldInfo.GetValue(target) as Array);
                            lengthAttribute.ResizeArray(fieldType, ref array2);
                        }
                        if (fieldType == typeof(bool[]))
                        {
                            obj = this.BytesToArray <bool>(source, ref num, array2, 1, new Func <byte[], int, bool>(BitConverter.ToBoolean));
                        }
                        else if (fieldType == typeof(char[]))
                        {
                            obj = this.BytesToChars(source, ref num, array2);
                        }
                        else if (fieldType == typeof(byte[]))
                        {
                            obj = this.BytesToArray <byte>(source, ref num, array2, 1, (byte[] buf, int off) => buf[off]);
                        }
                        else if (fieldType == typeof(sbyte[]))
                        {
                            obj = this.BytesToArray <byte>(source, ref num, array2, 1, (byte[] buf, int off) => buf[off]);
                        }
                        else if (fieldType == typeof(short[]))
                        {
                            obj = this.BytesToArray <short>(source, ref num, array2, 2, new Func <byte[], int, short>(BitConverter.ToInt16));
                        }
                        else if (fieldType == typeof(ushort[]))
                        {
                            obj = this.BytesToArray <ushort>(source, ref num, array2, 2, new Func <byte[], int, ushort>(BitConverter.ToUInt16));
                        }
                        else if (fieldType == typeof(int[]))
                        {
                            obj = this.BytesToArray <int>(source, ref num, array2, 4, new Func <byte[], int, int>(BitConverter.ToInt32));
                        }
                        else if (fieldType == typeof(uint[]))
                        {
                            obj = this.BytesToArray <uint>(source, ref num, array2, 4, new Func <byte[], int, uint>(BitConverter.ToUInt32));
                        }
                        else if (fieldType == typeof(long[]))
                        {
                            obj = this.BytesToArray <long>(source, ref num, array2, 8, new Func <byte[], int, long>(BitConverter.ToInt64));
                        }
                        else if (fieldType == typeof(ulong[]))
                        {
                            obj = this.BytesToArray <ulong>(source, ref num, array2, 8, new Func <byte[], int, ulong>(BitConverter.ToUInt64));
                        }
                        else if (fieldType == typeof(float[]))
                        {
                            obj = this.BytesToArray <float>(source, ref num, array2, 4, new Func <byte[], int, float>(BitConverter.ToSingle));
                        }
                        else if (fieldType == typeof(double[]))
                        {
                            obj = this.BytesToArray <double>(source, ref num, array2, 8, new Func <byte[], int, double>(BitConverter.ToDouble));
                        }
                        else if (!fieldType.GetElementType().IsPrimitive)
                        {
                            Array array3 = fieldInfo.GetValue(target) as Array;
                            if (array3 == null || array3.Length != array2.Length)
                            {
                                array3 = array2;
                            }
                            int num2 = 0;
                            foreach (object current in array3)
                            {
                                int num3;
                                this.Deserialize(source, num, current, out num3);
                                array3.SetValue(current, num2++);
                                num += num3;
                            }
                            fieldInfo.SetValue(target, array3);
                        }
                    }
                    else if (fieldType == typeof(bool))
                    {
                        obj = BitConverter.ToBoolean(source, num);
                        num++;
                    }
                    else if (fieldType == typeof(int))
                    {
                        obj  = BitConverter.ToInt32(source, num);
                        num += 4;
                    }
                    else if (fieldType == typeof(uint))
                    {
                        obj  = BitConverter.ToUInt32(source, num);
                        num += 4;
                    }
                    else if (fieldType == typeof(short))
                    {
                        obj  = BitConverter.ToInt16(source, num);
                        num += 2;
                    }
                    else if (fieldType == typeof(ushort))
                    {
                        obj  = BitConverter.ToUInt16(source, num);
                        num += 2;
                    }
                    else if (fieldType == typeof(long))
                    {
                        obj  = BitConverter.ToInt64(source, num);
                        num += 8;
                    }
                    else if (fieldType == typeof(ulong))
                    {
                        obj  = BitConverter.ToUInt64(source, num);
                        num += 8;
                    }
                    else if (fieldType == typeof(byte))
                    {
                        obj = source[num++];
                    }
                    else if (fieldType == typeof(sbyte))
                    {
                        obj = (sbyte)source[num++];
                    }
                    else if (fieldType == typeof(char))
                    {
                        obj  = BitConverter.ToChar(source, num);
                        num += 2;
                    }
                    else if (fieldType == typeof(float))
                    {
                        obj  = BitConverter.ToSingle(source, num);
                        num += 4;
                    }
                    else if (fieldType == typeof(double))
                    {
                        obj  = BitConverter.ToDouble(source, num);
                        num += 8;
                    }
                    else if (fieldType == typeof(string))
                    {
                        char[]          orgVal           = null;
                        LengthAttribute lengthAttribute2 = Attribute.GetCustomAttribute(fieldInfo, typeof(LengthAttribute)) as LengthAttribute;
                        if (lengthAttribute2 != null)
                        {
                            lengthAttribute2.ResizeArray <char>(ref orgVal);
                        }
                        char[] array4 = this.BytesToChars(source, ref num, orgVal);
                        string text   = new string(array4, 0, this.GetCompactLength(array4));
                        obj = text;
                    }
                    else if (!fieldType.IsPrimitive)
                    {
                        object value2 = fieldInfo.GetValue(target);
                        int    num4;
                        this.Deserialize(source, num, value2, out num4);
                        fieldInfo.SetValue(target, value2);
                        num += num4;
                    }
                    if (obj != null)
                    {
                        fieldInfo.SetValue(target, obj);
                    }
                }
            }
            writtenBytes = num - baseIndex;
            return(writtenBytes > 0);
        }
        private static int GetFieldSize(Type type, FieldInfo ownerFieldInfo, object instance)
        {
            int num = 0;

            if (type.IsPrimitive)
            {
                if (!RawSerializer.TryGetPrimitiveSize(type, out num))
                {
                    throw new UnknownLengthException(ownerFieldInfo);
                }
            }
            else if (type == typeof(string))
            {
                if (instance == null)
                {
                    throw new UnknownLengthException(ownerFieldInfo);
                }
                num += 2;
                num += (instance as string).Length * 2;
            }
            else
            {
                FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                FieldInfo[] array  = fields;
                for (int i = 0; i < array.Length; i++)
                {
                    FieldInfo fieldInfo = array[i];
                    if (!RawSerializer.IsIngoreField(fieldInfo))
                    {
                        Type            fieldType       = fieldInfo.FieldType;
                        LengthAttribute lengthAttribute = Attribute.GetCustomAttribute(fieldInfo, typeof(LengthAttribute)) as LengthAttribute;
                        if (fieldType.IsArray)
                        {
                            if (lengthAttribute != null)
                            {
                                num += lengthAttribute.Length * RawSerializer.GetFieldSize(fieldType.GetElementType(), fieldInfo, instance);
                            }
                            else
                            {
                                if (instance == null)
                                {
                                    throw new UnknownLengthException(fieldInfo);
                                }
                                int   fieldSize = RawSerializer.GetFieldSize(fieldType.GetElementType(), fieldInfo, instance);
                                Array array2    = fieldInfo.GetValue(instance) as Array;
                                num += 2;
                                num += array2.Length * fieldSize;
                            }
                        }
                        else if (lengthAttribute != null && fieldType == typeof(string))
                        {
                            num += lengthAttribute.Length * 2;
                        }
                        else
                        {
                            num += RawSerializer.GetFieldSize(fieldType, fieldInfo, instance);
                        }
                    }
                }
            }
            return(num);
        }
        private bool Serialize(object obj, int rawDataBaseIndex, out int writtenLength)
        {
            if (obj == null)
            {
                Console.WriteLine("Serialize() >> input object is null");
                writtenLength = 0;
                return(false);
            }
            Type type = obj.GetType();

            FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            if (fields == null)
            {
                Console.WriteLine("Serialize() >> GetFileds() is null");
                writtenLength = 0;
                return(false);
            }
            int num = rawDataBaseIndex;

            FieldInfo[] array = fields;
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo fieldInfo = array[i];
                if (!RawSerializer.IsIngoreField(fieldInfo))
                {
                    Type   fieldType = fieldInfo.FieldType;
                    object value     = fieldInfo.GetValue(obj);
                    byte[] array2    = null;
                    if (fieldType.IsArray)
                    {
                        Array           array3          = value as Array;
                        LengthAttribute lengthAttribute = Attribute.GetCustomAttribute(fieldInfo, typeof(LengthAttribute)) as LengthAttribute;
                        if (lengthAttribute != null)
                        {
                            lengthAttribute.ResizeArray(fieldType, ref array3);
                        }
                        bool isWriteLength = lengthAttribute == null;
                        if (fieldType == typeof(bool[]))
                        {
                            array2 = this.ArrayToBytes <bool>(array3 as bool[], isWriteLength, 1, new Func <bool, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(char[]))
                        {
                            array2 = this.CharsToBytes(array3 as char[], isWriteLength);
                        }
                        else if (fieldType == typeof(byte[]))
                        {
                            array2 = this.ArrayToBytes <byte>(array3 as byte[], isWriteLength, 1, (byte v) => new byte[]
                            {
                                v
                            });
                        }
                        else if (fieldType == typeof(sbyte[]))
                        {
                            array2 = this.ArrayToBytes <sbyte>(array3 as sbyte[], isWriteLength, 1, (sbyte v) => new byte[]
                            {
                                (byte)v
                            });
                        }
                        else if (fieldType == typeof(short[]))
                        {
                            array2 = this.ArrayToBytes <short>(array3 as short[], isWriteLength, 2, new Func <short, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(ushort[]))
                        {
                            array2 = this.ArrayToBytes <ushort>(array3 as ushort[], isWriteLength, 2, new Func <ushort, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(int[]))
                        {
                            array2 = this.ArrayToBytes <int>(array3 as int[], isWriteLength, 4, new Func <int, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(uint[]))
                        {
                            array2 = this.ArrayToBytes <uint>(array3 as uint[], isWriteLength, 4, new Func <uint, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(long[]))
                        {
                            array2 = this.ArrayToBytes <long>(array3 as long[], isWriteLength, 8, new Func <long, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(ulong[]))
                        {
                            array2 = this.ArrayToBytes <ulong>(array3 as ulong[], isWriteLength, 8, new Func <ulong, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(float[]))
                        {
                            array2 = this.ArrayToBytes <float>(array3 as float[], isWriteLength, 4, new Func <float, byte[]>(BitConverter.GetBytes));
                        }
                        else if (fieldType == typeof(double[]))
                        {
                            array2 = this.ArrayToBytes <double>(array3 as double[], isWriteLength, 8, new Func <double, byte[]>(BitConverter.GetBytes));
                        }
                        else if (!fieldType.GetElementType().IsPrimitive)
                        {
                            foreach (object current in array3)
                            {
                                int num2;
                                this.Serialize(current, num, out num2);
                                num += num2;
                            }
                        }
                    }
                    else if (fieldType == typeof(int))
                    {
                        array2 = BitConverter.GetBytes((int)value);
                    }
                    else if (fieldType == typeof(uint))
                    {
                        array2 = BitConverter.GetBytes((uint)value);
                    }
                    else if (fieldType == typeof(short))
                    {
                        array2 = BitConverter.GetBytes((short)value);
                    }
                    else if (fieldType == typeof(ushort))
                    {
                        array2 = BitConverter.GetBytes((ushort)value);
                    }
                    else if (fieldType == typeof(long))
                    {
                        array2 = BitConverter.GetBytes((long)value);
                    }
                    else if (fieldType == typeof(ulong))
                    {
                        array2 = BitConverter.GetBytes((ulong)value);
                    }
                    else if (fieldType == typeof(byte))
                    {
                        array2 = new byte[]
                        {
                            (byte)value
                        };
                    }
                    else if (fieldType == typeof(sbyte))
                    {
                        sbyte b = (sbyte)value;
                        array2 = new byte[]
                        {
                            (byte)b
                        };
                    }
                    else if (fieldType == typeof(float))
                    {
                        array2 = BitConverter.GetBytes((float)value);
                    }
                    else if (fieldType == typeof(double))
                    {
                        array2 = BitConverter.GetBytes((double)value);
                    }
                    else if (fieldType == typeof(bool))
                    {
                        array2 = BitConverter.GetBytes((bool)value);
                    }
                    else if (fieldType == typeof(char))
                    {
                        array2 = BitConverter.GetBytes((char)value);
                    }
                    else if (fieldType == typeof(string))
                    {
                        string          text             = value as string;
                        char[]          chars            = text.ToCharArray();
                        LengthAttribute lengthAttribute2 = Attribute.GetCustomAttribute(fieldInfo, typeof(LengthAttribute)) as LengthAttribute;
                        if (lengthAttribute2 != null)
                        {
                            lengthAttribute2.ResizeArray <char>(ref chars);
                        }
                        array2 = this.CharsToBytes(chars, lengthAttribute2 == null);
                    }
                    else if (!fieldType.IsPrimitive)
                    {
                        int num3;
                        this.Serialize(value, num, out num3);
                        num += num3;
                    }
                    if (array2 != null)
                    {
                        Buffer.BlockCopy(array2, 0, RawSerializer.mRawData, num, array2.Length);
                        num += array2.Length;
                    }
                }
            }
            writtenLength = num - rawDataBaseIndex;
            return(writtenLength > 0);
        }
 private static bool EqualFields(RawSerializer.OwnerFieldPair left, RawSerializer.OwnerFieldPair right)
 {
     if (left.field != null && right.field != null)
     {
         if (!object.Equals(left.field, right.field))
         {
             return(false);
         }
     }
     else
     {
         Type        type    = left.owner.GetType();
         Type        type2   = right.owner.GetType();
         FieldInfo[] fields  = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
         FieldInfo[] fields2 = type2.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
         for (int i = 0; i < fields.Length; i++)
         {
             FieldInfo fieldInfo  = fields[i];
             FieldInfo fieldInfo2 = fields2[i];
             if (fieldInfo == null || fieldInfo2 == null)
             {
                 return(false);
             }
             if (!RawSerializer.IsIngoreField(fieldInfo))
             {
                 if (fieldInfo.FieldType.IsArray)
                 {
                     Array array  = fieldInfo.GetValue(left.owner) as Array;
                     Array array2 = fieldInfo2.GetValue(right.owner) as Array;
                     int   num    = Math.Min(array.Length, array2.Length);
                     for (int j = 0; j < num; j++)
                     {
                         RawSerializer.OwnerFieldPair left2  = new RawSerializer.OwnerFieldPair(left.owner, array.GetValue(j));
                         RawSerializer.OwnerFieldPair right2 = new RawSerializer.OwnerFieldPair(right.owner, array2.GetValue(j));
                         if (!RawSerializer.EqualFields(left2, right2))
                         {
                             return(false);
                         }
                     }
                 }
                 else
                 {
                     object value  = fieldInfo.GetValue(left.owner);
                     object value2 = fieldInfo2.GetValue(right.owner);
                     RawSerializer.OwnerFieldPair left3;
                     RawSerializer.OwnerFieldPair right3;
                     if (type.IsPrimitive || type == typeof(string))
                     {
                         left3  = new RawSerializer.OwnerFieldPair(left.owner, value);
                         right3 = new RawSerializer.OwnerFieldPair(right.owner, value2);
                     }
                     else
                     {
                         left3  = new RawSerializer.OwnerFieldPair(value, null);
                         right3 = new RawSerializer.OwnerFieldPair(value2, null);
                     }
                     if (!RawSerializer.EqualFields(left3, right3))
                     {
                         return(false);
                     }
                 }
             }
         }
     }
     return(true);
 }