internal void ReadStruct(Type type, ref object Instance)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo field = fields[i];
                if (Tools.HasAttribute(field, Const.IGNORE))
                {
                    continue;
                }

                string  FType = field.FieldType.ToString();
                dynamic Value = null;

                if (!FType.EndsWith("[]"))
                {
                    Value = ReadField(FType, field, ref Instance);
                }
                else
                {
                    if (Tools.HasAttribute(field, Const.FARRAY))
                    {
                        byte[] Buffer = new byte[Tools.GetAttributePropertyValue(field, Const.FARRAY, "Length")];

                        if (Read(Buffer, 0, Buffer.Length) != Buffer.Length)
                        {
                            throw new Exception("Failed to Read");
                        }

                        Value = Buffer;
                    }
                    else if (Tools.HasAttribute(field, Const.PARRAY))
                    {
                        FType = FType.Substring(0, FType.Length - 2);

                        string  PType = Tools.GetAttributePropertyValue(field, Const.PARRAY, "PrefixType");
                        dynamic Count = ReadField(PType, field, ref Instance);


                        object[] Content = new object[Count];
                        for (long x = 0; x < Count; x++)
                        {
                            Content[x] = ReadField(FType, field, ref Instance);
                        }


                        Value = Array.CreateInstance(Type.GetType(FType), Count);
                        Content.CopyTo(Value, 0);
                    }
                    else
                    {
                        throw new Exception("Bad Struct Configuration");
                    }
                }

                field.SetValue(Instance, Value);
            }
        }
        internal void ReadStruct(Type type, ref object Instance)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo field = fields[i];
                if (Tools.HasAttribute(field, Const.IGNORE))
                {
                    continue;
                }

                string  FType = field.FieldType.ToString();
                dynamic Value = null;

                if (!FType.EndsWith("[]"))
                {
                    Value = ReadField(FType, field, ref Instance);
                }
                else
                {
                    dynamic Count = null;
                    if (Tools.HasAttribute(field, Const.FARRAY))
                    {
                        Count = Tools.GetAttributePropertyValue(field, Const.FARRAY, "Length");
                    }
                    else if (Tools.HasAttribute(field, Const.PARRAY))
                    {
                        string PType = Tools.GetAttributePropertyValue(field, Const.PARRAY, "PrefixType");
                        Count = ReadField(PType, field, ref Instance);
                    }
                    else if (Tools.HasAttribute(field, Const.RARRAY))
                    {
                        string    PFieldName  = Tools.GetAttributePropertyValue(field, Const.RARRAY, "FieldName");
                        FieldInfo PrefixField = (from x in fields where x.Name == PFieldName select x).First();
                        Count = PrefixField.GetValue(Instance);
                    }
                    else
                    {
                        throw new Exception("Bad Struct Array Configuration");
                    }

                    FType = FType.Substring(0, FType.Length - 2);

                    object[] Content = new object[Count];
                    for (long x = 0; x < Count; x++)
                    {
                        Content[x] = ReadField(FType, field, ref Instance);
                    }


                    Value = Array.CreateInstance(Type.GetType(FType), Count);
                    Content.CopyTo(Value, 0);
                }

                field.SetValue(Instance, Value);
            }
        }
        public void ReadStruct(Type type, ref object Result)
        {
            // Result = Activator.CreateInstance(type);
            FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (FieldInfo field in fields)
            {
                if (Tools.HasAttribute(field, Const.IGNORE))
                {
                    break;
                }
                object Value = null;
                switch (field.FieldType.ToString())
                {
                case Const.INT8:
                    Value = base.ReadByte();
                    break;

                case Const.UINT8:
                    Value = base.ReadSByte();
                    break;

                case Const.INT32:
                    Value = base.ReadInt32();
                    break;

                case Const.UINT32:
                    Value = base.ReadUInt32();
                    break;

                case Const.DOUBLE:
                    Value = base.ReadDouble();
                    break;

                case Const.FLOAT:
                    Value = base.ReadSingle();
                    break;

                case Const.INT64:
                    Value = base.ReadInt64();
                    break;

                case Const.UINT64:
                    Value = base.ReadUInt64();
                    break;

                case Const.STRING:
                    if (Tools.HasAttribute(field, Const.CSTRING) && Tools.HasAttribute(field, Const.PSTRING))
                    {
                        throw new Exception("You can't use CString and PString Attribute into the same field.");
                    }
                    if (Tools.HasAttribute(field, Const.CSTRING))
                    {
                        Value = ReadString(StringStyle.CString);
                        break;
                    }
                    if (Tools.HasAttribute(field, Const.UCSTRING))
                    {
                        Value = ReadString(StringStyle.UCString);
                        break;
                    }
                    if (Tools.HasAttribute(field, Const.PSTRING))
                    {
                        Value = ReadString(StringStyle.PString);
                        break;
                    }
                    throw new Exception("String Attribute Not Specified.");

                default:
                    if (Tools.HasAttribute(field, Const.STRUCT))
                    {
                        Value = Activator.CreateInstance(field.FieldType);
                        ReadStruct(field.FieldType, ref Value);
                    }
                    else
                    {
                        if (field.FieldType.BaseType.ToString() == Const.DELEGATE)
                        {
                            FieldInvoke Invoker = (FieldInvoke)field.GetValue(Result);
                            Value = Invoker;
                            if (Invoker == null)
                            {
                                break;
                            }
                            Result = Invoker.Invoke(BaseStream, true, Result);
                            break;
                        }
                        throw new Exception("Unk Struct Field: " + field.FieldType.ToString());
                    }
                    break;
                }
                field.SetValue(Result, Value);
            }
        }
        private void ReadStruct(Type type, ref object Instance)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo field = fields[i];
                if (Tools.HasAttribute(field, Const.IGNORE))
                {
                    continue;
                }
                dynamic Value    = null;
                bool    IsNumber = true;
                switch (field.FieldType.ToString())
                {
                case Const.INT8:
                    Value = base.ReadSByte();
                    break;

                case Const.INT16:
                    Value = base.ReadInt16();
                    break;

                case Const.UINT16:
                    Value = base.ReadUInt16();
                    break;

                case Const.UINT8:
                    Value = base.ReadByte();
                    break;

                case Const.INT32:
                    Value = base.ReadInt32();
                    break;

                case Const.UINT32:
                    Value = base.ReadUInt32();
                    break;

                case Const.DOUBLE:
                    Value = base.ReadDouble();
                    break;

                case Const.FLOAT:
                    Value = base.ReadSingle();
                    break;

                case Const.INT64:
                    Value = base.ReadInt64();
                    break;

                case Const.UINT64:
                    Value = base.ReadUInt64();
                    break;

                case Const.STRING:
                    IsNumber = false;
                    if (Tools.HasAttribute(field, Const.CSTRING) && Tools.HasAttribute(field, Const.PSTRING))
                    {
                        throw new Exception("You can't use CString and PString Attribute into the same field.");
                    }
                    if (Tools.HasAttribute(field, Const.CSTRING))
                    {
                        Value = ReadString(StringStyle.CString);
                        break;
                    }
                    if (Tools.HasAttribute(field, Const.UCSTRING))
                    {
                        Value = ReadString(StringStyle.UCString);
                        break;
                    }
                    if (Tools.HasAttribute(field, Const.PSTRING))
                    {
                        Value = ReadString(StringStyle.PString, field);
                        break;
                    }
                    if (Tools.HasAttribute(field, Const.FSTRING))
                    {
                        byte[] Bffr = new byte[Tools.GetAttributePropertyValue(field, Const.FSTRING, "Length")];
                        if (Read(Bffr, 0, Bffr.Length) != Bffr.Length)
                        {
                            throw new Exception("Failed to Read a String");
                        }
                        Value = Encoding.GetString(Bffr);
                        break;
                    }
                    throw new Exception("String Attribute Not Specified.");

                case Const.BYTEARR:
                    byte[] Buffer = new byte[Tools.GetAttributePropertyValue(field, Const.ArrSize, "Length")];
                    if (Read(Buffer, 0, Buffer.Length) != Buffer.Length)
                    {
                        throw new Exception("Failed to Read");
                    }
                    Value = Buffer;
                    break;

                default:
                    IsNumber = false;
                    if (Tools.HasAttribute(field, Const.STRUCT))
                    {
                        Value = Activator.CreateInstance(field.FieldType);
                        ReadStruct(field.FieldType, ref Value);
                    }
                    else
                    {
                        if (field.FieldType.BaseType.ToString() == Const.DELEGATE)
                        {
                            FieldInvoke Invoker = (FieldInvoke)field.GetValue(Instance);
                            Value = Invoker;
                            if (Invoker == null)
                            {
                                break;
                            }
                            Instance = Invoker.Invoke(BaseStream, true, Instance);
                            break;
                        }
                        throw new Exception("Unk Struct Field: " + field.FieldType.ToString());
                    }
                    break;
                }
                if (IsNumber && BigEndian)
                {
                    Value = Tools.Reverse(Value);
                }
                field.SetValue(Instance, Value);
            }
        }
        internal dynamic ReadField(string Type, FieldInfo field, ref object Instance)
        {
            bool    IsNumber = true;
            dynamic Value    = null;

            switch (Type)
            {
            case Const.INT8:
                Value = base.ReadSByte();
                break;

            case Const.INT16:
                Value = base.ReadInt16();
                break;

            case Const.CHAR:
                Value = base.ReadChar();
                break;

            case Const.UINT16:
                Value = base.ReadUInt16();
                break;

            case Const.UINT8:
                Value = base.ReadByte();
                break;

            case Const.INT32:
                Value = base.ReadInt32();
                break;

            case Const.UINT32:
                Value = base.ReadUInt32();
                break;

            case Const.DOUBLE:
                Value = base.ReadDouble();
                break;

            case Const.FLOAT:
                Value = base.ReadSingle();
                break;

            case Const.INT64:
                Value = base.ReadInt64();
                break;

            case Const.UINT64:
                Value = base.ReadUInt64();
                break;

            case Const.STRING:
                IsNumber = false;
                if (Tools.HasAttribute(field, Const.CSTRING) && Tools.HasAttribute(field, Const.PSTRING))
                {
                    throw new Exception("You can't use CString and PString Attribute into the same field.");
                }
                if (Tools.HasAttribute(field, Const.CSTRING))
                {
                    Value = ReadString(StringStyle.CString);
                    break;
                }
                if (Tools.HasAttribute(field, Const.UCSTRING))
                {
                    Value = ReadString(StringStyle.UCString);
                    break;
                }
                if (Tools.HasAttribute(field, Const.PSTRING))
                {
                    Value = ReadString(StringStyle.PString, field);
                    break;
                }
                if (Tools.HasAttribute(field, Const.FSTRING))
                {
                    byte[] Bffr = new byte[Tools.GetAttributePropertyValue(field, Const.FSTRING, "Length")];
                    if (Read(Bffr, 0, Bffr.Length) != Bffr.Length)
                    {
                        throw new Exception("Failed to Read a String");
                    }
                    bool TrimEnd = Tools.GetAttributePropertyValue(field, Const.FSTRING, "TrimNull");
                    Value = TrimEnd ? Encoding.GetString(Bffr).TrimEnd('\x0') : Encoding.GetString(Bffr);
                    break;
                }
                throw new Exception("String Attribute Not Specified.");

            default:
                IsNumber = false;
                if (Tools.HasAttribute(field, Const.STRUCT))
                {
                    Type FieldType = System.Type.GetType(Type);
                    Value = Activator.CreateInstance(FieldType);
                    ReadStruct(FieldType, ref Value);
                }
                else
                {
                    if (field.FieldType.BaseType.ToString() == Const.DELEGATE)
                    {
                        FieldInvoke Invoker = (FieldInvoke)field.GetValue(Instance);
                        Value = Invoker;
                        if (Invoker == null)
                        {
                            break;
                        }
                        Instance = Invoker.Invoke(BaseStream, true, Instance);
                        break;
                    }
                    throw new Exception("Unk Struct Field: " + field.FieldType.ToString());
                }
                break;
            }
            if (IsNumber && BigEndian)
            {
                Value = Tools.Reverse(Value);
            }
            return(Value);
        }