github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/streamreader.go (about) 1 package sdk 2 3 import ( 4 "context" 5 "io" 6 7 "github.com/0chain/errors" 8 ) 9 10 // Example implementation of a reader 11 type DataChan struct { 12 data []byte 13 err error 14 } 15 16 func NewStreamReader(dataChan chan *DataChan) *StreamReader { 17 return &StreamReader{dataChan} 18 } 19 20 type StreamReader struct { 21 dataChan chan *DataChan 22 } 23 24 // Client should always send bytes equal to less than chunkDataSizePerRead 25 func (r *StreamReader) Read(p []byte) (int, error) { 26 recieveData, ok := <-r.dataChan 27 if !ok && recieveData == nil { 28 return 0, io.EOF 29 } 30 if recieveData.err != nil { 31 return 0, recieveData.err 32 } 33 if len(recieveData.data) > len(p) { 34 return 0, io.ErrShortBuffer 35 } 36 copy(p, recieveData.data) 37 return len(recieveData.data), nil 38 } 39 40 func StartWriteWorker(ctx context.Context, source io.Reader, dataChan chan *DataChan, chunkDataSizePerRead int64) { 41 defer close(dataChan) 42 for { 43 select { 44 case <-ctx.Done(): 45 return 46 default: 47 } 48 data := make([]byte, chunkDataSizePerRead) 49 dataToSend := &DataChan{} 50 n, err := source.Read(data) 51 if n < int(chunkDataSizePerRead) { 52 data = data[:n] 53 } 54 if err != nil && !errors.Is(err, io.EOF) { 55 dataToSend.err = err 56 dataChan <- dataToSend 57 return 58 } 59 dataToSend.data = data 60 dataChan <- dataToSend 61 if n < int(chunkDataSizePerRead) { 62 return 63 } 64 } 65 66 }