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");
                    }
                    Value = Encoding.GetString(Bffr);
                    break;
                }
                throw new Exception("String Attribute Not Specified.");

            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);
            }
            return(Value);
        }
        public string ReadString(StringStyle Style, FieldInfo Info = null)
        {
            List <byte> Buffer = new List <byte>();

            switch (Style)
            {
            case StringStyle.CString:
                while (true)
                {
                    byte Byte = base.ReadByte();
                    if (Byte < 1)
                    {
                        break;
                    }
                    Buffer.Add(Byte);
                }
                return(Encoding.GetString(Buffer.ToArray()));

            case StringStyle.UCString:
                while (true)
                {
                    byte Byte1 = base.ReadByte();
                    byte Byte2 = base.ReadByte();
                    if (Byte1 == 0x00 && Byte2 == 0x00)
                    {
                        break;
                    }
                    Buffer.Add(Byte1);
                    Buffer.Add(Byte2);
                }
                return(Encoding.GetString(Buffer.ToArray()));

            case StringStyle.PString:
                if (Info != null)
                {
                    long   Len;
                    string Prefix        = Tools.GetAttributePropertyValue(Info, Const.PSTRING, "PrefixType");
                    bool   UnicodeLength = Tools.GetAttributePropertyValue(Info, Const.PSTRING, "UnicodeLength");
                    switch (Prefix)
                    {
                    case Const.INT16:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadInt16());
                        }
                        else
                        {
                            Len = ReadInt16();
                        }
                        break;

                    case Const.UINT16:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadUInt16());
                        }
                        else
                        {
                            Len = ReadUInt16();
                        }
                        break;

                    case Const.UINT8:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadByte());
                        }
                        else
                        {
                            Len = ReadByte();
                        }
                        break;

                    case Const.INT8:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadSByte());
                        }
                        else
                        {
                            Len = ReadSByte();
                        }
                        break;

                    case Const.INT32:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadInt32());
                        }
                        else
                        {
                            Len = ReadInt32();
                        }
                        break;

                    case Const.UINT32:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadUInt32());
                        }
                        else
                        {
                            Len = ReadUInt32();
                        }
                        break;

                    case Const.INT64:
                        if (BigEndian)
                        {
                            Len = Tools.Reverse(ReadInt64());
                        }
                        else
                        {
                            Len = ReadInt64();
                        }
                        break;

                    default:
                        throw new Exception("Invalid Data Type");
                    }
                    if (UnicodeLength)
                    {
                        Len *= 2;
                    }
                    if (Len > BaseStream.Length - BaseStream.Position)
                    {
                        throw new Exception("Invalid Length");
                    }
                    byte[] Buff = new byte[Len];
                    while (Len > 0)
                    {
                        Len -= BaseStream.Read(Buff, 0, Len > int.MaxValue ? int.MaxValue : (int)Len);
                    }
                    return(Encoding.GetString(Buff));
                }
                else
                {
                    return(ReadString());
                }

            default:
                throw new Exception("Unk Value Type");
            }
        }
        internal void WritePString(FieldInfo Field, dynamic Value)
        {
            byte[] Arr = Encoding.GetBytes(Value);

            string Prefix        = Tools.GetAttributePropertyValue(Field, Const.PSTRING, "PrefixType");
            bool   UnicodeLength = Tools.GetAttributePropertyValue(Field, Const.PSTRING, "UnicodeLength");


            long Length = Arr.LongLength;

            if (UnicodeLength)
            {
                Length /= 2;
            }

            switch (Prefix)
            {
            case Const.INT16:
                if (BigEndian)
                {
                    base.Write((short)Tools.Reverse((short)Length));
                }
                else
                {
                    base.Write((short)Length);
                }
                break;

            case Const.UINT16:
                if (BigEndian)
                {
                    base.Write((ushort)Tools.Reverse((ushort)Length));
                }
                else
                {
                    base.Write((ushort)Length);
                }
                break;

            case Const.UINT8:
                if (BigEndian)
                {
                    base.Write((byte)Tools.Reverse((byte)Length));
                }
                else
                {
                    base.Write((byte)Length);
                }
                break;

            case Const.INT8:
                if (BigEndian)
                {
                    base.Write((sbyte)Tools.Reverse((sbyte)Length));
                }
                else
                {
                    base.Write((sbyte)Length);
                }
                break;

            case Const.INT32:
                if (BigEndian)
                {
                    base.Write((int)Tools.Reverse((int)Length));
                }
                else
                {
                    base.Write((int)Length);
                }
                break;

            case Const.UINT32:
                if (BigEndian)
                {
                    base.Write((uint)Tools.Reverse((uint)Length));
                }
                else
                {
                    base.Write((uint)Length);
                }
                break;

            case Const.INT64:
                if (BigEndian)
                {
                    base.Write((long)Tools.Reverse(Length));
                }
                else
                {
                    base.Write(Length);
                }
                break;

            default:
                throw new Exception("Invalid Data Type");
            }
            base.Write(Arr);
        }