123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- // Copyright 2015 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Package bio implements common I/O abstractions used within the Go toolchain.
- package bio
- import (
- "bufio"
- "io"
- "log"
- "os"
- )
- // Reader implements a seekable buffered io.Reader.
- type Reader struct {
- f *os.File
- *bufio.Reader
- }
- // Writer implements a seekable buffered io.Writer.
- type Writer struct {
- f *os.File
- *bufio.Writer
- }
- // Create creates the file named name and returns a Writer
- // for that file.
- func Create(name string) (*Writer, error) {
- f, err := os.Create(name)
- if err != nil {
- return nil, err
- }
- return &Writer{f: f, Writer: bufio.NewWriter(f)}, nil
- }
- // Open returns a Reader for the file named name.
- func Open(name string) (*Reader, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- return NewReader(f), nil
- }
- // NewReader returns a Reader from an open file.
- func NewReader(f *os.File) *Reader {
- return &Reader{f: f, Reader: bufio.NewReader(f)}
- }
- func (r *Reader) MustSeek(offset int64, whence int) int64 {
- if whence == 1 {
- offset -= int64(r.Buffered())
- }
- off, err := r.f.Seek(offset, whence)
- if err != nil {
- log.Fatalf("seeking in output: %v", err)
- }
- r.Reset(r.f)
- return off
- }
- func (w *Writer) MustSeek(offset int64, whence int) int64 {
- if err := w.Flush(); err != nil {
- log.Fatalf("writing output: %v", err)
- }
- off, err := w.f.Seek(offset, whence)
- if err != nil {
- log.Fatalf("seeking in output: %v", err)
- }
- return off
- }
- func (r *Reader) Offset() int64 {
- off, err := r.f.Seek(0, 1)
- if err != nil {
- log.Fatalf("seeking in output [0, 1]: %v", err)
- }
- off -= int64(r.Buffered())
- return off
- }
- func (w *Writer) Offset() int64 {
- if err := w.Flush(); err != nil {
- log.Fatalf("writing output: %v", err)
- }
- off, err := w.f.Seek(0, 1)
- if err != nil {
- log.Fatalf("seeking in output [0, 1]: %v", err)
- }
- return off
- }
- func (r *Reader) Close() error {
- return r.f.Close()
- }
- func (w *Writer) Close() error {
- err := w.Flush()
- err1 := w.f.Close()
- if err == nil {
- err = err1
- }
- return err
- }
- func (r *Reader) File() *os.File {
- return r.f
- }
- func (w *Writer) File() *os.File {
- return w.f
- }
- // Slice reads the next length bytes of r into a slice.
- //
- // This slice may be backed by mmap'ed memory. Currently, this memory
- // will never be unmapped. The second result reports whether the
- // backing memory is read-only.
- func (r *Reader) Slice(length uint64) ([]byte, bool, error) {
- if length == 0 {
- return []byte{}, false, nil
- }
- data, ok := r.sliceOS(length)
- if ok {
- return data, true, nil
- }
- data = make([]byte, length)
- _, err := io.ReadFull(r, data)
- if err != nil {
- return nil, false, err
- }
- return data, false, nil
- }
- // SliceRO returns a slice containing the next length bytes of r
- // backed by a read-only mmap'd data. If the mmap cannot be
- // established (limit exceeded, region too small, etc) a nil slice
- // will be returned. If mmap succeeds, it will never be unmapped.
- func (r *Reader) SliceRO(length uint64) []byte {
- data, ok := r.sliceOS(length)
- if ok {
- return data
- }
- return nil
- }
|