diff --git a/std/io.joke b/std/io.joke index 7ac5f17e8..390d56841 100644 --- a/std/io.joke +++ b/std/io.joke @@ -24,3 +24,10 @@ {:added "1.0" :go "close(f)"} [^Object f]) + +(defn ^String read + "Reads up to n bytes from IOReader r and returns a string of the read bytes. + May return a shorter (or blank) string if EOF is encountered." + {:added "1.3.6" + :go "read(r, n)"} + ^String [^IOReader r ^Int n]) diff --git a/std/io/a_io.go b/std/io/a_io.go index 458c019a4..e60f6e61a 100644 --- a/std/io/a_io.go +++ b/std/io/a_io.go @@ -60,6 +60,24 @@ func __pipe_(_args []Object) Object { return NIL } +var __read__P ProcFn = __read_ +var read_ Proc = Proc{Fn: __read__P, Name: "read_", Package: "std/io"} + +func __read_(_args []Object) Object { + _c := len(_args) + switch { + case _c == 2: + r := ExtractIOReader(_args, 0) + n := ExtractInt(_args, 1) + _res := read(r, n) + return MakeString(_res) + + default: + PanicArity(_c) + } + return NIL +} + func Init() { InternsOrThunks() diff --git a/std/io/a_io_slow_init.go b/std/io/a_io_slow_init.go index 744fa53a1..277965dfb 100644 --- a/std/io/a_io_slow_init.go +++ b/std/io/a_io_slow_init.go @@ -34,4 +34,10 @@ func InternsOrThunks() { with code expecting an IOWriter. Returns a vector [reader, writer].`, "1.0")) + ioNamespace.InternVar("read", read_, + MakeMeta( + NewListFrom(NewVectorFrom(MakeSymbol("r"), MakeSymbol("n"))), + `Reads up to n bytes from IOReader r and returns a string of the read bytes. + May return a shorter (or blank) string if EOF is encountered.`, "1.3.6").Plus(MakeKeyword("tag"), String{S: "String"})) + } diff --git a/std/io/io_native.go b/std/io/io_native.go index c27c38823..06515a0f5 100644 --- a/std/io/io_native.go +++ b/std/io/io_native.go @@ -22,3 +22,12 @@ func close(f Object) Nil { } panic(RT.NewError("Object is not closable: " + f.ToString(false))) } + +func read(r io.Reader, n int) string { + buf := make([]byte, n) + cnt, err := r.Read(buf) + if err != io.EOF { + PanicOnErr(err) + } + return string(buf[:cnt]) +}