Skip to content

Commit

Permalink
Use io.Copy for copying bytes from Buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
fhs authored and rjkroege committed Aug 3, 2019
1 parent 5ca004b commit 85eee89
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 63 deletions.
10 changes: 10 additions & 0 deletions buf.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"io"
"strings"
"unicode/utf8"

"github.com/rjkroege/edwood/internal/runes"
Expand Down Expand Up @@ -31,6 +33,14 @@ func (b *Buffer) Read(q0 int, r []rune) (int, error) {
return n, nil
}

// Reader returns reader for text at [q0, q1).
//
// TODO(fhs): Once Buffer implements io.ReaderAt,
// we can use io.SectionReader instead of this function.
func (b *Buffer) Reader(q0, q1 int) io.Reader {
return strings.NewReader(string((*b)[q0:q1]))
}

func (b *Buffer) ReadC(q int) rune { return (*b)[q] }

func (b *Buffer) Reset() {
Expand Down
18 changes: 4 additions & 14 deletions exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,20 +531,10 @@ func putfile(f *File, q0 int, q1 int, name string) error {
if isapp {
return warnError(nil, "%s not written; file is append only", name)
}
r := make([]rune, RBUFSIZE)
n := 0
for q := q0; q < q1; q += n {
n = q1 - q
if n > RBUFSIZE {
n = RBUFSIZE
}
f.b.Read(q, r[:n])
s := string(r[:n])
io.WriteString(h, s)
nwritten, err := fd.Write([]byte(s))
if err != nil || nwritten != len(s) {
return warnError(nil, "can't write file %s: %v", name, err)
}

_, err = io.Copy(io.MultiWriter(h, fd), f.b.Reader(q0, q1))
if err != nil {
return warnError(nil, "can't write file %s: %v", name, err)
}

// Putting to the same file as the one that we originally read from.
Expand Down
19 changes: 7 additions & 12 deletions look_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,10 @@ func TestLook3Message(t *testing.T) {
want.Attr = &plumb.Attribute{Name: "click", Value: "3"}
}

text := textWithSelection(tc.text)
var text Text
textSetSelection(&text, tc.text)
text.w = tc.w
got, err := look3Message(text, 4, 4)
got, err := look3Message(&text, 4, 4)
if tc.name == "Error" {
wantErr := "empty selection"
if err.Error() != wantErr {
Expand All @@ -159,7 +160,7 @@ func TestLook3Message(t *testing.T) {
}
}

func textWithSelection(buf string) *Text {
func textSetSelection(t *Text, buf string) {
b := []rune(buf)
popRune := func(r rune) int {
q := runes.IndexRune(b, r)
Expand All @@ -170,13 +171,7 @@ func textWithSelection(buf string) *Text {
return q
}

q0 := popRune('«')
q1 := popRune('»')
return &Text{
file: &File{
b: Buffer(b),
},
q0: q0,
q1: q1,
}
t.q0 = popRune('«')
t.q1 = popRune('»')
t.file = &File{b: Buffer(b)}
}
2 changes: 1 addition & 1 deletion wind.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Window struct {
nopen [QMAX]byte
nomark bool
wrselrange Range
rdselfd *os.File
rdselfd *os.File // temporary file for rdsel read requests

col *Column
eventx *Xfid
Expand Down
49 changes: 13 additions & 36 deletions xfid.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,12 @@ out:
func xfidopen(x *Xfid) {
// log.Println("xfidopen", x)
// defer log.Println("xfidopen done")
var (
fc plan9.Fcall
w *Window
t *Text
n int
q0, q1 int
q uint64
)
var fc plan9.Fcall

w = x.f.w
q = FILE(x.f.qid)
w := x.f.w
q := FILE(x.f.qid)
if w != nil {
t = &w.body
t := &w.body
w.Lock('E')
switch q {
case QWaddr:
Expand Down Expand Up @@ -134,22 +127,10 @@ func xfidopen(x *Xfid) {
}
os.Remove(w.rdselfd.Name()) // tempfile ORCLOSE
w.nopen[q]++
q0 = t.q0
q1 = t.q1
r := make([]rune, RBUFSIZE)
for q0 < q1 {
n = q1 - q0
if n > RBUFSIZE {
n = RBUFSIZE
}
t.file.b.Read(q0, r[:n])
s := string(r[:n])
n, err = w.rdselfd.Write([]byte(s))
if err != nil || n != len(s) {
warning(nil, fmt.Sprintf("can't write temp file for pipe command %v\n", err))
break
}
q0 += n

_, err = io.Copy(w.rdselfd, t.file.b.Reader(t.q0, t.q1))
if err != nil {
warning(nil, fmt.Sprintf("can't write temp file for pipe command %v\n", err))
}
case QWwrsel:
w.nopen[q]++
Expand Down Expand Up @@ -196,13 +177,9 @@ func xfidopen(x *Xfid) {
func xfidclose(x *Xfid) {
// log.Println("xfidclose", x)
// defer log.Println("xfidclose done")
var (
fc plan9.Fcall
w *Window
q uint64
t *Text
)
w = x.f.w
var fc plan9.Fcall

w := x.f.w
x.f.busy = false
x.f.w = nil
if !x.f.open {
Expand All @@ -213,7 +190,7 @@ func xfidclose(x *Xfid) {
return
}

q = FILE(x.f.qid)
q := FILE(x.f.qid)
x.f.open = false
if w != nil {
// We need to lock row here before locking window (just like mousethread)
Expand Down Expand Up @@ -254,7 +231,7 @@ func xfidclose(x *Xfid) {
w.rdselfd = nil
case QWwrsel:
w.nomark = false
t = &w.body
t := &w.body
t.Show(min((w.wrselrange.q0), t.Nc()), min((w.wrselrange.q1), t.Nc()), true)
t.ScrDraw(t.fr.GetFrameFillStatus().Nchars)
case QWeditout:
Expand Down
61 changes: 61 additions & 0 deletions xfid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,67 @@ func (mr *mockResponder) respond(x *Xfid, t *plan9.Fcall, err error) *Xfid {

func (mr *mockResponder) msize() int { return 8192 }

func TestQWrdsel(t *testing.T) {
const wantSel = "εxαmple"

w := &Window{
body: Text{fr: &MockFrame{}},
tag: Text{
fr: &MockFrame{},
file: &File{},
},
col: new(Column),
}
textSetSelection(&w.body, "This is an «"+wantSel+"» sentence.\n")
w.body.file.text = []*Text{&w.body}
w.tag.file.text = []*Text{&w.tag}
w.body.w = w
w.tag.w = w
w.ref.Inc()
mr := &mockResponder{}
qid := plan9.Qid{
Path: QID(0, QWrdsel),
}
x := &Xfid{
f: &Fid{
qid: qid,
w: w,
},
fs: mr,
}

t.Run("xfidopen", func(t *testing.T) {
xfidopen(x)
if mr.err != nil {
t.Fatalf("got error %v; want nil", mr.err)
}
if got, want := mr.fcall.Qid, qid; !cmp.Equal(got, want) {
t.Fatalf("Qid.Path is %v; want %v", got, want)
}
if !x.f.open {
t.Fatalf("Fid not open")
}
})

t.Run("xfidread", func(t *testing.T) {
x.fcall.Count = 64
xfidread(x)
if got, want := mr.fcall.Count, uint32(len(wantSel)); got != want {
t.Errorf("fcall.Count is %v; want %v", got, want)
}
if got, want := string(mr.fcall.Data), wantSel; got != want {
t.Errorf("fcall.Data is %q; want %q\n", got, want)
}
})

t.Run("xfidclose", func(t *testing.T) {
xfidclose(x)
if w.rdselfd != nil {
t.Errorf("w.rdselfd is not nil")
}
})
}

func TestXfidwriteQWaddr(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down

0 comments on commit 85eee89

Please sign in to comment.