bitbucket.org/ai69/amoy@v0.2.3/channel.go (about) 1 package amoy 2 3 import "errors" 4 5 // BlockForever blocks current goroutine forever. 6 func BlockForever() { 7 <-make(chan struct{}) 8 } 9 10 // AccumulatedChannel returns a channel that accumulates values from given channel. 11 func AccumulatedChannel(inCh <-chan []byte, size int) <-chan []byte { 12 if size <= 0 { 13 panic(errors.New("invalid slice size")) 14 } 15 16 outCh := make(chan []byte, 1024) 17 go func(in <-chan []byte, out chan []byte) { 18 // close output channel on exit 19 defer close(out) 20 21 var ( 22 buffer = make([]byte, size, size) 23 pos = 0 24 ) 25 for { 26 select { 27 case data, ok := <-in: 28 // once the input channel is closed, we should dump left and exit 29 if !ok { 30 if pos > 0 { 31 out <- buffer[:pos] 32 } 33 return 34 } 35 36 for dataSize := len(data); dataSize > 0; dataSize = len(data) { 37 // calculate rest space in buffer 38 remainSize := size - pos 39 40 // if data is not bigger than rest, append to buffer 41 if dataSize <= remainSize { 42 copy(buffer[pos:pos+dataSize], data) 43 data = nil 44 pos += dataSize 45 } else { 46 // if data is bigger than rest, append first part to buffer, and keep the rest in data 47 copy(buffer[pos:size], data[:remainSize]) 48 data = data[remainSize:] 49 pos += remainSize 50 } 51 52 // if buffer is full, send to output channel, and reset buffer 53 if pos == size { 54 out <- buffer 55 buffer = make([]byte, size, size) 56 pos = 0 57 } 58 } 59 } 60 } 61 }(inCh, outCh) 62 return outCh 63 }