/// <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)); } }
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; }
/// <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; }
/// <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); }
/// <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; }
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); }
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 }); }
/// <summary> /// Initialization constructor /// </summary> public TDSPacketHeader(byte[] buffer, TDSMessageType type, TDSPacketStatus status) : this(buffer, type) { // Save status Status = status; }
/// <summary> /// Initialization constructor /// </summary> public TDSPacketHeader(byte[] buffer, TDSMessageType type) : this(buffer) { // Save type Type = type; }
/// <summary> /// Initialization constructor /// </summary> public TDSMessage(TDSMessageType type) : this() { // Save type MessageType = type; }
public static Task <TDSPacket> ReadSinglePacketAsync(TDSMessageType type, Stream stream, bool readPacketTypeFromStream) { return(ReadSinglePacketAsync(type, stream, readPacketTypeFromStream, CancellationToken.None)); }
public static IEnumerable <TDSPacket> Read(TDSMessageType type, Stream stream) { return(ReadAsync(type, stream).Result); }
public static Task <IEnumerable <TDSPacket> > ReadAsync(TDSMessageType type, Stream stream) { return(ReadAsync(type, stream, CancellationToken.None)); }
/// <summary> /// Initialization constructor /// </summary> public TDSMessage(TDSMessageType type, params TDSPacketToken[] tokens) : this(type) { AddRange(tokens); }
public static TDSPacket ReadSinglePacket(TDSMessageType type, Stream stream, bool readPacketTypeFromStream) { return(ReadSinglePacketAsync(type, stream, readPacketTypeFromStream).Result); }