github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/pipes/streams/read.go (about) 1 package streams 2 3 import ( 4 "bufio" 5 "context" 6 "fmt" 7 "io" 8 9 "github.com/lmorg/murex/config" 10 "github.com/lmorg/murex/lang/stdio" 11 "github.com/lmorg/murex/utils" 12 ) 13 14 // Read is the standard Reader interface Read() method. 15 func (stdin *Stdin) Read(p []byte) (i int, err error) { 16 for { 17 select { 18 case <-stdin.ctx.Done(): 19 return 0, io.EOF 20 default: 21 } 22 23 stdin.mutex.Lock() 24 l := len(stdin.buffer) 25 deps := stdin.dependents 26 27 stdin.mutex.Unlock() 28 29 if l == 0 { 30 if deps < 1 { 31 return 0, io.EOF 32 } 33 //time.Sleep(3 * time.Millisecond) 34 continue 35 } 36 37 break 38 } 39 40 stdin.mutex.Lock() 41 42 if len(p) >= len(stdin.buffer) { 43 i = len(stdin.buffer) 44 copy(p, stdin.buffer) 45 46 stdin.buffer = make([]byte, 0) 47 48 } else { 49 i = len(p) 50 copy(p, stdin.buffer[:i]) 51 52 stdin.buffer = stdin.buffer[i:] 53 } 54 55 stdin.bRead += uint64(i) 56 stdin.mutex.Unlock() 57 58 return i, err 59 } 60 61 // ReadLine returns each line in the stream as a callback function 62 func (stdin *Stdin) ReadLine(callback func([]byte)) error { 63 scanner := bufio.NewScanner(stdin) 64 for scanner.Scan() { 65 b := scanner.Bytes() 66 67 callback(append(b, utils.NewLineByte...)) 68 } 69 70 err := scanner.Err() 71 if err != nil { 72 return fmt.Errorf("error in stdin.ReadLine: %s", err.Error()) 73 } 74 return nil 75 } 76 77 // ReadAll reads everything and dump it into one byte slice. 78 func (stdin *Stdin) ReadAll() ([]byte, error) { 79 stdin.mutex.Lock() 80 stdin.max = 0 81 stdin.mutex.Unlock() 82 83 for { 84 select { 85 case <-stdin.ctx.Done(): 86 goto read 87 default: 88 } 89 90 stdin.mutex.Lock() 91 closed := stdin.dependents < 1 92 93 stdin.mutex.Unlock() 94 95 if closed { 96 break 97 } 98 } 99 100 read: 101 stdin.mutex.Lock() 102 stdin.bRead = uint64(len(stdin.buffer)) 103 b := stdin.buffer 104 stdin.mutex.Unlock() 105 return b, nil 106 } 107 108 // ReadArray returns a data type-specific array returned via a callback function 109 func (stdin *Stdin) ReadArray(ctx context.Context, callback func([]byte)) error { 110 return stdio.ReadArray(ctx, stdin, callback) 111 } 112 113 // ReadArrayWithType returns an array like "ReadArray" plus data type via a callback function 114 func (stdin *Stdin) ReadArrayWithType(ctx context.Context, callback func(interface{}, string)) error { 115 return stdio.ReadArrayWithType(ctx, stdin, callback) 116 } 117 118 // ReadMap returns a data type-specific key/values returned via a callback function 119 func (stdin *Stdin) ReadMap(config *config.Config, callback func(*stdio.Map)) error { 120 return stdio.ReadMap(stdin, config, callback) 121 } 122 123 // WriteTo reads from the stream.Io interface and writes to a destination 124 // io.Writer interface 125 func (stdin *Stdin) WriteTo(w io.Writer) (int64, error) { 126 return stdio.WriteTo(stdin, w) 127 }