transport.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package net
  2. import (
  3. "io"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. )
  6. // ReadFrom reads from a reader and put all content to a buffer.
  7. // If buffer is nil, ReadFrom creates a new normal buffer.
  8. func ReadFrom(reader io.Reader, buffer *alloc.Buffer) (*alloc.Buffer, error) {
  9. if buffer == nil {
  10. buffer = alloc.NewBuffer()
  11. }
  12. nBytes, err := reader.Read(buffer.Value)
  13. buffer.Slice(0, nBytes)
  14. return buffer, err
  15. }
  16. // ReadAllBytes reads all bytes required from reader, if no error happens.
  17. func ReadAllBytes(reader io.Reader, buffer []byte) (int, error) {
  18. bytesRead := 0
  19. bytesAsked := len(buffer)
  20. for bytesRead < bytesAsked {
  21. nBytes, err := reader.Read(buffer[bytesRead:])
  22. bytesRead += nBytes
  23. if err != nil {
  24. return bytesRead, err
  25. }
  26. }
  27. return bytesRead, nil
  28. }
  29. // ReaderToChan dumps all content from a given reader to a chan by constantly reading it until EOF.
  30. func ReaderToChan(stream chan<- *alloc.Buffer, reader io.Reader) error {
  31. allocate := alloc.NewBuffer
  32. large := false
  33. for {
  34. buffer, err := ReadFrom(reader, allocate())
  35. if buffer.Len() > 0 {
  36. stream <- buffer
  37. } else {
  38. buffer.Release()
  39. }
  40. if err != nil {
  41. return err
  42. }
  43. if buffer.IsFull() && !large {
  44. allocate = alloc.NewLargeBuffer
  45. large = true
  46. } else if !buffer.IsFull() {
  47. allocate = alloc.NewBuffer
  48. large = false
  49. }
  50. }
  51. }
  52. // ChanToWriter dumps all content from a given chan to a writer until the chan is closed.
  53. func ChanToWriter(writer io.Writer, stream <-chan *alloc.Buffer) error {
  54. for buffer := range stream {
  55. nBytes, err := writer.Write(buffer.Value)
  56. if nBytes < buffer.Len() {
  57. _, err = writer.Write(buffer.Value[nBytes:])
  58. }
  59. buffer.Release()
  60. if err != nil {
  61. return err
  62. }
  63. }
  64. return nil
  65. }