From b6e9c0324d17d124f7a179f5c0a549a0c6d5171c Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 19 May 2021 16:23:30 +0200 Subject: [PATCH] widget: make Editor implement io.Seeker, io.Reader and io.WriterTo The WriteTo, Seek, Read methods implement a more efficient access to the Editor content than Text. Signed-off-by: pierre --- widget/buffer.go | 10 ++++++++++ widget/editor.go | 15 +++++++++++++++ widget/editor_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/widget/buffer.go b/widget/buffer.go index e658d56f..50e71756 100644 --- a/widget/buffer.go +++ b/widget/buffer.go @@ -142,6 +142,16 @@ func (e *editBuffer) ReadRune() (rune, int, error) { return r, s, nil } +// WriteTo implements io.WriterTo. +func (e *editBuffer) WriteTo(w io.Writer) (int64, error) { + n1, err := w.Write(e.text[:e.gapstart]) + if err != nil { + return int64(n1), err + } + n2, err := w.Write(e.text[e.gapend:]) + return int64(n1 + n2), err +} + func (e *editBuffer) String() string { var b strings.Builder b.Grow(e.len()) diff --git a/widget/editor.go b/widget/editor.go index 19aef467..2de55374 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -1250,6 +1250,21 @@ func (e *Editor) ClearSelection() { e.caret.end = e.caret.start } +// WriteTo implements io.WriterTo. +func (e *Editor) WriteTo(w io.Writer) (int64, error) { + return e.rr.WriteTo(w) +} + +// Seek implements io.Seeker. +func (e *Editor) Seek(offset int64, whence int) (int64, error) { + return e.rr.Seek(0, io.SeekStart) +} + +// Read implements io.Reader. +func (e *Editor) Read(p []byte) (int, error) { + return e.rr.Read(p) +} + func max(a, b int) int { if a > b { return a diff --git a/widget/editor_test.go b/widget/editor_test.go index 2babdbf6..56e76311 100644 --- a/widget/editor_test.go +++ b/widget/editor_test.go @@ -3,8 +3,10 @@ package widget import ( + "bytes" "fmt" "image" + "io" "math/rand" "reflect" "strings" @@ -476,6 +478,46 @@ func TestSelectMove(t *testing.T) { testKey(key.NameDownArrow) } +func TestEditor_Read(t *testing.T) { + s := "hello world" + buf := make([]byte, len(s)) + e := new(Editor) + e.SetText(s) + + _, err := e.Seek(0, io.SeekStart) + if err != nil { + t.Error(err) + } + n, err := io.ReadFull(e, buf) + if err != nil { + t.Error(err) + } + if got, want := n, len(s); got != want { + t.Errorf("got %d; want %d", got, want) + } + if got, want := string(buf), s; got != want { + t.Errorf("got %q; want %q", got, want) + } +} + +func TestEditor_WriteTo(t *testing.T) { + s := "hello world" + var buf bytes.Buffer + e := new(Editor) + e.SetText(s) + + n, err := io.Copy(&buf, e) + if err != nil { + t.Error(err) + } + if got, want := int(n), len(s); got != want { + t.Errorf("got %d; want %d", got, want) + } + if got, want := buf.String(), s; got != want { + t.Errorf("got %q; want %q", got, want) + } +} + func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 { var w fixed.Int26_6 advances := e.lines[lineNum].Layout.Advances