| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | package buf | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 	"net" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | 	"v2ray.com/core/common" | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | 	"v2ray.com/core/common/errors" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 16:53:02 +01:00
										 |  |  | // ReadAllToMultiBuffer reads all content from the reader into a MultiBuffer, until EOF. | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | func ReadAllToMultiBuffer(reader io.Reader) (MultiBuffer, error) { | 
					
						
							| 
									
										
										
										
											2017-11-09 00:55:28 +01:00
										 |  |  | 	mb := NewMultiBufferCap(128) | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		b := New() | 
					
						
							| 
									
										
										
										
											2017-11-07 16:53:02 +01:00
										 |  |  | 		err := b.Reset(ReadFrom(reader)) | 
					
						
							|  |  |  | 		if b.IsEmpty() { | 
					
						
							|  |  |  | 			b.Release() | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | 			mb.Append(b) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if errors.Cause(err) == io.EOF { | 
					
						
							|  |  |  | 				return mb, nil | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mb.Release() | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | // ReadAllToBytes reads all content from the reader into a byte array, until EOF. | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | func ReadAllToBytes(reader io.Reader) ([]byte, error) { | 
					
						
							|  |  |  | 	mb, err := ReadAllToMultiBuffer(reader) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	b := make([]byte, mb.Len()) | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | 	common.Must2(mb.Read(b)) | 
					
						
							| 
									
										
										
										
											2017-11-04 01:33:28 +01:00
										 |  |  | 	mb.Release() | 
					
						
							|  |  |  | 	return b, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // MultiBuffer is a list of Buffers. The order of Buffer matters. | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | type MultiBuffer []*Buffer | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 00:55:28 +01:00
										 |  |  | // NewMultiBufferCap creates a new MultiBuffer instance. | 
					
						
							|  |  |  | func NewMultiBufferCap(capacity int) MultiBuffer { | 
					
						
							|  |  |  | 	return MultiBuffer(make([]*Buffer, 0, capacity)) | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // NewMultiBufferValue wraps a list of Buffers into MultiBuffer. | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | func NewMultiBufferValue(b ...*Buffer) MultiBuffer { | 
					
						
							|  |  |  | 	return MultiBuffer(b) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 15:02:21 +01:00
										 |  |  | // Append appends buffer to the end of this MultiBuffer | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | func (mb *MultiBuffer) Append(buf *Buffer) { | 
					
						
							|  |  |  | 	*mb = append(*mb, buf) | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 15:02:21 +01:00
										 |  |  | // AppendMulti appends a MultiBuffer to the end of this one. | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | func (mb *MultiBuffer) AppendMulti(buf MultiBuffer) { | 
					
						
							|  |  |  | 	*mb = append(*mb, buf...) | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 15:02:21 +01:00
										 |  |  | // Copy copied the begining part of the MultiBuffer into the given byte array. | 
					
						
							| 
									
										
										
										
											2017-04-25 01:56:08 +02:00
										 |  |  | func (mb MultiBuffer) Copy(b []byte) int { | 
					
						
							|  |  |  | 	total := 0 | 
					
						
							|  |  |  | 	for _, bb := range mb { | 
					
						
							|  |  |  | 		nBytes := copy(b[total:], bb.Bytes()) | 
					
						
							|  |  |  | 		total += nBytes | 
					
						
							|  |  |  | 		if nBytes < bb.Len() { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return total | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 15:02:21 +01:00
										 |  |  | // Read implements io.Reader. | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | func (mb *MultiBuffer) Read(b []byte) (int, error) { | 
					
						
							|  |  |  | 	endIndex := len(*mb) | 
					
						
							|  |  |  | 	totalBytes := 0 | 
					
						
							|  |  |  | 	for i, bb := range *mb { | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 		nBytes, _ := bb.Read(b) | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | 		totalBytes += nBytes | 
					
						
							|  |  |  | 		b = b[nBytes:] | 
					
						
							|  |  |  | 		if bb.IsEmpty() { | 
					
						
							|  |  |  | 			bb.Release() | 
					
						
							| 
									
										
										
										
											2017-11-07 16:28:39 +01:00
										 |  |  | 			(*mb)[i] = nil | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			endIndex = i | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*mb = (*mb)[endIndex:] | 
					
						
							|  |  |  | 	return totalBytes, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 15:02:21 +01:00
										 |  |  | // Write implements io.Writer. | 
					
						
							| 
									
										
										
										
											2017-05-02 00:28:16 +02:00
										 |  |  | func (mb *MultiBuffer) Write(b []byte) { | 
					
						
							|  |  |  | 	n := len(*mb) | 
					
						
							|  |  |  | 	if n > 0 && !(*mb)[n-1].IsFull() { | 
					
						
							|  |  |  | 		nBytes, _ := (*mb)[n-1].Write(b) | 
					
						
							|  |  |  | 		b = b[nBytes:] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for len(b) > 0 { | 
					
						
							|  |  |  | 		bb := New() | 
					
						
							|  |  |  | 		nBytes, _ := bb.Write(b) | 
					
						
							|  |  |  | 		b = b[nBytes:] | 
					
						
							|  |  |  | 		mb.Append(bb) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // Len returns the total number of bytes in the MultiBuffer. | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | func (mb MultiBuffer) Len() int { | 
					
						
							|  |  |  | 	size := 0 | 
					
						
							|  |  |  | 	for _, b := range mb { | 
					
						
							|  |  |  | 		size += b.Len() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return size | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // IsEmpty return true if the MultiBuffer has no content. | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | func (mb MultiBuffer) IsEmpty() bool { | 
					
						
							|  |  |  | 	for _, b := range mb { | 
					
						
							|  |  |  | 		if !b.IsEmpty() { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // Release releases all Buffers in the MultiBuffer. | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | func (mb *MultiBuffer) Release() { | 
					
						
							|  |  |  | 	for i, b := range *mb { | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | 		b.Release() | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | 		(*mb)[i] = nil | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-09 00:55:28 +01:00
										 |  |  | 	*mb = nil | 
					
						
							| 
									
										
										
										
											2017-04-15 21:07:23 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-16 22:30:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 19:16:56 +02:00
										 |  |  | // ToNetBuffers converts this MultiBuffer to net.Buffers. The return net.Buffers points to the same content of the MultiBuffer. | 
					
						
							| 
									
										
										
										
											2017-04-16 22:30:29 +02:00
										 |  |  | func (mb MultiBuffer) ToNetBuffers() net.Buffers { | 
					
						
							|  |  |  | 	bs := make([][]byte, len(mb)) | 
					
						
							|  |  |  | 	for i, b := range mb { | 
					
						
							|  |  |  | 		bs[i] = b.Bytes() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return bs | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-19 10:14:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:14:44 +01:00
										 |  |  | // SliceBySize splits the begining of this MultiBuffer into another one, for at most size bytes. | 
					
						
							| 
									
										
										
										
											2017-04-19 10:14:52 +02:00
										 |  |  | func (mb *MultiBuffer) SliceBySize(size int) MultiBuffer { | 
					
						
							| 
									
										
										
										
											2017-11-09 00:55:28 +01:00
										 |  |  | 	slice := NewMultiBufferCap(10) | 
					
						
							| 
									
										
										
										
											2017-04-19 10:14:52 +02:00
										 |  |  | 	sliceSize := 0 | 
					
						
							|  |  |  | 	endIndex := len(*mb) | 
					
						
							|  |  |  | 	for i, b := range *mb { | 
					
						
							|  |  |  | 		if b.Len()+sliceSize > size { | 
					
						
							|  |  |  | 			endIndex = i | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 		sliceSize += b.Len() | 
					
						
							| 
									
										
										
										
											2017-04-19 10:14:52 +02:00
										 |  |  | 		slice.Append(b) | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | 		(*mb)[i] = nil | 
					
						
							| 
									
										
										
										
											2017-04-19 10:14:52 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	*mb = (*mb)[endIndex:] | 
					
						
							|  |  |  | 	return slice | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-02 00:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:14:44 +01:00
										 |  |  | // SplitFirst splits out the first Buffer in this MultiBuffer. | 
					
						
							| 
									
										
										
										
											2017-05-02 00:28:16 +02:00
										 |  |  | func (mb *MultiBuffer) SplitFirst() *Buffer { | 
					
						
							|  |  |  | 	if len(*mb) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	b := (*mb)[0] | 
					
						
							| 
									
										
										
										
											2017-11-07 11:40:12 +01:00
										 |  |  | 	(*mb)[0] = nil | 
					
						
							| 
									
										
										
										
											2017-05-02 00:28:16 +02:00
										 |  |  | 	*mb = (*mb)[1:] | 
					
						
							|  |  |  | 	return b | 
					
						
							|  |  |  | } |