writer.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package bufio
  2. import (
  3. "io"
  4. "v2ray.com/core/common"
  5. "v2ray.com/core/common/buf"
  6. "v2ray.com/core/common/errors"
  7. )
  8. // BufferedWriter is an io.Writer with internal buffer. It writes to underlying writer when buffer is full or on demand.
  9. // This type is not thread safe.
  10. type BufferedWriter struct {
  11. writer io.Writer
  12. buffer *buf.Buffer
  13. buffered bool
  14. }
  15. // NewWriter creates a new BufferedWriter.
  16. func NewWriter(rawWriter io.Writer) *BufferedWriter {
  17. return &BufferedWriter{
  18. writer: rawWriter,
  19. buffer: buf.NewSmall(),
  20. buffered: true,
  21. }
  22. }
  23. func (v *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
  24. totalBytes := int64(0)
  25. for {
  26. oriSize := v.buffer.Len()
  27. err := v.buffer.AppendSupplier(buf.ReadFrom(reader))
  28. totalBytes += int64(v.buffer.Len() - oriSize)
  29. if err != nil {
  30. if errors.Cause(err) == io.EOF {
  31. return totalBytes, nil
  32. }
  33. return totalBytes, err
  34. }
  35. if err := v.Flush(); err != nil {
  36. return totalBytes, err
  37. }
  38. }
  39. }
  40. func (v *BufferedWriter) Write(b []byte) (int, error) {
  41. if !v.buffered || v.buffer == nil {
  42. return v.writer.Write(b)
  43. }
  44. nBytes, err := v.buffer.Write(b)
  45. if err != nil {
  46. return 0, err
  47. }
  48. if v.buffer.IsFull() {
  49. err := v.Flush()
  50. if err != nil {
  51. return 0, err
  52. }
  53. if nBytes < len(b) {
  54. if _, err := v.writer.Write(b[nBytes:]); err != nil {
  55. return nBytes, err
  56. }
  57. }
  58. }
  59. return len(b), nil
  60. }
  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. func (v *BufferedWriter) Buffered() bool {
  73. return v.buffered
  74. }
  75. func (v *BufferedWriter) SetBuffered(cached bool) {
  76. v.buffered = cached
  77. if !cached && !v.buffer.IsEmpty() {
  78. v.Flush()
  79. }
  80. }
  81. // Release implements common.Releasable.Release().
  82. func (v *BufferedWriter) Release() {
  83. if !v.buffer.IsEmpty() {
  84. v.Flush()
  85. }
  86. if v.buffer != nil {
  87. v.buffer.Release()
  88. v.buffer = nil
  89. }
  90. common.Release(v.writer)
  91. }