github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/pipes/streams/utils.go (about) 1 package streams 2 3 import ( 4 "github.com/lmorg/murex/lang/types" 5 ) 6 7 // Shamelessly stolen from https://blog.golang.org/go-slices-usage-and-internals 8 // (it works well so why reinvent the wheel?) 9 func appendBytes(slice []byte, data ...byte) []byte { 10 m := len(slice) 11 n := m + len(data) 12 if n > cap(slice) { // if necessary, reallocate 13 // allocate double what's needed, for future growth. 14 newSlice := make([]byte, (n+1)*2) 15 copy(newSlice, slice) 16 slice = newSlice 17 } 18 slice = slice[0:n] 19 copy(slice[m:n], data) 20 return slice 21 } 22 23 // IsTTY returns false because the Stdin stream is not a pseudo-TTY 24 func (stdin *Stdin) IsTTY() bool { return false } 25 26 // Stats provides real time stream stats. Useful for progress bars etc. 27 func (stdin *Stdin) Stats() (bytesWritten, bytesRead uint64) { 28 //stdin.mutex.RLock() 29 stdin.mutex.Lock() 30 bytesWritten = stdin.bWritten 31 bytesRead = stdin.bRead 32 //stdin.mutex.RUnlock() 33 stdin.mutex.Unlock() 34 return 35 } 36 37 // GetDataType returns the murex data type for the stream.Io interface 38 func (stdin *Stdin) GetDataType() (dt string) { 39 for { 40 select { 41 case <-stdin.ctx.Done(): 42 // This should probably be locked to avoid a data race, but I'm also 43 // quite scared locking it might also cause deadlocks given processes 44 // can be terminated at random points by users. Thus I'm think those 45 // edge cases of a data race will have more desirable side effects 46 // than those edge case of deadlocks. 47 //stdin.dtLock.Lock() 48 dt = stdin.dataType 49 //stdin.dtLock.Unlock() 50 if dt != "" { 51 return dt 52 } 53 return types.Generic 54 default: 55 } 56 57 stdin.mutex.Lock() 58 //stdin.dtLock.Lock() 59 dt = stdin.dataType 60 //stdin.dtLock.Unlock() 61 62 if dt != "" { 63 stdin.mutex.Unlock() 64 return 65 } 66 67 fin := stdin.dependents < 1 68 stdin.mutex.Unlock() 69 70 if fin { 71 return types.Generic 72 } 73 74 //time.Sleep(3 * time.Millisecond) 75 } 76 } 77 78 // SetDataType defines the murex data type for the stream.Io interface 79 func (stdin *Stdin) SetDataType(dt string) { 80 if len(dt) == 0 || dt == types.Null { 81 return 82 } 83 84 //stdin.dtLock.Lock() 85 stdin.mutex.Lock() 86 if stdin.dataType == "" { 87 stdin.dataType = dt 88 } 89 //stdin.dtLock.Unlock() 90 stdin.mutex.Unlock() 91 }