io.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package buf
  2. import (
  3. "io"
  4. "syscall"
  5. "time"
  6. )
  7. // Reader extends io.Reader with MultiBuffer.
  8. type Reader interface {
  9. // ReadMultiBuffer reads content from underlying reader, and put it into a MultiBuffer.
  10. ReadMultiBuffer() (MultiBuffer, error)
  11. }
  12. // ErrReadTimeout is an error that happens with IO timeout.
  13. var ErrReadTimeout = newError("IO timeout")
  14. // TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.
  15. type TimeoutReader interface {
  16. ReadMultiBufferTimeout(time.Duration) (MultiBuffer, error)
  17. }
  18. // Writer extends io.Writer with MultiBuffer.
  19. type Writer interface {
  20. // WriteMultiBuffer writes a MultiBuffer into underlying writer.
  21. WriteMultiBuffer(MultiBuffer) error
  22. }
  23. // ReadFrom creates a Supplier to read from a given io.Reader.
  24. func ReadFrom(reader io.Reader) Supplier {
  25. return func(b []byte) (int, error) {
  26. return reader.Read(b)
  27. }
  28. }
  29. // ReadFullFrom creates a Supplier to read full buffer from a given io.Reader.
  30. func ReadFullFrom(reader io.Reader, size int32) Supplier {
  31. return func(b []byte) (int, error) {
  32. return io.ReadFull(reader, b[:size])
  33. }
  34. }
  35. // WriteAllBytes ensures all bytes are written into the given writer.
  36. func WriteAllBytes(writer io.Writer, payload []byte) error {
  37. for len(payload) > 0 {
  38. n, err := writer.Write(payload)
  39. if err != nil {
  40. return err
  41. }
  42. payload = payload[n:]
  43. }
  44. return nil
  45. }
  46. // NewReader creates a new Reader.
  47. // The Reader instance doesn't take the ownership of reader.
  48. func NewReader(reader io.Reader) Reader {
  49. if mr, ok := reader.(Reader); ok {
  50. return mr
  51. }
  52. return newReaderPlatform(reader)
  53. }
  54. // NewWriter creates a new Writer.
  55. func NewWriter(writer io.Writer) Writer {
  56. if mw, ok := writer.(Writer); ok {
  57. return mw
  58. }
  59. if _, ok := writer.(syscall.Conn); !ok {
  60. // If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.
  61. return &SequentialWriter{
  62. Writer: writer,
  63. }
  64. }
  65. return &BufferToBytesWriter{
  66. Writer: writer,
  67. }
  68. }