Source file src/cmd/internal/bio/buf.go

     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 NewReader(f), nil
    44  }
    45  
    46  // NewReader returns a Reader from an open file.
    47  func NewReader(f *os.File) *Reader {
    48  	return &Reader{f: f, Reader: bufio.NewReader(f)}
    49  }
    50  
    51  func (r *Reader) MustSeek(offset int64, whence int) int64 {
    52  	if whence == 1 {
    53  		offset -= int64(r.Buffered())
    54  	}
    55  	off, err := r.f.Seek(offset, whence)
    56  	if err != nil {
    57  		log.Fatalf("seeking in output: %v", err)
    58  	}
    59  	r.Reset(r.f)
    60  	return off
    61  }
    62  
    63  func (w *Writer) MustSeek(offset int64, whence int) int64 {
    64  	if err := w.Flush(); err != nil {
    65  		log.Fatalf("writing output: %v", err)
    66  	}
    67  	off, err := w.f.Seek(offset, whence)
    68  	if err != nil {
    69  		log.Fatalf("seeking in output: %v", err)
    70  	}
    71  	return off
    72  }
    73  
    74  func (r *Reader) Offset() int64 {
    75  	off, err := r.f.Seek(0, 1)
    76  	if err != nil {
    77  		log.Fatalf("seeking in output [0, 1]: %v", err)
    78  	}
    79  	off -= int64(r.Buffered())
    80  	return off
    81  }
    82  
    83  func (w *Writer) Offset() int64 {
    84  	if err := w.Flush(); err != nil {
    85  		log.Fatalf("writing output: %v", err)
    86  	}
    87  	off, err := w.f.Seek(0, 1)
    88  	if err != nil {
    89  		log.Fatalf("seeking in output [0, 1]: %v", err)
    90  	}
    91  	return off
    92  }
    93  
    94  func (r *Reader) Close() error {
    95  	return r.f.Close()
    96  }
    97  
    98  func (w *Writer) Close() error {
    99  	err := w.Flush()
   100  	err1 := w.f.Close()
   101  	if err == nil {
   102  		err = err1
   103  	}
   104  	return err
   105  }
   106  
   107  func (r *Reader) File() *os.File {
   108  	return r.f
   109  }
   110  
   111  func (w *Writer) File() *os.File {
   112  	return w.f
   113  }
   114  
   115  // Slice reads the next length bytes of r into a slice.
   116  //
   117  // This slice may be backed by mmap'ed memory. Currently, this memory
   118  // will never be unmapped. The second result reports whether the
   119  // backing memory is read-only.
   120  func (r *Reader) Slice(length uint64) ([]byte, bool, error) {
   121  	if length == 0 {
   122  		return []byte{}, false, nil
   123  	}
   124  
   125  	data, ok := r.sliceOS(length)
   126  	if ok {
   127  		return data, true, nil
   128  	}
   129  
   130  	data = make([]byte, length)
   131  	_, err := io.ReadFull(r, data)
   132  	if err != nil {
   133  		return nil, false, err
   134  	}
   135  	return data, false, nil
   136  }
   137  
   138  // SliceRO returns a slice containing the next length bytes of r
   139  // backed by a read-only mmap'd data. If the mmap cannot be
   140  // established (limit exceeded, region too small, etc) a nil slice
   141  // will be returned. If mmap succeeds, it will never be unmapped.
   142  func (r *Reader) SliceRO(length uint64) []byte {
   143  	data, ok := r.sliceOS(length)
   144  	if ok {
   145  		return data
   146  	}
   147  	return nil
   148  }
   149  

View as plain text