github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/bio/buf.go (about) 1 // Copyright 2015 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 bio implements common I/O abstractions used within the Go toolchain. 6 package bio 7 8 import ( 9 "bufio" 10 "io" 11 "log" 12 "os" 13 ) 14 15 // Reader implements a seekable buffered io.Reader. 16 type Reader struct { 17 f *os.File 18 *bufio.Reader 19 } 20 21 // Writer implements a seekable buffered io.Writer. 22 type Writer struct { 23 f *os.File 24 *bufio.Writer 25 } 26 27 // Create creates the file named name and returns a Writer 28 // for that file. 29 func Create(name string) (*Writer, error) { 30 f, err := os.Create(name) 31 if err != nil { 32 return nil, err 33 } 34 return &Writer{f: f, Writer: bufio.NewWriter(f)}, nil 35 } 36 37 // Open returns a Reader for the file named name. 38 func Open(name string) (*Reader, error) { 39 f, err := os.Open(name) 40 if err != nil { 41 return nil, err 42 } 43 return &Reader{f: f, Reader: bufio.NewReader(f)}, nil 44 } 45 46 func (r *Reader) MustSeek(offset int64, whence int) int64 { 47 if whence == 1 { 48 offset -= int64(r.Buffered()) 49 } 50 off, err := r.f.Seek(offset, whence) 51 if err != nil { 52 log.Fatalf("seeking in output: %v", err) 53 } 54 r.Reset(r.f) 55 return off 56 } 57 58 func (w *Writer) MustSeek(offset int64, whence int) int64 { 59 if err := w.Flush(); err != nil { 60 log.Fatalf("writing output: %v", err) 61 } 62 off, err := w.f.Seek(offset, whence) 63 if err != nil { 64 log.Fatalf("seeking in output: %v", err) 65 } 66 return off 67 } 68 69 func (r *Reader) Offset() int64 { 70 off, err := r.f.Seek(0, 1) 71 if err != nil { 72 log.Fatalf("seeking in output [0, 1]: %v", err) 73 } 74 off -= int64(r.Buffered()) 75 return off 76 } 77 78 func (w *Writer) Offset() int64 { 79 if err := w.Flush(); err != nil { 80 log.Fatalf("writing output: %v", err) 81 } 82 off, err := w.f.Seek(0, 1) 83 if err != nil { 84 log.Fatalf("seeking in output [0, 1]: %v", err) 85 } 86 return off 87 } 88 89 func (r *Reader) Close() error { 90 return r.f.Close() 91 } 92 93 func (w *Writer) Close() error { 94 err := w.Flush() 95 err1 := w.f.Close() 96 if err == nil { 97 err = err1 98 } 99 return err 100 } 101 102 func (r *Reader) File() *os.File { 103 return r.f 104 } 105 106 func (w *Writer) File() *os.File { 107 return w.f 108 } 109 110 // Slice reads the next length bytes of r into a slice. 111 // 112 // This slice may be backed by mmap'ed memory. Currently, this memory 113 // will never be unmapped. The second result reports whether the 114 // backing memory is read-only. 115 func (r *Reader) Slice(length uint64) ([]byte, bool, error) { 116 if length == 0 { 117 return []byte{}, false, nil 118 } 119 120 data, ok := r.sliceOS(length) 121 if ok { 122 return data, true, nil 123 } 124 125 data = make([]byte, length) 126 _, err := io.ReadFull(r, data) 127 if err != nil { 128 return nil, false, err 129 } 130 return data, false, nil 131 } 132 133 // SliceRO returns a slice containing the next length bytes of r 134 // backed by a read-only mmap'd data. If the mmap cannot be 135 // established (limit exceeded, region too small, etc) a nil slice 136 // will be returned. If mmap succeeds, it will never be unmapped. 137 func (r *Reader) SliceRO(length uint64) []byte { 138 data, ok := r.sliceOS(length) 139 if ok { 140 return data 141 } 142 return nil 143 }