multi_buffer.go 4.5 KB

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