multi_buffer.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package buf
  2. import (
  3. "io"
  4. "v2ray.com/core/common/errors"
  5. "v2ray.com/core/common/serial"
  6. )
  7. // ReadAllToBytes reads all content from the reader into a byte array, until EOF.
  8. func ReadAllToBytes(reader io.Reader) ([]byte, error) {
  9. mb, err := ReadFrom(reader)
  10. if err != nil {
  11. return nil, err
  12. }
  13. if mb.Len() == 0 {
  14. return nil, nil
  15. }
  16. b := make([]byte, mb.Len())
  17. mb, _ = SplitBytes(mb, b)
  18. ReleaseMulti(mb)
  19. return b, nil
  20. }
  21. // MultiBuffer is a list of Buffers. The order of Buffer matters.
  22. type MultiBuffer []*Buffer
  23. // MergeMulti merges content from src to dest, and returns the new address of dest and src
  24. func MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBuffer) {
  25. dest = append(dest, src...)
  26. for idx := range src {
  27. src[idx] = nil
  28. }
  29. return dest, src[:0]
  30. }
  31. // MergeBytes merges the given bytes into MultiBuffer and return the new address of the merged MultiBuffer.
  32. func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {
  33. n := len(dest)
  34. if n > 0 && !(dest)[n-1].IsFull() {
  35. nBytes, _ := (dest)[n-1].Write(src)
  36. src = src[nBytes:]
  37. }
  38. for len(src) > 0 {
  39. b := New()
  40. nBytes, _ := b.Write(src)
  41. src = src[nBytes:]
  42. dest = append(dest, b)
  43. }
  44. return dest
  45. }
  46. // ReleaseMulti release all content of the MultiBuffer, and returns an empty MultiBuffer.
  47. func ReleaseMulti(mb MultiBuffer) MultiBuffer {
  48. for i := range mb {
  49. mb[i].Release()
  50. mb[i] = nil
  51. }
  52. return mb[:0]
  53. }
  54. // Copy copied the beginning part of the MultiBuffer into the given byte array.
  55. func (mb MultiBuffer) Copy(b []byte) int {
  56. total := 0
  57. for _, bb := range mb {
  58. nBytes := copy(b[total:], bb.Bytes())
  59. total += nBytes
  60. if int32(nBytes) < bb.Len() {
  61. break
  62. }
  63. }
  64. return total
  65. }
  66. // ReadFrom reads all content from reader until EOF.
  67. func ReadFrom(reader io.Reader) (MultiBuffer, error) {
  68. mb := make(MultiBuffer, 0, 16)
  69. for {
  70. b := New()
  71. _, err := b.ReadFullFrom(reader, Size)
  72. if b.IsEmpty() {
  73. b.Release()
  74. } else {
  75. mb = append(mb, b)
  76. }
  77. if err != nil {
  78. if errors.Cause(err) == io.EOF || errors.Cause(err) == io.ErrUnexpectedEOF {
  79. return mb, nil
  80. }
  81. return mb, err
  82. }
  83. }
  84. }
  85. // SplitBytes splits the given amount of bytes from the beginning of the MultiBuffer.
  86. // It returns the new address of MultiBuffer leftover, and number of bytes written into the input byte slice.
  87. func SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int) {
  88. totalBytes := 0
  89. for len(mb) > 0 {
  90. bb := mb[0]
  91. nBytes, _ := bb.Read(b)
  92. totalBytes += nBytes
  93. b = b[nBytes:]
  94. if !bb.IsEmpty() {
  95. break
  96. }
  97. bb.Release()
  98. mb = mb[1:]
  99. }
  100. return mb, totalBytes
  101. }
  102. // SplitFirst splits the first Buffer from the beginning of the MultiBuffer.
  103. func SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {
  104. if len(mb) == 0 {
  105. return mb, nil
  106. }
  107. b := mb[0]
  108. mb[0] = nil
  109. mb = mb[1:]
  110. return mb, b
  111. }
  112. // SplitSize splits the beginning of the MultiBuffer into another one, for at most size bytes.
  113. func SplitSize(mb MultiBuffer, size int32) (MultiBuffer, MultiBuffer) {
  114. if len(mb) == 0 {
  115. return mb, nil
  116. }
  117. if mb[0].Len() > size {
  118. b := New()
  119. copy(b.Extend(size), mb[0].BytesTo(size))
  120. mb[0].Advance(size)
  121. return mb, MultiBuffer{b}
  122. }
  123. totalBytes := int32(0)
  124. var r MultiBuffer
  125. endIndex := 0
  126. for i := range mb {
  127. if totalBytes+mb[i].Len() > size {
  128. endIndex = i
  129. break
  130. }
  131. r = append(r, mb[i])
  132. mb[i] = nil
  133. }
  134. if endIndex == len(mb) {
  135. // To reuse mb array
  136. mb = mb[:0]
  137. } else {
  138. mb = mb[endIndex:]
  139. }
  140. return mb, r
  141. }
  142. // Len returns the total number of bytes in the MultiBuffer.
  143. func (mb MultiBuffer) Len() int32 {
  144. if mb == nil {
  145. return 0
  146. }
  147. size := int32(0)
  148. for _, b := range mb {
  149. size += b.Len()
  150. }
  151. return size
  152. }
  153. // IsEmpty return true if the MultiBuffer has no content.
  154. func (mb MultiBuffer) IsEmpty() bool {
  155. for _, b := range mb {
  156. if !b.IsEmpty() {
  157. return false
  158. }
  159. }
  160. return true
  161. }
  162. // String returns the content of the MultiBuffer in string.
  163. func (mb MultiBuffer) String() string {
  164. v := make([]interface{}, len(mb))
  165. for i, b := range mb {
  166. v[i] = b
  167. }
  168. return serial.Concat(v...)
  169. }
  170. // MultiBufferContainer is a ReadWriteCloser wrapper over MultiBuffer.
  171. type MultiBufferContainer struct {
  172. MultiBuffer
  173. }
  174. // Read implements io.Reader.
  175. func (c *MultiBufferContainer) Read(b []byte) (int, error) {
  176. if c.MultiBuffer.IsEmpty() {
  177. return 0, io.EOF
  178. }
  179. mb, nBytes := SplitBytes(c.MultiBuffer, b)
  180. c.MultiBuffer = mb
  181. return nBytes, nil
  182. }
  183. // ReadMultiBuffer implements Reader.
  184. func (c *MultiBufferContainer) ReadMultiBuffer() (MultiBuffer, error) {
  185. mb := c.MultiBuffer
  186. c.MultiBuffer = nil
  187. return mb, nil
  188. }
  189. // Write implements io.Writer.
  190. func (c *MultiBufferContainer) Write(b []byte) (int, error) {
  191. c.MultiBuffer = MergeBytes(c.MultiBuffer, b)
  192. return len(b), nil
  193. }
  194. // WriteMultiBuffer implement Writer.
  195. func (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {
  196. mb, _ := MergeMulti(c.MultiBuffer, b)
  197. c.MultiBuffer = mb
  198. return nil
  199. }
  200. // Close implement io.Closer.
  201. func (c *MultiBufferContainer) Close() error {
  202. c.MultiBuffer = ReleaseMulti(c.MultiBuffer)
  203. return nil
  204. }