예제 #1
0
        public static void ReadFormat(FormatToken.Format f, TdsResponseStream stream)
        {
            var t = _types[f.Type];

            if (t.FormatFormat == FormatFormat.LenOneByte || t.FormatFormat == FormatFormat.Decimal)
            {
                f.Len = stream.Read();
            }

            if (t.FormatFormat == FormatFormat.LenFourBytes || t.FormatFormat == FormatFormat.Image)
            {
                f.Len = stream.ReadInt();
            }

            if (t.FormatFormat == FormatFormat.Image)
            {
                int nameLen = stream.ReadShort();
                f.ObjectName = stream.ReadString(nameLen);
            }

            if (t.FormatFormat == FormatFormat.Decimal)
            {
                f.Pecision = stream.Read();
                f.Scale    = stream.Read();
            }

            int localLen = stream.Read();

            f.LocaleInfo = stream.ReadString(localLen);

            // todo: blob
        }
예제 #2
0
        private static object GetDecimalValue(TdsResponseStream stream, TdsType type, FormatToken.Format f)
        {
            int len = stream.Read();

            if (len > 0)
            {
                var scale = Math.Pow(10, f.Scale ?? 0);

                bool sign  = stream.Read() != 0;
                var  bytes = stream.ReadBytes(len - 1);
                var  bi    = new BigInteger(bytes.Reverse().ToArray());

                var d = (decimal)bi;
                if (sign)
                {
                    d = -d;
                }

                return(d / (decimal)scale);
            }
            else
            {
                return(null);
            }
        }
예제 #3
0
        public TdsToken ReadToken(TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            var tokenType = (TokenType)stream.Read();

            TdsToken        token = null;
            TokenDescriptor desc;

            if (_tokenDescriptors.TryGetValue(tokenType, out desc))
            {
                if (desc.Builder == null)
                {
                    token = CreateNotImplementedToken(desc, stream);
                }
                else
                {
                    //_logger?.LogTrace($"Building token of type {tokenType}");
                    token = desc.Builder(desc, stream, encoder, lastFormat);
                    _logger?.LogTrace(token.ToString());
                }
            }
            else
            {
                _logger?.LogError($"Unknown token of type {tokenType}");
                throw new Exception($"Unknown token of type {tokenType}");
            }

            return(token);
        }
예제 #4
0
        private static object GetMoneyValue(TdsResponseStream stream, TdsType type)
        {
            int len;

            if (type == TdsType.TDS_MONEY)
            {
                len = 8;
            }
            else if (type == TdsType.TDS_MONEYN)
            {
                len = stream.Read();
            }
            else
            {
                len = 4;
            }

            long?x = null;

            if (len == 4)
            {
                x = stream.ReadInt();
            }
            else if (len == 8)
            {
                int hi = stream.ReadInt();
                int lo = stream.ReadInt();
                x = lo | (hi << 32);
            }

            return(x.HasValue ? new decimal(x.Value) * 0.0001m : (decimal?)null);
        }
예제 #5
0
        private TdsToken CreateEnvChange(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len  = stream.ReadShort();
            int read = 0;

            var changes = new List <EnvChangeToken.Change>();

            while (read < len)
            {
                var change = new EnvChangeToken.Change();
                change.Type = (EnvChangeToken.EnvType)stream.Read();
                int newValLen = stream.Read();
                change.NewValue = stream.ReadString(newValLen);
                int oldValLen = stream.Read();
                change.OldValue = stream.ReadString(oldValLen);
                read           += 3 + newValLen + oldValLen;

                changes.Add(change);
            }

            return(new EnvChangeToken(tokenDesc.TokenType)
            {
                Changes = changes
            });
        }
예제 #6
0
        private TdsToken CreateReturnStatus(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int value = stream.ReadInt();

            return(new ReturnStatusToken(tokenDesc.TokenType)
            {
                Value = value,
            });
        }
예제 #7
0
        private TdsToken CreateNotImplementedToken(TokenDescriptor tokenDesc, TdsResponseStream stream)
        {
            int len = 0;

            switch (tokenDesc.Len)
            {
            case TokenLength.OneByteLen:
                len = stream.Read();
                stream.SkipRead(len);
                len += 1;
                break;

            case TokenLength.TwoByteLen:
                len = stream.ReadShort();
                stream.SkipRead(len);
                len += 2;
                break;

            case TokenLength.FourByteLen:
                len = stream.ReadInt();
                stream.SkipRead(len);
                len += 4;
                break;

            case TokenLength.OneByte:
                len = 1;
                stream.SkipRead(len);
                break;

            case TokenLength.FourBytes:
                len = 4;
                stream.SkipRead(len);
                break;

            case TokenLength.EigthBytes:
                len = 8;
                stream.SkipRead(len);
                break;

            case TokenLength.Dependent:
            default:
                _logger?.LogError($"Unknown length of token of type {tokenDesc.TokenType}");
                throw new Exception($"Unknown length of token of type {tokenDesc.TokenType}");
            }

            _logger?.LogWarning($"Not implemented token {tokenDesc.TokenType} of len {len}");
            return(new UnknownToken(tokenDesc.TokenType, len));
        }
예제 #8
0
        private TdsToken CreateLoginAck(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len         = stream.ReadShort();
            int status      = stream.Read();
            var version     = stream.ReadBytes(4);
            int nameLen     = stream.Read();
            var name        = stream.ReadString(nameLen);
            var progVersion = stream.ReadBytes(4);

            return(new LoginAckToken(tokenDesc.TokenType)
            {
                Succeed = status == 5,
                Fail = status == 6,
                Negotiate = status == 7,
                TdsVersion = $"{version[0]}.{version[1]}.{version[2]}.{version[3]}",
                ServerProgram = name,
                ServerVersion = $"{progVersion[0]}.{progVersion[1]}.{progVersion[2]}.{progVersion[3]}",
            });
        }
예제 #9
0
        private TdsToken CreateData(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            if (lastFormat == null)
            {
                _logger?.LogError($"Format for {tokenDesc.TokenType} not found");
                throw new Exception($"Format for {tokenDesc.TokenType} not found");
            }

            var data = new List <object>();

            foreach (var f in lastFormat.Formats)
            {
                data.Add(TypeReader.ReadData(f, stream, encoder));
            }

            return(new DataToken(tokenDesc.TokenType)
            {
                Data = data,
            });
        }
예제 #10
0
        private TdsToken CreateCapabiltiy(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len = stream.ReadShort();

            if (stream.Read() != 1)
            {
                throw new Exception("TDS_CAPABILITY: expected request string");
            }
            int capReqLen = stream.Read();

            if (capReqLen != 11 && capReqLen != 0)
            {
                throw new Exception("TDS_CAPABILITY: byte count not 11");
            }

            byte[] capRequest = new byte[11];
            if (capReqLen != 0)
            {
                stream.Read(capRequest, 0, 11);
            }

            if (stream.Read() != 2)
            {
                throw new Exception("TDS_CAPABILITY: expected response string");
            }

            int capResLen = stream.Read();

            if (capResLen != 10 && capResLen != 0)
            {
                throw new Exception("TDS_CAPABILITY: byte count not 10");
            }

            byte[] capResponse = new byte[10];
            if (capResLen != 0)
            {
                stream.Read(capResponse, 0, 10);
            }

            return(new CapabiltiyToken(tokenDesc.TokenType, capRequest, capResponse));
        }
예제 #11
0
        private TdsToken CreateDone(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int status    = stream.ReadShort();
            int tranState = stream.ReadShort();
            int count     = stream.ReadInt();

            return(new DoneToken(tokenDesc.TokenType)
            {
                More = (status & 1) != 0,
                Error = (status & 2) != 0,
                InTransaction = (status & 4) != 0,
                Proc = (status & 8) != 0,
                Count = (status & 16) != 0,
                AttentionAck = (status & 32) != 0,
                //Event = (status & 64) != 0,

                TransactionState = (DoneToken.TransactionStatus)tranState,

                RowCount = (status & 16) != 0 ? count : (int?)null,
            });
        }
예제 #12
0
        private TdsToken CreateControl(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len  = stream.ReadShort();
            int read = 0;

            var formats = new List <string>();

            while (read < len)
            {
                int formatLen = stream.Read();
                var format    = stream.ReadString(formatLen);
                read += 1 + formatLen;

                formats.Add(format);
            }

            return(new ControlToken(tokenDesc.TokenType)
            {
                Formats = formats
            });
        }
예제 #13
0
        public void Connect()
        {
            System.Net.IPEndPoint endPoint;
            if (System.Net.IPAddress.TryParse(_paramaters.ServerAddress, out var ipadr))
            {
                endPoint = new System.Net.IPEndPoint(ipadr, _paramaters.ServerPort);
            }
            else
            {
                var ip = System.Net.Dns.GetHostEntryAsync(_paramaters.ServerAddress).GetAwaiter().GetResult();
                endPoint = new System.Net.IPEndPoint(
                    ip.AddressList.OrderByDescending(a => a.AddressFamily == AddressFamily.InterNetwork).First(),
                    _paramaters.ServerPort);
            }

            _logger?.LogDebug($"Connecting to {_paramaters.ServerAddress} -> {endPoint}");
            _socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.IP);
            _socket.Connect(endPoint);

            _req = new TdsRequestStream(_socket, this, _loggerFactory?.CreateLogger <TdsRequestStream>());
            _res = new TdsResponseStream(_socket, this, _loggerFactory?.CreateLogger <TdsResponseStream>());
        }
예제 #14
0
        private static object GetDatetimeValue(TdsResponseStream stream, TdsType type)
        {
            int len;
            int dayTicks;
            int timeTicks;
            int minutes;

            if (type == TdsType.TDS_DATETIMEN)
            {
                len = stream.Read();
            }
            else if (type == TdsType.TDS_SHORTDATE)
            {
                len = 4;
            }
            else
            {
                len = 8;
            }

            switch (len)
            {
            case 8:
                dayTicks  = stream.ReadInt();
                timeTicks = stream.ReadInt();
                return(new System.Data.SqlTypes.SqlDateTime(dayTicks, timeTicks).Value);

            case 4:
                dayTicks = stream.ReadShort();
                minutes  = stream.ReadShort();
                return(new DateTime(1900, 1, 1).AddDays(dayTicks).AddMinutes(minutes));

            default:
            case 0:
                return(null);
            }
        }
예제 #15
0
        private TdsToken CreateTextMessage(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len       = stream.ReadShort();
            int msgNumber = stream.ReadInt();
            int state     = stream.Read();
            int severity  = stream.Read();

            int sqlStatusLen = stream.Read();
            var sqlStatus    = stream.ReadBytes(sqlStatusLen);

            int status    = stream.Read();
            int tranState = stream.ReadShort(); // discarded

            int msgLen = stream.ReadShort();
            var msg    = stream.ReadString(msgLen);

            int srvNameLen = stream.Read();
            var serverName = stream.ReadString(srvNameLen);

            int procNameLen = stream.Read();
            var procName    = stream.ReadString(procNameLen);

            int lineNumber = stream.ReadShort();

            return(new TextMessageToken(tokenDesc.TokenType)
            {
                MessageNumber = msgNumber,
                State = state,
                Severity = severity,
                ParamsFollows = status == 1,
                Message = msg,
                ServerName = serverName,
                ProcName = procName,
                LineNumber = lineNumber,
            });
        }
예제 #16
0
        public static object ReadData(FormatToken.Format f, TdsResponseStream stream, Encoding encoder)
        {
            int len;

            switch (f.Type)
            {
            case TdsType.TDS_INTN:
            case TdsType.TDS_UINTN:     // lets ignore unsigned for now
                switch (stream.Read())
                {
                case 1:
                    return(stream.Read());

                case 2:
                    return(stream.ReadShort());

                case 4:
                    return(stream.ReadInt());

                case 8:
                    return(stream.ReadLong());
                }
                break;

            case TdsType.TDS_INT1:
            case TdsType.TDS_UINT1:
                return(stream.Read());

            case TdsType.TDS_INT2:
            case TdsType.TDS_UINT2:
                return(stream.ReadShort());

            case TdsType.TDS_INT4:
            case TdsType.TDS_UINT4:
                return(stream.ReadInt());

            case TdsType.TDS_INT8:
            case TdsType.TDS_UINT8:
                return(stream.ReadLong());

            case TdsType.TDS_BIT:
                return(stream.Read() != 0);

            case TdsType.TDS_DATETIMEN:
            case TdsType.TDS_DATETIME:
            case TdsType.TDS_SHORTDATE:
                return(GetDatetimeValue(stream, f.Type));

            case TdsType.TDS_FLT4:
                return(BitConverter.Int32BitsToSingle(stream.ReadInt()));

            case TdsType.TDS_FLT8:
                return(BitConverter.Int64BitsToDouble(stream.ReadLong()));

            case TdsType.TDS_FLTN:
                len = stream.Read();

                if (len == 4)
                {
                    return(BitConverter.Int32BitsToSingle(stream.ReadInt()));
                }
                else if (len == 8)
                {
                    return(BitConverter.Int64BitsToDouble(stream.ReadLong()));
                }

                break;

            case TdsType.TDS_SHORTMONEY:
            case TdsType.TDS_MONEY:
            case TdsType.TDS_MONEYN:
                return(GetMoneyValue(stream, f.Type));

            case TdsType.TDS_DECN:
            case TdsType.TDS_NUMN:
                return(GetDecimalValue(stream, f.Type, f));

            case TdsType.TDS_LONGBINARY:
                len = stream.ReadInt();
                return(stream.ReadBytes(len));

            case TdsType.TDS_LONGCHAR:
                len = stream.ReadInt();
                if (len > 0)
                {
                    return(encoder.GetString(stream.ReadBytes(len)));
                }
                break;

            case TdsType.TDS_IMAGE:
                len = stream.Read();
                if (len > 0)
                {
                    var txtPtr    = stream.ReadBytes(len);
                    var timeStamp = stream.ReadBytes(8);
                    int dataLen   = stream.ReadInt();
                    return(stream.ReadBytes(dataLen));
                }
                break;

            case TdsType.TDS_TEXT:
                len = stream.Read();
                if (len > 0)
                {
                    var txtPtr    = stream.ReadBytes(len);
                    var timeStamp = stream.ReadBytes(8);
                    int dataLen   = stream.ReadInt();
                    return(encoder.GetString(stream.ReadBytes(dataLen)));
                }
                break;

            case TdsType.TDS_CHAR:
            case TdsType.TDS_VARCHAR:
                len = stream.Read();
                if (len > 0)
                {
                    return(encoder.GetString(stream.ReadBytes(len)));
                }
                break;

            case TdsType.TDS_BINARY:
            case TdsType.TDS_VARBINARY:
            case TdsType.TDS_BOUNDARY:
            case TdsType.TDS_SENSITIVITY:
                len = stream.Read();
                return(stream.ReadBytes(len));

            case TdsType.TDS_VOID:
            case TdsType.TDS_BLOB:
            default:
                throw new NotImplementedException();
            }

            return(null);
        }
예제 #17
0
        private TdsToken CreateFormat(TokenDescriptor tokenDesc, TdsResponseStream stream, Encoding encoder, FormatToken lastFormat)
        {
            int len;

            if (tokenDesc.Len == TokenLength.FourByteLen)
            {
                len = stream.ReadInt();
            }
            else
            {
                len = stream.ReadShort();
            }

            int numFormats = stream.ReadShort();

            var formats = new List <FormatToken.Format>();

            for (int i = 0; i < numFormats; i++)
            {
                var f = new FormatToken.Format
                {
                    Params = tokenDesc.TokenType == TokenType.TDS_PARAMFMT || tokenDesc.TokenType == TokenType.TDS_PARAMFMT2,
                };

                int nameLen = stream.Read();
                f.Name = stream.ReadString(nameLen);

                if (tokenDesc.TokenType == TokenType.TDS_ROWFMT2)
                {
                    int catalogNameLen = stream.Read();
                    f.CatalogName = stream.ReadString(catalogNameLen);
                    int schemaNameLen = stream.Read();
                    f.SchemaName = stream.ReadString(schemaNameLen);
                    int tableNameLen = stream.Read();
                    f.TableName = stream.ReadString(tableNameLen);
                    int columnNameLen = stream.Read();
                    f.ColumnName = stream.ReadString(columnNameLen);
                }

                if (tokenDesc.Len == TokenLength.FourByteLen)
                {
                    f.Status = stream.ReadInt();
                }
                else
                {
                    f.Status = stream.Read();
                }

                f.UserType = (UserDataType)stream.ReadInt();
                f.Type     = (TdsType)stream.Read();

                TypeReader.ReadFormat(f, stream);

                formats.Add(f);
            }

            return(new FormatToken(tokenDesc.TokenType)
            {
                Formats = formats,
            });
        }