buffered_writer.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package buf
  2. import (
  3. "io"
  4. "v2ray.com/core/common/errors"
  5. )
  6. // BufferedWriter is an io.Writer with internal buffer. It writes to underlying writer when buffer is full or on demand.
  7. // This type is not thread safe.
  8. type BufferedWriter struct {
  9. writer io.Writer
  10. buffer *Buffer
  11. buffered bool
  12. }
  13. // NewBufferedWriter creates a new BufferedWriter.
  14. func NewBufferedWriter(rawWriter io.Writer) *BufferedWriter {
  15. return &BufferedWriter{
  16. writer: rawWriter,
  17. buffer: NewLocal(1024),
  18. buffered: true,
  19. }
  20. }
  21. // ReadFrom implements io.ReaderFrom.ReadFrom().
  22. func (v *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
  23. totalBytes := int64(0)
  24. for {
  25. oriSize := v.buffer.Len()
  26. err := v.buffer.AppendSupplier(ReadFrom(reader))
  27. totalBytes += int64(v.buffer.Len() - oriSize)
  28. if err != nil {
  29. if errors.Cause(err) == io.EOF {
  30. return totalBytes, nil
  31. }
  32. return totalBytes, err
  33. }
  34. if err := v.Flush(); err != nil {
  35. return totalBytes, err
  36. }
  37. }
  38. }
  39. func (v *BufferedWriter) Write(b []byte) (int, error) {
  40. if !v.buffered || v.buffer == nil {
  41. return v.writer.Write(b)
  42. }
  43. nBytes, err := v.buffer.Write(b)
  44. if err != nil {
  45. return 0, err
  46. }
  47. if v.buffer.IsFull() {
  48. err := v.Flush()
  49. if err != nil {
  50. return 0, err
  51. }
  52. if nBytes < len(b) {
  53. if _, err := v.writer.Write(b[nBytes:]); err != nil {
  54. return nBytes, err
  55. }
  56. }
  57. }
  58. return len(b), nil
  59. }
  60. // Flush writes all buffered content into underlying writer, if any.
  61. func (v *BufferedWriter) Flush() error {
  62. defer v.buffer.Clear()
  63. for !v.buffer.IsEmpty() {
  64. nBytes, err := v.writer.Write(v.buffer.Bytes())
  65. if err != nil {
  66. return err
  67. }
  68. v.buffer.SliceFrom(nBytes)
  69. }
  70. return nil
  71. }
  72. // IsBuffered returns true if this BufferedWriter holds a buffer.
  73. func (v *BufferedWriter) IsBuffered() bool {
  74. return v.buffered
  75. }
  76. // SetBuffered controls whether the BufferedWriter holds a buffer for writing. If not buffered, any write() calls into underlying writer directly.
  77. func (v *BufferedWriter) SetBuffered(cached bool) error {
  78. v.buffered = cached
  79. if !cached && !v.buffer.IsEmpty() {
  80. return v.Flush()
  81. }
  82. return nil
  83. }