Пример #1
0
        /// <summary>
        /// Ensures that the current packet has at least a single spare byte
        /// </summary>
        /// <param name="type">Type of the packet to look for</param>
        private void _EnsureOutgoingPacketHasSpace()
        {
            // Check if we have a packet
            if (OutgoingPacketHeader == null)
            {
                // Message must be started before we can ensure packet availability
                throw new InvalidOperationException("Message has not been started");
            }

            // Check if last packet has no space in it
            if (OutgoingPacketHeader.Length >= PacketSize)
            {
                // Save outgoing packet type before sending it, which will reset the packet header
                TDSMessageType outgoingPacketType = OutgoingPacketHeader.Type;

                // Save outgoing packet number
                byte packetID = OutgoingPacketHeader.PacketID;

                // Before allocating a new packet we need to serialize the current packet
                _SendCurrentPacket();

                // Allocate a new packet since the last packet is full
                _CreateOutgoingPacket(outgoingPacketType, (byte)(((int)packetID + 1) % 256));
            }
        }
Пример #2
0
 public TDSPacketHeader(TDSMessageType type, TDSMessageStatus status, ushort spid = 0x0000, byte packet = 0x00, byte window = 0x00)
 {
     Type   = type;
     Status = status;
     SPID   = spid;
     Packet = packet;
     Window = window;
 }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TDSPacketHeader" /> class.
 /// </summary>
 /// <param name="type">TDS Message Type</param>
 /// <param name="status">TDS Message Status</param>
 /// <param name="spid">SPID number</param>
 /// <param name="packet">Packet number</param>
 /// <param name="window">Window number</param>
 public TDSPacketHeader(TDSMessageType type, TDSMessageStatus status, ushort spid = 0x0000, byte packet = 0x00, byte window = 0x00)
 {
     this.Type   = type;
     this.Status = status;
     this.SPID   = spid;
     this.Packet = packet;
     this.Window = window;
 }
Пример #4
0
        /// <summary>
        /// Start a new message
        /// </summary>
        /// <param name="type">Type of the message to start</param>
        public virtual void StartMessage(TDSMessageType type)
        {
            // Flush current packet if available
            _SendCurrentPacket();

            // Create a new packet of the specified type
            _CreateOutgoingPacket(type, 1);
        }
 public TDSInvalidMessageException(string message,
                                   TDSMessageType type,
                                   byte[] payload,
                                   Exception innerException = null) : base(message, innerException)
 {
     MessageType = type;
     Payload     = new byte[payload.Length];
     Buffer.BlockCopy(payload, 0, Payload, 0, payload.Length);
 }
Пример #6
0
        /// <summary>
        /// Create a new TDS packet in the message
        /// </summary>
        private void _CreateOutgoingPacket(TDSMessageType type, byte packetID)
        {
            // Allocate an outgoing packet in case it isn't available
            _AllocateOutgoingPacket();

            // Allocate a new packet with the specified type and normal status
            OutgoingPacketHeader = new TDSPacketHeader(_outgoingPacket, type, TDSPacketStatus.Normal);

            // Assign session identifier to the packet
            OutgoingPacketHeader.SPID = OutgoingSessionID;

            // Increment packet identifier
            OutgoingPacketHeader.PacketID = packetID;
        }
Пример #7
0
        public static async Task <IEnumerable <TDSPacket> > ReadAsync(TDSMessageType type, Stream stream, CancellationToken cancellationToken)
        {
            List <TDSPacket> packets = new List <TDSPacket>();
            TDSPacket        lastPacket;
            bool             notFirstPacket = false;

            do
            {
                lastPacket = await ReadSinglePacketAsync(type, stream, notFirstPacket, cancellationToken).ConfigureAwait(false);

                packets.Add(lastPacket);
                notFirstPacket = true;
            }while ((lastPacket.Status & TDSStatus.EndOfMessage) != TDSStatus.EndOfMessage);

            return(packets);
        }
Пример #8
0
        public static async Task <TDSPacket> ReadSinglePacketAsync(
            TDSMessageType type, Stream stream, bool readPacketTypeFromStream, CancellationToken cancellationToken)
        {
            // Already have the type, read the rest of the TDS packet header
            var header          = new byte[HeaderLength];
            int packetBytesRead = 0;

            if (!readPacketTypeFromStream)
            {
                header[0]       = (byte)type;
                packetBytesRead = 1;
            }
            while (packetBytesRead < header.Length)
            {
                var thisRead = await stream.ReadAsync(header, packetBytesRead, header.Length - packetBytesRead, cancellationToken).ConfigureAwait(false);

                if (thisRead <= 0)
                {
                    throw new TDSInvalidPacketException("Incomplete TDS packet header received.", header, packetBytesRead);
                }
                packetBytesRead += thisRead;
            }

            // Break out fields from the packet header
            var status = (TDSStatus)header[1];
            var length = (ushort)((header[2] << 8) + header[3]);

            if (length < header.Length)
            {
                throw new TDSInvalidPacketException("Invalid length (" + length + ") in TDS packet.", header, packetBytesRead);
            }
            var spid     = (ushort)((header[4] << 8) + header[5]);
            var packetId = header[6];
            var window   = header[7];

            var payload = new byte[length - HeaderLength];

            // Read rest of packet
            while (packetBytesRead < length)
            {
                var thisRead = await stream.ReadAsync(payload, packetBytesRead - HeaderLength, length - packetBytesRead, cancellationToken).ConfigureAwait(false);

                if (thisRead <= 0)
                {
                    var packetData = new byte[packetBytesRead];
                    Buffer.BlockCopy(header, 0, packetData, 0, HeaderLength);
                    Buffer.BlockCopy(payload, 0, packetData, HeaderLength, packetBytesRead - HeaderLength);
                    throw new TDSInvalidPacketException(
                              "Connection closed before complete TDS packet could be read, got " + packetBytesRead + " bytes, expected " + length + " bytes.",
                              packetData,
                              packetBytesRead);
                }
                packetBytesRead += thisRead;
            }

            if ((TDSMessageType)header[0] != type)
            {
                var packetData = new byte[packetBytesRead];
                Buffer.BlockCopy(header, 0, packetData, 0, HeaderLength);
                Buffer.BlockCopy(payload, 0, packetData, HeaderLength, packetBytesRead - HeaderLength);
                throw new TDSInvalidPacketException(
                          $"Unexpected message type, expected {type} got {(TDSMessageType)header[0]}", null, 0);
            }

            if (DumpPackets)
            {
                log.DebugFormat("Received {0} packet. Data:\r\n{1}", type, header.Concat(payload).FormatAsHex());
            }

            return(new TDSPacket
            {
                PacketType = type,
                Status = status,
                Length = length,
                SPID = spid,
                PacketID = packetId,
                Window = window,
                Payload = payload
            });
        }
Пример #9
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSPacketHeader(byte[] buffer, TDSMessageType type, TDSPacketStatus status) :
     this(buffer, type)
 {
     // Save status
     Status = status;
 }
Пример #10
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSPacketHeader(byte[] buffer, TDSMessageType type) :
     this(buffer)
 {
     // Save type
     Type = type;
 }
Пример #11
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSPacketHeader(byte[] buffer, TDSMessageType type, TDSPacketStatus status) :
     this(buffer, type)
 {
     // Save status
     Status = status;
 }
Пример #12
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSPacketHeader(byte[] buffer, TDSMessageType type) :
     this(buffer)
 {
     // Save type
     Type = type;
 }
Пример #13
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSMessage(TDSMessageType type) :
     this()
 {
     // Save type
     MessageType = type;
 }
Пример #14
0
 public static Task <TDSPacket> ReadSinglePacketAsync(TDSMessageType type, Stream stream, bool readPacketTypeFromStream)
 {
     return(ReadSinglePacketAsync(type, stream, readPacketTypeFromStream, CancellationToken.None));
 }
Пример #15
0
 public static IEnumerable <TDSPacket> Read(TDSMessageType type, Stream stream)
 {
     return(ReadAsync(type, stream).Result);
 }
Пример #16
0
 public static Task <IEnumerable <TDSPacket> > ReadAsync(TDSMessageType type, Stream stream)
 {
     return(ReadAsync(type, stream, CancellationToken.None));
 }
Пример #17
0
        /// <summary>
        /// Create a new TDS packet in the message
        /// </summary>
        private void _CreateOutgoingPacket(TDSMessageType type, byte packetID)
        {
            // Allocate an outgoing packet in case it isn't available
            _AllocateOutgoingPacket();

            // Allocate a new packet with the specified type and normal status
            OutgoingPacketHeader = new TDSPacketHeader(_outgoingPacket, type, TDSPacketStatus.Normal);

            // Assign session identifier to the packet
            OutgoingPacketHeader.SPID = OutgoingSessionID;

            // Increment packet identifier
            OutgoingPacketHeader.PacketID = packetID;
        }
Пример #18
0
        /// <summary>
        /// Start a new message
        /// </summary>
        /// <param name="type">Type of the message to start</param>
        public virtual void StartMessage(TDSMessageType type)
        {
            // Flush current packet if available
            _SendCurrentPacket();

            // Create a new packet of the specified type
            _CreateOutgoingPacket(type, 1);
        }
Пример #19
0
 /// <summary>
 /// Initialization constructor
 /// </summary>
 public TDSMessage(TDSMessageType type, params TDSPacketToken[] tokens) :
     this(type)
 {
     AddRange(tokens);
 }
Пример #20
0
 public static TDSPacket ReadSinglePacket(TDSMessageType type, Stream stream, bool readPacketTypeFromStream)
 {
     return(ReadSinglePacketAsync(type, stream, readPacketTypeFromStream).Result);
 }