github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/connection_windows.go (about)

     1  // +build windows
     2  
     3  package net
     4  
     5  import (
     6  	nt "net"
     7  
     8  	"github.com/angenalZZZ/gofunc/net/pool/bytebuffer"
     9  	prb "github.com/angenalZZZ/gofunc/net/pool/ringbuffer"
    10  	"github.com/angenalZZZ/gofunc/net/ringbuffer"
    11  )
    12  
    13  type stderr struct {
    14  	c   *stdConn
    15  	err error
    16  }
    17  
    18  type wakeReq struct {
    19  	c *stdConn
    20  }
    21  
    22  type tcpIn struct {
    23  	c  *stdConn
    24  	in *bytebuffer.ByteBuffer
    25  }
    26  
    27  type udpIn struct {
    28  	c *stdConn
    29  }
    30  
    31  type stdConn struct {
    32  	ctx           interface{}            // user-defined context
    33  	conn          nt.Conn                // original connection
    34  	loop          *eventloop             // owner event-loop
    35  	buffer        *bytebuffer.ByteBuffer // reuse memory of inbound data as a temporary buffer
    36  	codec         ICodec                 // codec for TCP
    37  	localAddr     nt.Addr                // local server addr
    38  	remoteAddr    nt.Addr                // remote peer addr
    39  	byteBuffer    *bytebuffer.ByteBuffer // bytes buffer for buffering current packet and data in ring-buffer
    40  	inboundBuffer *ringbuffer.RingBuffer // buffer for data from client
    41  }
    42  
    43  func newTCPConn(conn nt.Conn, el *eventloop) *stdConn {
    44  	return &stdConn{
    45  		conn:          conn,
    46  		loop:          el,
    47  		codec:         el.codec,
    48  		inboundBuffer: prb.Get(),
    49  	}
    50  }
    51  
    52  func (c *stdConn) releaseTCP() {
    53  	c.ctx = nil
    54  	c.localAddr = nil
    55  	c.remoteAddr = nil
    56  	prb.Put(c.inboundBuffer)
    57  	c.inboundBuffer = nil
    58  	bytebuffer.Put(c.buffer)
    59  	c.buffer = nil
    60  }
    61  
    62  func newUDPConn(el *eventloop, localAddr, remoteAddr nt.Addr, buf *bytebuffer.ByteBuffer) *stdConn {
    63  	return &stdConn{
    64  		loop:       el,
    65  		localAddr:  localAddr,
    66  		remoteAddr: remoteAddr,
    67  		buffer:     buf,
    68  	}
    69  }
    70  
    71  func (c *stdConn) releaseUDP() {
    72  	c.ctx = nil
    73  	c.localAddr = nil
    74  	bytebuffer.Put(c.buffer)
    75  	c.buffer = nil
    76  }
    77  
    78  func (c *stdConn) read() ([]byte, error) {
    79  	return c.codec.Decode(c)
    80  }
    81  
    82  func (c *stdConn) check() {
    83  	if c.inboundBuffer == nil {
    84  		c.inboundBuffer = prb.Get()
    85  	}
    86  }
    87  
    88  // ================================= Public APIs =================================
    89  
    90  func (c *stdConn) Read() []byte {
    91  	c.check()
    92  	if c.inboundBuffer.IsEmpty() {
    93  		return c.buffer.Bytes()
    94  	}
    95  	c.byteBuffer = c.inboundBuffer.WithByteBuffer(c.buffer.Bytes())
    96  	return c.byteBuffer.Bytes()
    97  }
    98  
    99  func (c *stdConn) ResetBuffer() {
   100  	c.check()
   101  	c.buffer.Reset()
   102  	c.inboundBuffer.Reset()
   103  	bytebuffer.Put(c.byteBuffer)
   104  	c.byteBuffer = nil
   105  }
   106  
   107  func (c *stdConn) ReadN(n int) (size int, buf []byte) {
   108  	c.check()
   109  	inBufferLen := c.inboundBuffer.Length()
   110  	tempBufferLen := c.buffer.Len()
   111  	if totalLen := inBufferLen + tempBufferLen; totalLen < n || n <= 0 {
   112  		n = totalLen
   113  	}
   114  	size = n
   115  	if c.inboundBuffer.IsEmpty() {
   116  		buf = c.buffer.B[:n]
   117  		return
   118  	}
   119  	head, tail := c.inboundBuffer.LazyRead(n)
   120  	c.byteBuffer = bytebuffer.Get()
   121  	_, _ = c.byteBuffer.Write(head)
   122  	_, _ = c.byteBuffer.Write(tail)
   123  	if inBufferLen >= n {
   124  		buf = c.byteBuffer.Bytes()
   125  		return
   126  	}
   127  
   128  	restSize := n - inBufferLen
   129  	_, _ = c.byteBuffer.Write(c.buffer.B[:restSize])
   130  	buf = c.byteBuffer.Bytes()
   131  	return
   132  }
   133  
   134  func (c *stdConn) ShiftN(n int) (size int) {
   135  	c.check()
   136  	inBufferLen := c.inboundBuffer.Length()
   137  	tempBufferLen := c.buffer.Len()
   138  	if inBufferLen+tempBufferLen < n || n <= 0 {
   139  		c.ResetBuffer()
   140  		size = inBufferLen + tempBufferLen
   141  		return
   142  	}
   143  	size = n
   144  	if c.inboundBuffer.IsEmpty() {
   145  		c.buffer.B = c.buffer.B[n:]
   146  		return
   147  	}
   148  
   149  	bytebuffer.Put(c.byteBuffer)
   150  	c.byteBuffer = nil
   151  
   152  	if inBufferLen >= n {
   153  		c.inboundBuffer.Shift(n)
   154  		return
   155  	}
   156  	c.inboundBuffer.Reset()
   157  
   158  	restSize := n - inBufferLen
   159  	c.buffer.B = c.buffer.B[restSize:]
   160  	return
   161  }
   162  
   163  func (c *stdConn) BufferLength() int {
   164  	c.check()
   165  	return c.inboundBuffer.Length() + c.buffer.Len()
   166  }
   167  
   168  func (c *stdConn) AsyncWrite(buf []byte) (err error) {
   169  	var encodedBuf []byte
   170  	if encodedBuf, err = c.codec.Encode(c, buf); err == nil {
   171  		c.loop.ch <- func() error {
   172  			_, _ = c.conn.Write(encodedBuf)
   173  			return nil
   174  		}
   175  	}
   176  	return
   177  }
   178  
   179  func (c *stdConn) SendTo(buf []byte) (err error) {
   180  	_, err = c.loop.svr.ln.pconn.WriteTo(buf, c.remoteAddr)
   181  	return
   182  }
   183  
   184  func (c *stdConn) Wake() error {
   185  	c.loop.ch <- wakeReq{c}
   186  	return nil
   187  }
   188  
   189  func (c *stdConn) Close() error {
   190  	c.loop.ch <- func() error {
   191  		return c.loop.loopCloseConn(c)
   192  	}
   193  	return nil
   194  }
   195  
   196  func (c *stdConn) Context() interface{}       { return c.ctx }
   197  func (c *stdConn) SetContext(ctx interface{}) { c.ctx = ctx }
   198  func (c *stdConn) LocalAddr() nt.Addr         { return c.localAddr }
   199  func (c *stdConn) RemoteAddr() nt.Addr        { return c.remoteAddr }