chain_writer.go 925 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package io
  2. import (
  3. "io"
  4. "sync"
  5. "v2ray.com/core/common/alloc"
  6. )
  7. type ChainWriter struct {
  8. sync.Mutex
  9. writer Writer
  10. }
  11. func NewChainWriter(writer Writer) *ChainWriter {
  12. return &ChainWriter{
  13. writer: writer,
  14. }
  15. }
  16. func (v *ChainWriter) Write(payload []byte) (int, error) {
  17. v.Lock()
  18. defer v.Unlock()
  19. if v.writer == nil {
  20. return 0, io.ErrClosedPipe
  21. }
  22. bytesWritten := 0
  23. size := len(payload)
  24. for size > 0 {
  25. buffer := alloc.NewBuffer().Clear()
  26. if size > alloc.BufferSize {
  27. buffer.Append(payload[:alloc.BufferSize])
  28. size -= alloc.BufferSize
  29. payload = payload[alloc.BufferSize:]
  30. bytesWritten += alloc.BufferSize
  31. } else {
  32. buffer.Append(payload)
  33. bytesWritten += size
  34. size = 0
  35. }
  36. err := v.writer.Write(buffer)
  37. if err != nil {
  38. return bytesWritten, err
  39. }
  40. }
  41. return bytesWritten, nil
  42. }
  43. func (v *ChainWriter) Release() {
  44. v.Lock()
  45. v.writer.Release()
  46. v.writer = nil
  47. v.Unlock()
  48. }