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  }