gitea

Development moved to Codeberg

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
package buffer

import (
	"encoding/gob"
	"io"
)

type swap struct {
	A BufferAt
	B BufferAt
}

// NewSwap creates a Buffer which writes to a until you write past a.Cap()
// then it io.Copy's from a to b and writes to b.
// Once the Buffer is empty again, it starts over writing to a.
// Note that if b.Cap() <= a.Cap() it will cause a panic, b is expected
// to be larger in order to accommodate writes past a.Cap().
func NewSwap(a, b Buffer) Buffer {
	return NewSwapAt(toBufferAt(a), toBufferAt(b))
}

// NewSwapAt creates a BufferAt which writes to a until you write past a.Cap()
// then it io.Copy's from a to b and writes to b.
// Once the Buffer is empty again, it starts over writing to a.
// Note that if b.Cap() <= a.Cap() it will cause a panic, b is expected
// to be larger in order to accommodate writes past a.Cap().
func NewSwapAt(a, b BufferAt) BufferAt {
	if b.Cap() <= a.Cap() {
		panic("Buffer b must be larger than a.")
	}
	return &swap{A: a, B: b}
}

func (buf *swap) Len() int64 {
	return buf.A.Len() + buf.B.Len()
}

func (buf *swap) Cap() int64 {
	return buf.B.Cap()
}

func (buf *swap) Read(p []byte) (n int, err error) {
	if buf.A.Len() > 0 {
		return buf.A.Read(p)
	}
	return buf.B.Read(p)
}

func (buf *swap) ReadAt(p []byte, off int64) (n int, err error) {
	if buf.A.Len() > 0 {
		return buf.A.ReadAt(p, off)
	}
	return buf.B.ReadAt(p, off)
}

func (buf *swap) Write(p []byte) (n int, err error) {
	switch {
	case buf.B.Len() > 0:
		n, err = buf.B.Write(p)

	case buf.A.Len()+int64(len(p)) > buf.A.Cap():
		_, err = io.Copy(buf.B, buf.A)
		if err == nil {
			n, err = buf.B.Write(p)
		}

	default:
		n, err = buf.A.Write(p)
	}

	return n, err
}

func (buf *swap) WriteAt(p []byte, off int64) (n int, err error) {
	switch {
	case buf.B.Len() > 0:
		n, err = buf.B.WriteAt(p, off)

	case off+int64(len(p)) > buf.A.Cap():
		_, err = io.Copy(buf.B, buf.A)
		if err == nil {
			n, err = buf.B.WriteAt(p, off)
		}

	default:
		n, err = buf.A.WriteAt(p, off)
	}

	return n, err
}

func (buf *swap) Reset() {
	buf.A.Reset()
	buf.B.Reset()
}

func init() {
	gob.Register(&swap{})
}