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  }