| 
					
				 | 
			
			
				@@ -0,0 +1,94 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package net 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"bytes" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"crypto/rand" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"io" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"io/ioutil" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"testing" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/v2ray/v2ray-core/testing/unit" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestReaderAndWrite(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert := unit.Assert(t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size := 1024 * 1024 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	buffer := make([]byte, size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	nBytes, err := rand.Read(buffer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Int(nBytes).Equals(len(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Error(err).IsNil() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	readerBuffer := bytes.NewReader(buffer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	writerBuffer := bytes.NewBuffer(make([]byte, 0, size)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	transportChan := make(chan []byte, size/bufferSize*10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	err = ReaderToChan(transportChan, readerBuffer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Error(err).Equals(io.EOF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	close(transportChan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	err = ChanToWriter(writerBuffer, transportChan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Error(err).IsNil() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Bytes(buffer).Equals(writerBuffer.Bytes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type StaticReader struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	total   int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	current int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (reader *StaticReader) Read(b []byte) (size int, err error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size = len(b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if size > reader.total-reader.current { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		size = reader.total - reader.current 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	//rand.Read(b[:size]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	reader.current += size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if reader.current == reader.total { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = io.EOF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func BenchmarkTransport(b *testing.B) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size := 1024 * 1024 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for i := 0; i < b.N; i++ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		transportChanA := make(chan []byte, 128) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		transportChanB := make(chan []byte, 128) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		readerA := &StaticReader{size, 0} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		readerB := &StaticReader{size, 0} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		writerA := ioutil.Discard 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		writerB := ioutil.Discard 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		finishA := make(chan bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		finishB := make(chan bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		go func() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ChanToWriter(writerA, transportChanA) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			close(finishA) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		go func() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ReaderToChan(transportChanA, readerA) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			close(transportChanA) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		go func() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ChanToWriter(writerB, transportChanB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			close(finishB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		go func() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ReaderToChan(transportChanB, readerB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			close(transportChanB) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<-transportChanA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<-transportChanB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |