github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/pipes/streams/define.go (about) 1 package streams 2 3 import ( 4 "context" 5 "os" 6 "sync" 7 "sync/atomic" 8 9 "github.com/lmorg/murex/lang/stdio" 10 ) 11 12 func init() { 13 stdio.RegisterPipe("std", newStream) 14 } 15 16 func newStream(_ string) (io stdio.Io, err error) { 17 io = NewStdin() 18 return 19 } 20 21 // Stdin is the default stdio.Io interface. 22 // Despite it's name, this interface can and is used for Stdout and Stderr streams too. 23 type Stdin struct { 24 mutex sync.Mutex 25 ctx context.Context 26 forceClose func() 27 buffer []byte 28 bRead uint64 29 bWritten uint64 30 dependents int32 31 dataType string 32 max int 33 } 34 35 // DefaultMaxBufferSize is the maximum size of buffer for stdin 36 // var DefaultMaxBufferSize = 1024 * 1024 * 1000 // 10 meg 37 var DefaultMaxBufferSize = 1024 * 1024 * 1 // 1 meg 38 39 // NewStdin creates a new stream.Io interface for piping data between processes. 40 // Despite it's name, this interface can and is used for Stdout and Stderr streams too. 41 func NewStdin() (stdin *Stdin) { 42 stdin = new(Stdin) 43 stdin.max = DefaultMaxBufferSize 44 //stdin.buffer = make([]byte, 0, 1024*1024) 45 stdin.ctx, stdin.forceClose = context.WithCancel(context.Background()) 46 return 47 } 48 49 // NewStdinWithContext creates a new stream.Io interface for piping data between processes. 50 // Despite it's name, this interface can and is used for Stdout and Stderr streams too. 51 // This function is also useful as a context aware version of ioutil.ReadAll 52 func NewStdinWithContext(ctx context.Context, forceClose context.CancelFunc) (stdin *Stdin) { 53 stdin = new(Stdin) 54 stdin.max = DefaultMaxBufferSize 55 stdin.ctx = ctx 56 stdin.forceClose = forceClose 57 return 58 } 59 60 func (stdin *Stdin) File() *os.File { 61 return nil 62 } 63 64 // Open the stream.Io interface for another dependant 65 func (stdin *Stdin) Open() { 66 stdin.mutex.Lock() 67 atomic.AddInt32(&stdin.dependents, 1) 68 stdin.mutex.Unlock() 69 } 70 71 // Close the stream.Io interface 72 func (stdin *Stdin) Close() { 73 stdin.mutex.Lock() 74 75 i := atomic.AddInt32(&stdin.dependents, -1) 76 if i < 0 { 77 panic("More closed dependents than open") 78 } 79 80 stdin.mutex.Unlock() 81 } 82 83 // ForceClose forces the stream.Io interface to close. This should only be called by a STDIN reader 84 func (stdin *Stdin) ForceClose() { 85 if stdin.forceClose != nil { 86 stdin.forceClose() 87 } 88 }