User defined pipe and redirection operators: Difference between revisions

Content added Content deleted
(→‎{{header|ALGOL 68}}: PROC and OP details)
(→‎{{header|Go}}: Use builtin io.TeeReader; don't special-case CloseWithError(io.EOF))
Line 194: Line 194:
import (
import (
"bufio"
"bufio"
"bytes"
"fmt"
"fmt"
"io"
"io"
Line 205: Line 204:
// fake file system
// fake file system
var fs = make(map[string]string)
var fs = make(map[string]string)

type file struct{ name string }

func (f file) Write(p []byte) (int, error) {
fs[f.name] += string(p)
return len(p), nil
}


// role of > operator
// role of > operator
func toName(name string, src io.Reader) {
func toName(name string, src io.Reader) {
b, _ := ioutil.ReadAll(src)
io.Copy(file{name}, src)
fs[name] = string(b)
}
}


// role of < operator
// role of < operator
func fromName(name string) io.Reader {
func fromName(name string) io.Reader {
return bytes.NewBufferString(fs[name])
return strings.NewReader(fs[name])
}
}


func tee(in io.Reader, name string) io.Reader {
func tee(in io.Reader, name string) io.Reader {
pr, pw := io.Pipe()
return io.TeeReader(in, file{name})
go func() {
b := make([]byte, 512)
for {
readN, readErr := in.Read(b)
if readN > 0 {
writeN, writeErr := pw.Write(b[:readN])
fs[name] += string(b[:writeN])
if writeErr != nil {
return
}
}
switch readErr {
case nil:
continue
case io.EOF:
pw.Close()
default:
pw.CloseWithError(readErr)
}
return
}
}()
return pr
}
}


Line 319: Line 301:
io.WriteString(pw, "\n")
io.WriteString(pw, "\n")
}
}
break
}
}
pw.CloseWithError(readErr)
pw.CloseWithError(readErr)
Line 369: Line 350:
}
}
writeLines(0, rn)
writeLines(0, rn)
pw.CloseWithError(readErr)
if readErr == io.EOF {
pw.Close()
} else {
pw.CloseWithError(readErr)
}
}()
}()
return pr
return pr
Line 382: Line 359:
go func() {
go func() {
b, err := ioutil.ReadAll(in)
b, err := ioutil.ReadAll(in)
if err != nil {
pw.CloseWithError(err)
return
}
if len(b) > 0 {
if len(b) > 0 {
if b[len(b)-1] == '\n' {
if b[len(b)-1] == '\n' {
Line 398: Line 371:
}
}
}
}
pw.Close()
pw.CloseWithError(err)
}()
}()
return pr
return pr