diff --git a/api.go b/api.go index d556589..eb1a49b 100644 --- a/api.go +++ b/api.go @@ -23,6 +23,7 @@ import ( "syscall" "time" + "hilbish/sink" "hilbish/util" rt "github.com/arnodel/golua/runtime" @@ -133,6 +134,9 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) { pluginModule := moduleLoader(rtm) mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule)) + sinkModule := sink.Loader(l) + mod.Set(rt.StringValue("sink"), rt.TableValue(sinkModule)) + return rt.TableValue(mod), nil } diff --git a/lua.go b/lua.go index 9cefada..00398ea 100644 --- a/lua.go +++ b/lua.go @@ -4,7 +4,6 @@ import ( "fmt" "os" - "hilbish/sink" "hilbish/util" "hilbish/golibs/bait" "hilbish/golibs/commander" @@ -25,7 +24,6 @@ func luaInit() { MessageHandler: debuglib.Traceback, }) lib.LoadAll(l) - sink.SetupSinkType(l) lib.LoadLibs(l, hilbishLoader) // yes this is stupid, i know diff --git a/sink/sink.go b/sink/sink.go index be8b7d1..4899d89 100644 --- a/sink/sink.go +++ b/sink/sink.go @@ -2,6 +2,7 @@ package sink import ( "bufio" + "bytes" "fmt" "io" "os" @@ -18,14 +19,13 @@ var sinkMetaKey = rt.StringValue("hshsink") // A sink is a structure that has input and/or output to/from // a desination. type Sink struct{ - writer *bufio.Writer - reader *bufio.Reader + rw *bufio.ReadWriter file *os.File UserData *rt.UserData autoFlush bool } -func SetupSinkType(rtm *rt.Runtime) { +func Loader(rtm *rt.Runtime) *rt.Table { sinkMeta := rt.NewTable() sinkMethods := rt.NewTable() @@ -65,9 +65,24 @@ func SetupSinkType(rtm *rt.Runtime) { sinkMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(sinkIndex, "__index", 2, false))) rtm.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta)) + + exports := map[string]util.LuaExport{ + "new": {luaSinkNew, 0, false}, + } + + mod := rt.NewTable() + util.SetExports(rtm, mod, exports) + + return mod } +func luaSinkNew(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + snk := NewSink(t.Runtime, new(bytes.Buffer)) + + return c.PushingNext1(t.Runtime, rt.UserDataValue(snk.UserData)), nil +} + // #member // readAll() -> string // --- @returns string @@ -84,7 +99,7 @@ func luaSinkReadAll(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { lines := []string{} for { - line, err := s.reader.ReadString('\n') + line, err := s.rw.ReadString('\n') if err != nil { if err == io.EOF { break @@ -113,7 +128,7 @@ func luaSinkRead(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - str, _ := s.reader.ReadString('\n') + str, _ := s.rw.ReadString('\n') return c.PushingNext1(t.Runtime, rt.StringValue(str)), nil } @@ -135,9 +150,9 @@ func luaSinkWrite(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - s.writer.Write([]byte(data)) + s.rw.Write([]byte(data)) if s.autoFlush { - s.writer.Flush() + s.rw.Flush() } return c.Next(), nil @@ -160,9 +175,9 @@ func luaSinkWriteln(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - s.writer.Write([]byte(data + "\n")) + s.rw.Write([]byte(data + "\n")) if s.autoFlush { - s.writer.Flush() + s.rw.Flush() } return c.Next(), nil @@ -181,7 +196,7 @@ func luaSinkFlush(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - s.writer.Flush() + s.rw.Flush() return c.Next(), nil } @@ -212,9 +227,22 @@ func luaSinkAutoFlush(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return c.Next(), nil } +func NewSink(rtm *rt.Runtime, rw io.ReadWriter) *Sink { + s := &Sink{ + rw: bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)), + } + s.UserData = sinkUserData(rtm, s) + + if f, ok := rw.(*os.File); ok { + s.file = f + } + + return s +} + func NewSinkInput(rtm *rt.Runtime, r io.Reader) *Sink { s := &Sink{ - reader: bufio.NewReader(r), + rw: bufio.NewReadWriter(bufio.NewReader(r), nil), } s.UserData = sinkUserData(rtm, s) @@ -227,7 +255,7 @@ func NewSinkInput(rtm *rt.Runtime, r io.Reader) *Sink { func NewSinkOutput(rtm *rt.Runtime, w io.Writer) *Sink { s := &Sink{ - writer: bufio.NewWriter(w), + rw: bufio.NewReadWriter(nil, bufio.NewWriter(w)), autoFlush: true, } s.UserData = sinkUserData(rtm, s)