io.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package buf
  2. import (
  3. "io"
  4. "net"
  5. "os"
  6. "syscall"
  7. "time"
  8. )
  9. // Reader extends io.Reader with MultiBuffer.
  10. type Reader interface {
  11. // ReadMultiBuffer reads content from underlying reader, and put it into a MultiBuffer.
  12. ReadMultiBuffer() (MultiBuffer, error)
  13. }
  14. // ErrReadTimeout is an error that happens with IO timeout.
  15. var ErrReadTimeout = newError("IO timeout")
  16. // TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.
  17. type TimeoutReader interface {
  18. ReadMultiBufferTimeout(time.Duration) (MultiBuffer, error)
  19. }
  20. // Writer extends io.Writer with MultiBuffer.
  21. type Writer interface {
  22. // WriteMultiBuffer writes a MultiBuffer into underlying writer.
  23. WriteMultiBuffer(MultiBuffer) error
  24. }
  25. // WriteAllBytes ensures all bytes are written into the given writer.
  26. func WriteAllBytes(writer io.Writer, payload []byte) error {
  27. for len(payload) > 0 {
  28. n, err := writer.Write(payload)
  29. if err != nil {
  30. return err
  31. }
  32. payload = payload[n:]
  33. }
  34. return nil
  35. }
  36. func isPacketReader(reader io.Reader) bool {
  37. _, ok := reader.(net.PacketConn)
  38. return ok
  39. }
  40. // NewReader creates a new Reader.
  41. // The Reader instance doesn't take the ownership of reader.
  42. func NewReader(reader io.Reader) Reader {
  43. if mr, ok := reader.(Reader); ok {
  44. return mr
  45. }
  46. if isPacketReader(reader) {
  47. return &PacketReader{
  48. Reader: reader,
  49. }
  50. }
  51. _, isFile := reader.(*os.File)
  52. if !isFile && useReadv {
  53. if sc, ok := reader.(syscall.Conn); ok {
  54. rawConn, err := sc.SyscallConn()
  55. if err != nil {
  56. newError("failed to get sysconn").Base(err).WriteToLog()
  57. } else {
  58. return NewReadVReader(reader, rawConn)
  59. }
  60. }
  61. }
  62. return &SingleReader{
  63. Reader: reader,
  64. }
  65. }
  66. // NewPacketReader creates a new PacketReader based on the given reader.
  67. func NewPacketReader(reader io.Reader) Reader {
  68. if mr, ok := reader.(Reader); ok {
  69. return mr
  70. }
  71. return &PacketReader{
  72. Reader: reader,
  73. }
  74. }
  75. func isPacketWriter(writer io.Writer) bool {
  76. if _, ok := writer.(net.PacketConn); ok {
  77. return true
  78. }
  79. // If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.
  80. if _, ok := writer.(syscall.Conn); !ok {
  81. return true
  82. }
  83. return false
  84. }
  85. // NewWriter creates a new Writer.
  86. func NewWriter(writer io.Writer) Writer {
  87. if mw, ok := writer.(Writer); ok {
  88. return mw
  89. }
  90. if isPacketWriter(writer) {
  91. return &SequentialWriter{
  92. Writer: writer,
  93. }
  94. }
  95. return &BufferToBytesWriter{
  96. Writer: writer,
  97. }
  98. }