| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | package buf | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"v2ray.com/core/common/errors" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // BytesToBufferReader is a Reader that adjusts its reading speed automatically. | 
					
						
							|  |  |  | type BytesToBufferReader struct { | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 	io.Reader | 
					
						
							| 
									
										
										
										
											2017-04-19 23:30:18 +02:00
										 |  |  | 	buffer []byte | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 22:23:21 +01:00
										 |  |  | func NewBytesToBufferReader(reader io.Reader) Reader { | 
					
						
							|  |  |  | 	return &BytesToBufferReader{ | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 		Reader: reader, | 
					
						
							| 
									
										
										
										
											2017-11-08 22:23:21 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *BytesToBufferReader) readSmall() (MultiBuffer, error) { | 
					
						
							|  |  |  | 	b := New() | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 	if err := b.Reset(ReadFrom(r.Reader)); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-08 22:23:21 +01:00
										 |  |  | 		b.Release() | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if b.IsFull() { | 
					
						
							|  |  |  | 		r.buffer = make([]byte, 32*1024) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NewMultiBufferValue(b), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | // ReadMultiBuffer implements Reader. | 
					
						
							|  |  |  | func (r *BytesToBufferReader) ReadMultiBuffer() (MultiBuffer, error) { | 
					
						
							| 
									
										
										
										
											2017-11-08 22:23:21 +01:00
										 |  |  | 	if r.buffer == nil { | 
					
						
							|  |  |  | 		return r.readSmall() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 	nBytes, err := r.Reader.Read(r.buffer) | 
					
						
							| 
									
										
										
										
											2017-04-19 23:30:18 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 00:55:28 +01:00
										 |  |  | 	mb := NewMultiBufferCap(nBytes/Size + 1) | 
					
						
							| 
									
										
										
										
											2017-05-02 00:28:16 +02:00
										 |  |  | 	mb.Write(r.buffer[:nBytes]) | 
					
						
							| 
									
										
										
										
											2017-07-24 21:41:12 +02:00
										 |  |  | 	return mb, nil | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | type BufferedReader struct { | 
					
						
							|  |  |  | 	stream       Reader | 
					
						
							|  |  |  | 	legacyReader io.Reader | 
					
						
							|  |  |  | 	leftOver     MultiBuffer | 
					
						
							|  |  |  | 	buffered     bool | 
					
						
							| 
									
										
										
										
											2017-04-15 22:22:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func NewBufferedReader(reader Reader) *BufferedReader { | 
					
						
							|  |  |  | 	r := &BufferedReader{ | 
					
						
							|  |  |  | 		stream:   reader, | 
					
						
							|  |  |  | 		buffered: true, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if lr, ok := reader.(io.Reader); ok { | 
					
						
							|  |  |  | 		r.legacyReader = lr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *BufferedReader) SetBuffered(f bool) { | 
					
						
							|  |  |  | 	r.buffered = f | 
					
						
							| 
									
										
										
										
											2017-04-15 22:22:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func (r *BufferedReader) IsBuffered() bool { | 
					
						
							|  |  |  | 	return r.buffered | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func (r *BufferedReader) Read(b []byte) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	if r.leftOver != nil { | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 		nBytes, _ := r.leftOver.Read(b) | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 		if r.leftOver.IsEmpty() { | 
					
						
							|  |  |  | 			r.leftOver.Release() | 
					
						
							|  |  |  | 			r.leftOver = nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 		return nBytes, nil | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 	if !r.buffered && r.legacyReader != nil { | 
					
						
							|  |  |  | 		return r.legacyReader.Read(b) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mb, err := r.stream.ReadMultiBuffer() | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return 0, err | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 	nBytes, _ := mb.Read(b) | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	if !mb.IsEmpty() { | 
					
						
							|  |  |  | 		r.leftOver = mb | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-19 21:27:21 +02:00
										 |  |  | 	return nBytes, nil | 
					
						
							| 
									
										
										
										
											2016-12-09 13:17:34 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-15 22:22:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) { | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	if r.leftOver != nil { | 
					
						
							|  |  |  | 		mb := r.leftOver | 
					
						
							|  |  |  | 		r.leftOver = nil | 
					
						
							|  |  |  | 		return mb, nil | 
					
						
							| 
									
										
										
										
											2017-04-15 22:22:29 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 	return r.stream.ReadMultiBuffer() | 
					
						
							| 
									
										
										
										
											2017-04-15 22:22:29 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func (r *BufferedReader) writeToInternal(writer io.Writer) (int64, error) { | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 	mbWriter := NewWriter(writer) | 
					
						
							|  |  |  | 	totalBytes := int64(0) | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	if r.leftOver != nil { | 
					
						
							| 
									
										
										
										
											2017-11-03 13:19:48 +01:00
										 |  |  | 		totalBytes += int64(r.leftOver.Len()) | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 		if err := mbWriter.WriteMultiBuffer(r.leftOver); err != nil { | 
					
						
							| 
									
										
										
										
											2017-04-19 16:29:36 +02:00
										 |  |  | 			return 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 		mb, err := r.stream.ReadMultiBuffer() | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return totalBytes, err | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-04-19 11:52:27 +02:00
										 |  |  | 		totalBytes += int64(mb.Len()) | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | 		if err := mbWriter.WriteMultiBuffer(mb); err != nil { | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 			return totalBytes, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 22:33:15 +01:00
										 |  |  | func (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) { | 
					
						
							| 
									
										
										
										
											2017-04-17 22:35:20 +02:00
										 |  |  | 	nBytes, err := r.writeToInternal(writer) | 
					
						
							|  |  |  | 	if errors.Cause(err) == io.EOF { | 
					
						
							|  |  |  | 		return nBytes, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nBytes, err | 
					
						
							|  |  |  | } |