github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/xio/frame/frame.go (about)

     1  package frame
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"io"
     7  	"math/rand"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/codingeasygo/util/xio"
    12  )
    13  
    14  const (
    15  	//DefaultLengthFieldLength is default frame header length
    16  	DefaultLengthFieldLength = 4
    17  	DefaultBufferSize        = 8 * 1024
    18  )
    19  
    20  // ErrFrameTooLarge is the error when the frame head lenght > buffer length
    21  var ErrFrameTooLarge = fmt.Errorf("%v", "frame is too large")
    22  
    23  type readDeadlinable interface {
    24  	SetReadDeadline(t time.Time) error
    25  }
    26  
    27  type writeDeadlinable interface {
    28  	SetWriteDeadline(t time.Time) error
    29  }
    30  
    31  func connInfo(v interface{}) string {
    32  	local := xio.LocalAddr(v)
    33  	remote := xio.RemoteAddr(v)
    34  	if local == remote {
    35  		return local
    36  	} else {
    37  		return local + "<=>" + remote
    38  	}
    39  }
    40  
    41  type Header interface {
    42  	GetByteOrder() (order binary.ByteOrder)
    43  	GetLengthFieldMagic() (value int)
    44  	GetLengthFieldOffset() (value int)
    45  	GetLengthFieldLength() (value int)
    46  	GetLengthAdjustment() (value int)
    47  	GetDataOffset() (value int)
    48  	GetDataPrefix() (prefix []byte)
    49  	SetByteOrder(order binary.ByteOrder)
    50  	SetLengthFieldMagic(value int)
    51  	SetLengthFieldOffset(value int)
    52  	SetLengthFieldLength(value int)
    53  	SetLengthAdjustment(value int)
    54  	SetDataOffset(value int)
    55  	SetDataPrefix(prefix []byte)
    56  	WriteHead(buffer []byte)
    57  	ReadHead(buffer []byte) (length uint32)
    58  }
    59  
    60  // Reader is interface for read the raw io as frame mode
    61  type Reader interface {
    62  	io.Reader
    63  	Header
    64  	BufferSize() int
    65  	ReadFrame() (frame []byte, err error)
    66  	SetReadTimeout(timeout time.Duration)
    67  	WriteTo(writer io.Writer) (w int64, err error)
    68  }
    69  
    70  // Writer is interface for write the raw io as frame mode
    71  type Writer interface {
    72  	io.Writer
    73  	Header
    74  	WriteFrame(buffer []byte) (n int, err error)
    75  	SetWriteTimeout(timeout time.Duration)
    76  	ReadFrom(reader io.Reader) (w int64, err error)
    77  }
    78  
    79  // ReadWriter is interface for read/write the raw io as frame mode
    80  type ReadWriter interface {
    81  	Reader
    82  	Writer
    83  	SetTimeout(timeout time.Duration)
    84  }
    85  
    86  // ReadWriteCloser is interface for read/write the raw io as frame mode
    87  type ReadWriteCloser interface {
    88  	ReadWriter
    89  	io.Closer
    90  }
    91  
    92  type BaseHeader struct {
    93  	ByteOrder         binary.ByteOrder
    94  	LengthFieldMagic  int
    95  	LengthFieldOffset int
    96  	LengthFieldLength int
    97  	LengthAdjustment  int
    98  	DataOffset        int
    99  	DataPrefix        []byte
   100  }
   101  
   102  func NewDefaultHeader() (header *BaseHeader) {
   103  	header = &BaseHeader{
   104  		ByteOrder:         binary.BigEndian,
   105  		LengthFieldMagic:  0,
   106  		LengthFieldOffset: 0,
   107  		LengthFieldLength: 4,
   108  		LengthAdjustment:  0,
   109  		DataOffset:        4,
   110  	}
   111  	return
   112  }
   113  
   114  func CloneHeader(src Header) (header *BaseHeader) {
   115  	header = &BaseHeader{
   116  		ByteOrder:         src.GetByteOrder(),
   117  		LengthFieldMagic:  src.GetLengthFieldMagic(),
   118  		LengthFieldOffset: src.GetLengthFieldOffset(),
   119  		LengthFieldLength: src.GetLengthFieldLength(),
   120  		LengthAdjustment:  src.GetLengthAdjustment(),
   121  		DataOffset:        src.GetDataOffset(),
   122  		DataPrefix:        src.GetDataPrefix(),
   123  	}
   124  	return
   125  }
   126  
   127  func (b *BaseHeader) WriteHead(buffer []byte) {
   128  	switch b.LengthFieldLength {
   129  	case 1:
   130  		buffer[b.LengthFieldOffset] = byte(len(buffer) + b.LengthAdjustment)
   131  	case 2:
   132  		b.ByteOrder.PutUint16(buffer[b.LengthFieldOffset:], uint16(len(buffer)+b.LengthAdjustment))
   133  	case 4:
   134  		b.ByteOrder.PutUint32(buffer[b.LengthFieldOffset:], uint32(len(buffer)+b.LengthAdjustment))
   135  	default:
   136  		panic("not supported LengthFieldLength")
   137  	}
   138  	for i := 0; i < b.LengthFieldMagic; i++ {
   139  		buffer[b.LengthFieldOffset+i] = byte(rand.Intn(255))
   140  	}
   141  }
   142  
   143  func (b *BaseHeader) ReadHead(buffer []byte) (length uint32) {
   144  	for i := 0; i < b.LengthFieldMagic; i++ {
   145  		buffer[uint32(b.LengthFieldOffset)+uint32(i)] = 0
   146  	}
   147  	switch b.LengthFieldLength {
   148  	case 1:
   149  		length = uint32(buffer[uint32(b.LengthFieldOffset)]) - uint32(b.LengthAdjustment)
   150  	case 2:
   151  		length = uint32(b.ByteOrder.Uint16(buffer[uint32(b.LengthFieldOffset):])) - uint32(b.LengthAdjustment)
   152  	case 4:
   153  		length = uint32(b.ByteOrder.Uint32(buffer[uint32(b.LengthFieldOffset):])) - uint32(b.LengthAdjustment)
   154  	default:
   155  		panic("not supported LengthFieldLength")
   156  	}
   157  	return
   158  }
   159  
   160  func (b *BaseHeader) GetByteOrder() (order binary.ByteOrder) {
   161  	order = b.ByteOrder
   162  	return
   163  }
   164  
   165  func (b *BaseHeader) GetLengthFieldMagic() (value int) {
   166  	value = b.LengthFieldMagic
   167  	return
   168  }
   169  
   170  func (b *BaseHeader) GetLengthFieldOffset() (value int) {
   171  	value = b.LengthFieldOffset
   172  	return
   173  }
   174  
   175  func (b *BaseHeader) GetLengthFieldLength() (value int) {
   176  	value = b.LengthFieldLength
   177  	return
   178  }
   179  
   180  func (b *BaseHeader) GetLengthAdjustment() (value int) {
   181  	value = b.LengthAdjustment
   182  	return
   183  }
   184  
   185  func (b *BaseHeader) GetDataOffset() (value int) {
   186  	value = b.DataOffset
   187  	return
   188  }
   189  
   190  func (b *BaseHeader) GetDataPrefix() (prefix []byte) {
   191  	prefix = b.DataPrefix
   192  	return
   193  }
   194  
   195  func (b *BaseHeader) SetByteOrder(order binary.ByteOrder) {
   196  	b.ByteOrder = order
   197  }
   198  
   199  func (b *BaseHeader) SetLengthFieldMagic(value int) {
   200  	b.LengthFieldMagic = value
   201  }
   202  
   203  func (b *BaseHeader) SetLengthFieldOffset(value int) {
   204  	b.LengthFieldOffset = value
   205  }
   206  
   207  func (b *BaseHeader) SetLengthFieldLength(value int) {
   208  	b.LengthFieldLength = value
   209  }
   210  
   211  func (b *BaseHeader) SetLengthAdjustment(value int) {
   212  	b.LengthAdjustment = value
   213  }
   214  
   215  func (b *BaseHeader) SetDataOffset(value int) {
   216  	b.DataOffset = value
   217  }
   218  
   219  func (b *BaseHeader) SetDataPrefix(prefix []byte) {
   220  	b.DataPrefix = prefix
   221  }
   222  
   223  // NewReader will create new Reader by raw reader and buffer size
   224  func NewReader(raw io.Reader, bufferSize int) (reader *BaseReader) {
   225  	reader = NewBaseReader(raw, bufferSize)
   226  	return
   227  }
   228  
   229  // NewWriter will return new BaseWriter
   230  func NewWriter(raw io.Writer) (writer *BaseWriter) {
   231  	writer = NewBaseWriter(raw)
   232  	return
   233  }
   234  
   235  // BaseReadWriteCloser is frame reader/writer combiner
   236  type BaseReadWriteCloser struct {
   237  	io.Closer
   238  	Header
   239  	*BaseReader
   240  	*BaseWriter
   241  }
   242  
   243  // Close will call the closer
   244  func (b *BaseReadWriteCloser) Close() (err error) {
   245  	if b.Closer != nil {
   246  		err = b.Closer.Close()
   247  	}
   248  	return
   249  }
   250  
   251  func (b *BaseReadWriteCloser) String() string {
   252  	if interface{}(b.BaseReader.Raw) == interface{}(b.BaseWriter.Raw) {
   253  		return fmt.Sprintf("%v", b.BaseReader)
   254  	} else {
   255  		return fmt.Sprintf("Reader:%v,Writer:%v", b.BaseReader, b.BaseWriter)
   256  	}
   257  }
   258  
   259  // SetTimeout will record the timout
   260  func (b *BaseReadWriteCloser) SetTimeout(timeout time.Duration) {
   261  	b.BaseReader.SetReadTimeout(timeout)
   262  	b.BaseWriter.SetWriteTimeout(timeout)
   263  }
   264  
   265  // NewReadWriter will return new ReadWriteCloser
   266  func NewReadWriter(header Header, raw io.ReadWriter, bufferSize int) (frame *BaseReadWriteCloser) {
   267  	if bufferSize < 1 {
   268  		panic("buffer size is < 1")
   269  	}
   270  	if header == nil {
   271  		header = NewDefaultHeader()
   272  	} else {
   273  		header = CloneHeader(header)
   274  	}
   275  	closer, _ := raw.(io.Closer)
   276  	frame = &BaseReadWriteCloser{
   277  		Closer:     closer,
   278  		BaseReader: NewBaseReader(raw, bufferSize),
   279  		BaseWriter: NewBaseWriter(raw),
   280  	}
   281  	frame.Header = header
   282  	frame.BaseReader.Header = header
   283  	frame.BaseWriter.Header = header
   284  	return
   285  }
   286  
   287  // NewReadWriteCloser will return new ReadWriteCloser
   288  func NewReadWriteCloser(header Header, raw io.ReadWriteCloser, bufferSize int) (frame *BaseReadWriteCloser) {
   289  	if bufferSize < 1 {
   290  		panic("buffer size is < 1")
   291  	}
   292  	if header == nil {
   293  		header = NewDefaultHeader()
   294  	} else {
   295  		header = CloneHeader(header)
   296  	}
   297  	frame = &BaseReadWriteCloser{
   298  		Closer:     raw,
   299  		BaseReader: NewBaseReader(raw, bufferSize),
   300  		BaseWriter: NewBaseWriter(raw),
   301  	}
   302  	frame.Header = header
   303  	frame.BaseReader.Header = header
   304  	frame.BaseWriter.Header = header
   305  	return
   306  }
   307  
   308  // BaseReader imple read raw connection by frame mode
   309  type BaseReader struct {
   310  	Header
   311  	Buffer  []byte
   312  	Raw     io.Reader
   313  	Timeout time.Duration
   314  	offset  uint32
   315  	length  uint32
   316  	locker  sync.RWMutex
   317  }
   318  
   319  // NewBaseReader will create new Reader by raw reader and buffer size
   320  func NewBaseReader(raw io.Reader, bufferSize int) (reader *BaseReader) {
   321  	if bufferSize < 1 {
   322  		panic("buffer size is < 1")
   323  	}
   324  	reader = &BaseReader{
   325  		Header: NewDefaultHeader(),
   326  		Buffer: make([]byte, bufferSize),
   327  		Raw:    raw,
   328  		locker: sync.RWMutex{},
   329  	}
   330  	return
   331  }
   332  
   333  func (b *BaseReader) BufferSize() int { return len(b.Buffer) }
   334  
   335  // readMore will read more data to buffer
   336  func (b *BaseReader) readMore() (err error) {
   337  	if r, ok := b.Raw.(readDeadlinable); b.Timeout > 0 && ok {
   338  		r.SetReadDeadline(time.Now().Add(b.Timeout))
   339  	}
   340  	readed, err := b.Raw.Read(b.Buffer[b.offset+b.length:])
   341  	if err == nil {
   342  		b.length += uint32(readed)
   343  	}
   344  	return
   345  }
   346  
   347  // ReadFrame will read raw reader as frame mode. it will return length(4bytes)+data.
   348  // the return []byte is the buffer slice, must be copy to new []byte, it will be change after next read
   349  func (b *BaseReader) ReadFrame() (cmd []byte, err error) {
   350  	b.locker.Lock()
   351  	defer b.locker.Unlock()
   352  	more := b.length < uint32(b.GetLengthFieldLength())+1
   353  	for {
   354  		if more {
   355  			err = b.readMore()
   356  			if err != nil {
   357  				break
   358  			}
   359  			if b.length < uint32(b.GetLengthFieldLength())+1 {
   360  				continue
   361  			}
   362  		}
   363  		frameLength := b.ReadHead(b.Buffer[b.offset : b.offset+b.length])
   364  		if frameLength < 1 {
   365  			err = fmt.Errorf("frame length is zero")
   366  			break
   367  		}
   368  		if frameLength > uint32(len(b.Buffer)) {
   369  			err = ErrFrameTooLarge
   370  			break
   371  		}
   372  		if b.length < frameLength {
   373  			more = true
   374  			if b.offset > 0 {
   375  				copy(b.Buffer[0:], b.Buffer[b.offset:b.offset+b.length])
   376  				b.offset = 0
   377  			}
   378  			continue
   379  		}
   380  		cmd = b.Buffer[b.offset : b.offset+frameLength]
   381  		b.offset += frameLength
   382  		b.length -= frameLength
   383  		more = b.length <= uint32(b.GetLengthFieldLength())
   384  		if b.length < 1 {
   385  			b.offset = 0
   386  		}
   387  		if more && b.offset > 0 {
   388  			copy(b.Buffer[0:], b.Buffer[b.offset:b.offset+b.length])
   389  			b.offset = 0
   390  		}
   391  		break
   392  	}
   393  	return
   394  }
   395  
   396  // Read implment the io.Reader
   397  // it will read the one frame and copy the data to p
   398  func (b *BaseReader) Read(p []byte) (n int, err error) {
   399  	n, err = Read(b, p)
   400  	return
   401  }
   402  
   403  // SetReadTimeout will record the timout
   404  func (b *BaseReader) SetReadTimeout(timeout time.Duration) {
   405  	b.Timeout = timeout
   406  }
   407  
   408  func (b *BaseReader) WriteTo(writer io.Writer) (w int64, err error) {
   409  	w, err = WriteTo(b, writer)
   410  	return
   411  }
   412  
   413  func (b *BaseReader) String() string {
   414  	return connInfo(b.Raw)
   415  }
   416  
   417  func Read(reader Reader, p []byte) (n int, err error) {
   418  	offset := reader.GetDataOffset()
   419  	data, err := reader.ReadFrame()
   420  	if err == nil {
   421  		n = copy(p, data[offset:])
   422  	}
   423  	return
   424  }
   425  
   426  func WriteTo(reader Reader, writer io.Writer) (w int64, err error) {
   427  	var n int
   428  	var buffer []byte
   429  	offset := reader.GetDataOffset()
   430  	for {
   431  		buffer, err = reader.ReadFrame()
   432  		if err == nil {
   433  			n, err = writer.Write(buffer[offset:])
   434  		}
   435  		if err != nil {
   436  			break
   437  		}
   438  		w += int64(n)
   439  	}
   440  	return
   441  }
   442  
   443  // BaseWriter implment the frame Writer
   444  type BaseWriter struct {
   445  	Header
   446  	Raw     io.Writer
   447  	Timeout time.Duration
   448  	locker  sync.RWMutex
   449  }
   450  
   451  // NewBaseWriter will return new BaseWriter
   452  func NewBaseWriter(raw io.Writer) (writer *BaseWriter) {
   453  	writer = &BaseWriter{
   454  		Header: NewDefaultHeader(),
   455  		Raw:    raw,
   456  		locker: sync.RWMutex{},
   457  	}
   458  	return
   459  }
   460  
   461  // WriteFrame will write data by frame mode, it must have 4 bytes at the begin of buffer to store the frame length.
   462  // genral buffer is (4 bytes)+(user data), 4 bytes will be set the in WriteCmd
   463  func (b *BaseWriter) WriteFrame(buffer []byte) (w int, err error) {
   464  	b.locker.Lock()
   465  	defer b.locker.Unlock()
   466  	if w, ok := b.Raw.(writeDeadlinable); b.Timeout > 0 && ok {
   467  		w.SetWriteDeadline(time.Now().Add(b.Timeout))
   468  	}
   469  	b.WriteHead(buffer)
   470  	w, err = b.Raw.Write(buffer)
   471  	return
   472  }
   473  
   474  // Write implment the io.Writer, the p is user data buffer.
   475  // it will make a new []byte with len(p)+4, the copy data to buffer
   476  func (b *BaseWriter) Write(p []byte) (n int, err error) {
   477  	n, err = Write(b, p)
   478  	return
   479  }
   480  
   481  // SetWriteTimeout will record the timout
   482  func (b *BaseWriter) SetWriteTimeout(timeout time.Duration) {
   483  	b.Timeout = timeout
   484  }
   485  
   486  func (b *BaseWriter) ReadFrom(reader io.Reader) (w int64, err error) {
   487  	w, err = ReadFrom(b, reader, DefaultBufferSize)
   488  	return
   489  }
   490  
   491  func (b *BaseWriter) String() string {
   492  	return connInfo(b.Raw)
   493  }
   494  
   495  func Write(writer Writer, p []byte) (n int, err error) {
   496  	offset := writer.GetDataOffset()
   497  	buf := make([]byte, len(p)+offset)
   498  	copy(buf[offset:], p)
   499  	n = len(p)
   500  	_, err = writer.WriteFrame(buf)
   501  	return
   502  }
   503  
   504  func ReadFrom(writer Writer, reader io.Reader, bufferSize int) (w int64, err error) {
   505  	var n int
   506  	buffer := make([]byte, bufferSize)
   507  	offset := writer.GetDataOffset()
   508  	for {
   509  		n, err = reader.Read(buffer[offset:])
   510  		if err == nil {
   511  			n, err = writer.WriteFrame(buffer[:offset+n])
   512  		}
   513  		if err != nil {
   514  			break
   515  		}
   516  		w += int64(n)
   517  	}
   518  	return
   519  }
   520  
   521  type BasePiper struct {
   522  	Raw        xio.Piper
   523  	Header     Header
   524  	BufferSize int
   525  	Timeout    time.Duration
   526  }
   527  
   528  func NewBasePiper(raw xio.Piper, bufferSize int) (piper *BasePiper) {
   529  	piper = &BasePiper{
   530  		Raw:        raw,
   531  		Header:     NewDefaultHeader(),
   532  		BufferSize: bufferSize,
   533  	}
   534  	return
   535  }
   536  
   537  func (b *BasePiper) PipeConn(conn io.ReadWriteCloser, target string) (err error) {
   538  	rwc := NewReadWriteCloser(b.Header, conn, b.BufferSize)
   539  	rwc.SetTimeout(b.Timeout)
   540  	err = b.Raw.PipeConn(rwc, target)
   541  	return
   542  }
   543  
   544  func (b *BasePiper) Close() (err error) {
   545  	err = b.Raw.Close()
   546  	return
   547  }
   548  
   549  // RawWrapReadWriteCloser is frame reader/writer combiner
   550  type RawWrapReadWriteCloser struct {
   551  	io.Closer
   552  	Header
   553  	*RawWrapReader
   554  	*RawWrapWriter
   555  }
   556  
   557  // Close will call the closer
   558  func (r *RawWrapReadWriteCloser) Close() (err error) {
   559  	if r.Closer != nil {
   560  		err = r.Closer.Close()
   561  	}
   562  	return
   563  }
   564  
   565  func (r *RawWrapReadWriteCloser) String() string {
   566  	if interface{}(r.RawWrapReader.Raw) == interface{}(r.RawWrapWriter.Raw) {
   567  		return fmt.Sprintf("%v", r.RawWrapReader)
   568  	} else {
   569  		return fmt.Sprintf("Reader:%v,Writer:%v", r.RawWrapReader, r.RawWrapWriter)
   570  	}
   571  }
   572  
   573  // SetTimeout will record the timout
   574  func (r *RawWrapReadWriteCloser) SetTimeout(timeout time.Duration) {
   575  	r.RawWrapReader.SetReadTimeout(timeout)
   576  	r.RawWrapWriter.SetWriteTimeout(timeout)
   577  }
   578  
   579  // NewRawReadWriter will return new ReadWriteCloser
   580  func NewRawReadWriter(header Header, raw io.ReadWriter, bufferSize int) (frame *RawWrapReadWriteCloser) {
   581  	if bufferSize < 1 {
   582  		panic("buffer size is < 1")
   583  	}
   584  	if header == nil {
   585  		header = NewDefaultHeader()
   586  	} else {
   587  		header = CloneHeader(header)
   588  	}
   589  	closer, _ := raw.(io.Closer)
   590  	frame = &RawWrapReadWriteCloser{
   591  		Closer:        closer,
   592  		RawWrapReader: NewRawWrapReader(raw, bufferSize),
   593  		RawWrapWriter: NewRawWrapWriter(raw),
   594  	}
   595  	frame.Header = header
   596  	frame.RawWrapReader.Header = header
   597  	frame.RawWrapWriter.Header = header
   598  	return
   599  }
   600  
   601  // NewRawReadWriteCloser will return new ReadWriteCloser
   602  func NewRawReadWriteCloser(header Header, raw io.ReadWriteCloser, bufferSize int) (frame *RawWrapReadWriteCloser) {
   603  	if bufferSize < 1 {
   604  		panic("buffer size is < 1")
   605  	}
   606  	if header == nil {
   607  		header = NewDefaultHeader()
   608  	} else {
   609  		header = CloneHeader(header)
   610  	}
   611  	frame = &RawWrapReadWriteCloser{
   612  		Closer:        raw,
   613  		RawWrapReader: NewRawWrapReader(raw, bufferSize),
   614  		RawWrapWriter: NewRawWrapWriter(raw),
   615  	}
   616  	frame.Header = header
   617  	frame.RawWrapReader.Header = header
   618  	frame.RawWrapWriter.Header = header
   619  	return
   620  }
   621  
   622  // RawWrapReader imple read raw connection by frame mode
   623  type RawWrapReader struct {
   624  	Header
   625  	Buffer  []byte
   626  	Raw     io.Reader
   627  	Timeout time.Duration
   628  	locker  sync.RWMutex
   629  }
   630  
   631  // NewRawWrapReader will create new Reader by raw reader and buffer size
   632  func NewRawWrapReader(raw io.Reader, bufferSize int) (reader *RawWrapReader) {
   633  	if bufferSize < 1 {
   634  		panic("buffer size is < 1")
   635  	}
   636  	reader = &RawWrapReader{
   637  		Header: NewDefaultHeader(),
   638  		Buffer: make([]byte, bufferSize),
   639  		Raw:    raw,
   640  		locker: sync.RWMutex{},
   641  	}
   642  	return
   643  }
   644  
   645  func (r *RawWrapReader) BufferSize() int { return len(r.Buffer) }
   646  
   647  // ReadFrame will read raw reader as raw mode. it will return DataOffset+data.
   648  func (r *RawWrapReader) ReadFrame() (cmd []byte, err error) {
   649  	r.locker.Lock()
   650  	defer r.locker.Unlock()
   651  	offset := r.GetDataOffset()
   652  	prefix := r.GetDataPrefix()
   653  	l := len(prefix)
   654  	n, err := r.Read(r.Buffer[offset+l:])
   655  	if err != nil {
   656  		return
   657  	}
   658  	cmd = r.Buffer[:offset+l+n]
   659  	r.WriteHead(cmd)
   660  	if l > 0 {
   661  		copy(cmd[offset:offset+l], prefix)
   662  	}
   663  	return
   664  }
   665  
   666  // Read implment the io.Reader
   667  // it will read the one frame and copy the data to p
   668  func (r *RawWrapReader) Read(p []byte) (n int, err error) {
   669  	if raw, ok := r.Raw.(readDeadlinable); r.Timeout > 0 && ok {
   670  		raw.SetReadDeadline(time.Now().Add(r.Timeout))
   671  	}
   672  	n, err = r.Raw.Read(p)
   673  	return
   674  }
   675  
   676  // SetReadTimeout will record the timout
   677  func (r *RawWrapReader) SetReadTimeout(timeout time.Duration) {
   678  	r.Timeout = timeout
   679  }
   680  
   681  func (r *RawWrapReader) WriteTo(writer io.Writer) (w int64, err error) {
   682  	w, err = io.CopyBuffer(writer, r.Raw, r.Buffer)
   683  	return
   684  }
   685  
   686  func (r *RawWrapReader) String() string {
   687  	return connInfo(r.Raw)
   688  }
   689  
   690  // RawWrapWriter implment the frame Writer
   691  type RawWrapWriter struct {
   692  	Header
   693  	Raw     io.Writer
   694  	Timeout time.Duration
   695  	locker  sync.RWMutex
   696  }
   697  
   698  // NewRawWrapWriter will return new RawWrapWriter
   699  func NewRawWrapWriter(raw io.Writer) (writer *RawWrapWriter) {
   700  	writer = &RawWrapWriter{
   701  		Header: NewDefaultHeader(),
   702  		Raw:    raw,
   703  		locker: sync.RWMutex{},
   704  	}
   705  	return
   706  }
   707  
   708  func (r *RawWrapWriter) WriteFrame(buffer []byte) (w int, err error) {
   709  	r.locker.Lock()
   710  	defer r.locker.Unlock()
   711  	offset := r.GetDataOffset()
   712  	prefix := r.GetDataPrefix()
   713  	n := offset + len(prefix)
   714  	w, err = r.Write(buffer[n:])
   715  	w += n
   716  	return
   717  }
   718  
   719  // Write implment the io.Writer, the p is user data buffer.
   720  // it will make a new []byte with len(p)+4, the copy data to buffer
   721  func (r *RawWrapWriter) Write(p []byte) (n int, err error) {
   722  	if raw, ok := r.Raw.(writeDeadlinable); r.Timeout > 0 && ok {
   723  		raw.SetWriteDeadline(time.Now().Add(r.Timeout))
   724  	}
   725  	n, err = r.Raw.Write(p)
   726  	return
   727  }
   728  
   729  // SetWriteTimeout will record the timout
   730  func (r *RawWrapWriter) SetWriteTimeout(timeout time.Duration) {
   731  	r.Timeout = timeout
   732  }
   733  
   734  func (r *RawWrapWriter) ReadFrom(reader io.Reader) (w int64, err error) {
   735  	w, err = io.CopyBuffer(r.Raw, reader, make([]byte, DefaultBufferSize))
   736  	return
   737  }
   738  
   739  func (r *RawWrapWriter) String() string {
   740  	return connInfo(r.Raw)
   741  }
   742  
   743  type PassReadWriteCloser struct {
   744  	io.Closer
   745  	Header
   746  	*PassReadCloser
   747  	*PassWriteCloser
   748  }
   749  
   750  func NewPassReadWriteCloser(header Header, raw io.ReadWriteCloser, bufferSize int) (pass *PassReadWriteCloser) {
   751  	if bufferSize < 1 {
   752  		panic("buffer size is < 1")
   753  	}
   754  	if header == nil {
   755  		header = NewDefaultHeader()
   756  	} else {
   757  		header = CloneHeader(header)
   758  	}
   759  	pass = &PassReadWriteCloser{
   760  		Closer:          raw,
   761  		PassReadCloser:  NewPassReadCloser(raw),
   762  		PassWriteCloser: NewPassWriteCloser(raw, bufferSize),
   763  	}
   764  	pass.Header = header
   765  	pass.PassReadCloser.Header = header
   766  	pass.PassWriteCloser.Header = header
   767  	return
   768  }
   769  
   770  func NewPassReadWriter(header Header, raw io.ReadWriter, bufferSize int) (pass *PassReadWriteCloser) {
   771  	if bufferSize < 1 {
   772  		panic("buffer size is < 1")
   773  	}
   774  	if header == nil {
   775  		header = NewDefaultHeader()
   776  	} else {
   777  		header = CloneHeader(header)
   778  	}
   779  	closer, _ := raw.(io.Closer)
   780  	pass = &PassReadWriteCloser{
   781  		Closer:          closer,
   782  		PassReadCloser:  NewPassReader(raw),
   783  		PassWriteCloser: NewPassWriter(raw, bufferSize),
   784  	}
   785  	pass.Header = header
   786  	pass.PassReadCloser.Header = header
   787  	pass.PassWriteCloser.Header = header
   788  	return
   789  }
   790  
   791  func (r *PassReadWriteCloser) Close() (err error) {
   792  	if r.Closer != nil {
   793  		err = r.Closer.Close()
   794  	}
   795  	return
   796  }
   797  
   798  func (r *PassReadWriteCloser) String() string {
   799  	if interface{}(r.PassReadCloser.Reader) == interface{}(r.PassWriteCloser.Writer) {
   800  		return fmt.Sprintf("%v", r.PassReadCloser)
   801  	} else {
   802  		return fmt.Sprintf("Reader:%v,Writer:%v", r.PassReadCloser, r.PassWriteCloser)
   803  	}
   804  }
   805  
   806  type PassWriteCloser struct {
   807  	Header
   808  	io.Writer
   809  	io.Closer
   810  	buffer []byte
   811  	length uint32
   812  }
   813  
   814  func NewPassWriteCloser(next io.WriteCloser, bufferSize int) (writer *PassWriteCloser) {
   815  	writer = &PassWriteCloser{
   816  		Header: NewDefaultHeader(),
   817  		Writer: next,
   818  		Closer: next,
   819  		buffer: make([]byte, bufferSize),
   820  	}
   821  	return
   822  }
   823  
   824  func NewPassWriter(next io.Writer, bufferSize int) (writer *PassWriteCloser) {
   825  	writer = &PassWriteCloser{
   826  		Header: NewDefaultHeader(),
   827  		Writer: next,
   828  		buffer: make([]byte, bufferSize),
   829  	}
   830  	if closer, ok := next.(io.Closer); ok {
   831  		writer.Closer = closer
   832  	}
   833  	return
   834  }
   835  
   836  func (w *PassWriteCloser) readFrame(header uint32, buffer []byte) (size uint32, err error) {
   837  	bufSize := uint32(len(buffer))
   838  	if bufSize < header {
   839  		return
   840  	}
   841  	frameLength := w.ReadHead(buffer)
   842  	if frameLength <= uint32(-w.GetLengthAdjustment()) {
   843  		err = fmt.Errorf("head is zero")
   844  		return
   845  	}
   846  	if frameLength > uint32(len(w.buffer)) {
   847  		err = ErrFrameTooLarge
   848  		return
   849  	}
   850  	if bufSize >= frameLength {
   851  		size = frameLength
   852  	}
   853  	return
   854  }
   855  
   856  func (w *PassWriteCloser) Write(p []byte) (writed int, err error) {
   857  	recvSize := uint32(len(p))
   858  	recvBuf := p
   859  	header := uint32(w.GetLengthFieldLength())
   860  	offset := uint32(w.GetDataOffset())
   861  	frameSize := uint32(0)
   862  	n := 0
   863  	for {
   864  		if w.length < 1 {
   865  			frameSize, err = w.readFrame(header, recvBuf)
   866  			if err != nil {
   867  				break
   868  			}
   869  			if frameSize < 1 { //need more data
   870  				n = copy(w.buffer, recvBuf)
   871  				writed += n
   872  				w.length += uint32(n)
   873  				break
   874  			}
   875  			n, err = w.Writer.Write(recvBuf[offset:frameSize])
   876  			if err != nil {
   877  				break
   878  			}
   879  			writed += n
   880  			recvBuf = recvBuf[frameSize:]
   881  			recvSize -= frameSize
   882  			if recvSize < 1 {
   883  				break
   884  			}
   885  		} else {
   886  			if len(recvBuf) > 0 {
   887  				n = copy(w.buffer[w.length:], recvBuf)
   888  				writed += n
   889  				recvBuf = recvBuf[n:]
   890  				recvSize -= uint32(n)
   891  				w.length += uint32(n)
   892  			}
   893  			frameSize, err = w.readFrame(header, w.buffer[:w.length])
   894  			if err != nil {
   895  				break
   896  			}
   897  			if frameSize < 1 { //need more data
   898  				break
   899  			}
   900  			n, err = w.Writer.Write(w.buffer[offset:frameSize])
   901  			if err != nil {
   902  				break
   903  			}
   904  			writed += n
   905  			copy(w.buffer[0:], w.buffer[frameSize:w.length])
   906  			w.length -= frameSize
   907  		}
   908  	}
   909  	return
   910  }
   911  
   912  func (w *PassWriteCloser) Close() (err error) {
   913  	if w.Closer != nil {
   914  		err = w.Closer.Close()
   915  	}
   916  	return
   917  }
   918  
   919  func (w *PassWriteCloser) String() string {
   920  	return connInfo(w.Writer)
   921  }
   922  
   923  type PassReadCloser struct {
   924  	Header
   925  	io.Reader
   926  	io.Closer
   927  }
   928  
   929  func NewPassReadCloser(from io.ReadCloser) (reader *PassReadCloser) {
   930  	reader = &PassReadCloser{
   931  		Header: NewDefaultHeader(),
   932  		Reader: from,
   933  		Closer: from,
   934  	}
   935  	return
   936  }
   937  
   938  func NewPassReader(from io.Reader) (reader *PassReadCloser) {
   939  	reader = &PassReadCloser{
   940  		Header: NewDefaultHeader(),
   941  		Reader: from,
   942  	}
   943  	if closer, ok := from.(io.Closer); ok {
   944  		reader.Closer = closer
   945  	}
   946  	return
   947  }
   948  
   949  func (r *PassReadCloser) Read(p []byte) (n int, err error) {
   950  	offset := r.GetDataOffset()
   951  	n, err = r.Reader.Read(p[offset:])
   952  	if err == nil {
   953  		n += offset
   954  		r.WriteHead(p[:n])
   955  	}
   956  	return
   957  }
   958  
   959  func (r *PassReadCloser) Close() (err error) {
   960  	if r.Closer != nil {
   961  		err = r.Closer.Close()
   962  	}
   963  	return
   964  }
   965  
   966  func (r *PassReadCloser) String() string {
   967  	return connInfo(r.Reader)
   968  }