github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/internal/traceparser/filebuf/fromreader.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package filebuf 6 7 import ( 8 "bytes" 9 "io" 10 ) 11 12 // implement a Buf version from an io.Reader 13 14 type rbuf struct { 15 buf []byte // contents 16 pos int64 17 seeks, reads int // number of calls. 0 seems right. 18 } 19 20 func (r *rbuf) Stats() Stat { 21 return Stat{r.seeks, r.reads, int64(len(r.buf))} 22 } 23 24 func (r *rbuf) Size() int64 { 25 return int64(len(r.buf)) 26 } 27 28 // FromReader creates a Buf by copying the contents of an io.Reader 29 func FromReader(rd io.Reader) (Buf, error) { 30 r := &rbuf{} 31 x := bytes.NewBuffer(r.buf) 32 _, err := io.Copy(x, rd) 33 r.buf = x.Bytes() 34 if err != nil { 35 return nil, err 36 } 37 return r, nil 38 } 39 40 func (r *rbuf) Close() error { 41 return nil 42 } 43 44 func (r *rbuf) Read(p []byte) (int, error) { 45 n := copy(p, r.buf[r.pos:]) 46 r.pos += int64(n) 47 if n == 0 || n < len(p) { 48 return n, io.EOF 49 } 50 return n, nil 51 } 52 53 func (r *rbuf) Seek(offset int64, whence int) (int64, error) { 54 seekpos := offset 55 switch whence { 56 case io.SeekCurrent: 57 seekpos += int64(r.pos) 58 case io.SeekEnd: 59 seekpos += int64(len(r.buf)) 60 } 61 if seekpos < 0 || seekpos > int64(len(r.buf)) { 62 if seekpos < 0 { 63 r.pos = 0 64 return 0, nil 65 } 66 r.pos = int64(len(r.buf)) 67 return r.pos, nil 68 } 69 r.pos = seekpos 70 return seekpos, nil 71 }