Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Namespace Net

    ''' <summary>
    ''' Represents the state of a packet collected across multiple asynchronous reads.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class PacketState2

        ''' <summary>
        ''' Initializes a default instance of the PacketState class.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' Initializes a new instance of the PacketState class with the specified socket.
        ''' </summary>
        ''' <param name="workSocket">The socket on which to receive data.</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal workSocket As Socket)
            Me.WorkSocket = workSocket
        End Sub

        Private _workSocket As Socket

        ''' <summary>
        ''' Gets the client socket.
        ''' </summary>
        ''' <returns>The client socket.</returns>
        ''' <remarks></remarks>
        Public Property WorkSocket() As Socket
            Get
                Return Me._workSocket
            End Get
            Set(ByVal value As Socket)
                Me._workSocket = value
            End Set
        End Property

        Private _storage As Object

        ''' <summary>
        ''' Gets or sets an object representing data that can be maintained across asynchronous calls to the work socket.
        ''' </summary>
        ''' <returns>An object representing data that can be maintained across asynchronous calls to the work socket.</returns>
        ''' <remarks></remarks>
        Public Property Storage As Object
            Get
                Return Me._storage
            End Get
            Set(value As Object)
                Me._storage = value
            End Set
        End Property

        Private _byte0 As Byte

        ''' <summary>
        ''' Gets or sets the value of byte index 0 for this message.
        ''' </summary>
        ''' <returns>The value of byte index 0 for this message.</returns>
        ''' <remarks></remarks>
        Public Property Byte0() As Byte
            Get
                Return Me._byte0
            End Get
            Set(ByVal value As Byte)
                Me._byte0 = value
            End Set
        End Property

        Private _byte1 As Byte

        ''' <summary>
        ''' Gets or sets the value of byte index 1 for this message.
        ''' </summary>
        ''' <returns>The value of byte index 1 for this message.</returns>
        ''' <remarks></remarks>
        Public Property Byte1() As Byte
            Get
                Return Me._byte1
            End Get
            Set(ByVal value As Byte)
                Me._byte1 = value
            End Set
        End Property

        Private _byte2 As Byte

        ''' <summary>
        ''' Gets or sets the value of byte index 2 for this message.
        ''' </summary>
        ''' <returns>The value of byte index 2 for this message.</returns>
        ''' <remarks></remarks>
        Public Property Byte2() As Byte
            Get
                Return Me._byte2
            End Get
            Set(ByVal value As Byte)
                Me._byte2 = value
            End Set
        End Property

        ''' <summary>
        ''' The size of the receive buffer.
        ''' </summary>
        ''' <remarks></remarks>
        Public Const BUFFER_SIZE As Integer = 8192

        ''' <summary>
        ''' The end record byte.
        ''' </summary>
        ''' <remarks></remarks>
        Public Const END_RECORD As Byte = &HC

        Private _buffer As Byte() = New Byte(BUFFER_SIZE) {}

        ''' <summary>
        ''' Gets the receive buffer.
        ''' </summary>
        ''' <returns>The receive buffer.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Buffer() As Byte()
            Get
                Return Me._buffer
            End Get
        End Property

        Private _appendPos As Integer
        Private _builder As Byte()

        ''' <summary>
        ''' Gets a byte builder for data collection.
        ''' </summary>
        ''' <returns>A byte array used for data collection.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Builder() As Byte()
            Get
                Return Me._builder
            End Get
        End Property

        ''' <summary>
        ''' Gets the starting index of the next append operation on the builder array.
        ''' </summary>
        ''' <returns>The starting index of the next append operation on the builder array.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property AppendOffset()
            Get
                Return Me._appendPos
            End Get
        End Property

        ''' <summary>
        ''' Initializes the builder array to the specified size.
        ''' </summary>
        ''' <param name="size">The size of the builder array.</param>
        ''' <remarks></remarks>
        Public Sub InitializeBuilder(ByVal size As Integer)
            Me._builder = New Byte(size) {}
            Me.SetAppendOffset(0)
        End Sub

        ''' <summary>
        ''' Sets the starting index of the next append operation on the builder array.
        ''' </summary>
        ''' <param name="offset">The index to set.  Must be greater than or equal to 0.</param>
        ''' <remarks></remarks>
        Public Sub SetAppendOffset(ByVal offset As Integer)
            If offset < 0 Then _
                offset = 0
            Me._appendPos = offset
        End Sub

        ''' <summary>
        ''' Appends the specified bytes to the builder at the specified offset and length.
        ''' </summary>
        ''' <param name="bytes">The byte array to append.</param>
        ''' <param name="offset">The starting offset on the byte array for the append.</param>
        ''' <param name="length">The number of bytes to append.</param>
        ''' <remarks></remarks>
        Public Sub Append(ByVal bytes As Byte(), ByVal offset As Integer, ByVal length As Integer)
            If (Me.Builder IsNot Nothing) Then
                Array.Copy(bytes, offset, Me.Builder, Me._appendPos, length)
                Me._appendPos = Me._appendPos + length
            End If
        End Sub

        Private _stringBuilder As StringBuilder = New StringBuilder()

        ''' <summary>
        ''' Gets the string builder for building received data strings.
        ''' </summary>
        ''' <returns>The string builder for building received data strings.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property StringBuilder() As StringBuilder
            Get
                Return Me._stringBuilder
            End Get
        End Property

        ''' <summary>
        ''' The number of bytes received.
        ''' </summary>
        ''' <remarks></remarks>
        Public ReceivedBytes As Integer = 0

        ''' <summary>
        ''' A value indicating whether the packet header has been fully received.
        ''' </summary>
        ''' <remarks></remarks>
        Public ReceivedHeader As Boolean = False

        Private _recordSize As Integer = 0

        ''' <summary>
        ''' Gets the expected size in bytes of the data collected by the builder.
        ''' </summary>
        ''' <returns>The expected size in bytes of the data collected by the builder.</returns>
        ''' <remarks></remarks>
        Public Property RecordSize() As Integer
            Get
                Return Me._recordSize
            End Get
            Set(ByVal value As Integer)
                Me._recordSize = value
            End Set
        End Property

    End Class

End Namespace