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 }