github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/internal/file/rofile.go (about)

     1  package file
     2  
     3  import (
     4  	"bufio"
     5  	"errors"
     6  	"os"
     7  )
     8  
     9  type rofile struct {
    10  	*os.File
    11  	br     *bufio.Reader
    12  	off    int64
    13  	closed bool
    14  	std    bool
    15  }
    16  
    17  func (ro *rofile) IsClosed() bool {
    18  	return ro.closed
    19  }
    20  
    21  func (ro *rofile) Close() error {
    22  	if ro.std {
    23  		return errors.New("cannot close standard file")
    24  	}
    25  
    26  	if err := ro.File.Close(); err != nil {
    27  		return err
    28  	}
    29  
    30  	ro.closed = true
    31  
    32  	return nil
    33  }
    34  
    35  func (ro *rofile) Flush() error {
    36  	return os.ErrInvalid
    37  }
    38  
    39  func (ro *rofile) UnreadByte() error {
    40  	err := ro.br.UnreadByte()
    41  	if err == nil {
    42  		ro.off--
    43  	}
    44  	return err
    45  }
    46  
    47  func (ro *rofile) ReadByte() (c byte, err error) {
    48  	c, err = ro.br.ReadByte()
    49  	if err == nil {
    50  		ro.off++
    51  	}
    52  	return c, err
    53  }
    54  
    55  func (ro *rofile) Read(p []byte) (n int, err error) {
    56  	n, err = ro.br.Read(p)
    57  	ro.off += int64(n)
    58  	return n, err
    59  }
    60  
    61  func (ro *rofile) ReadBytes(delim byte) (line []byte, err error) {
    62  	line, err = ro.br.ReadBytes(delim)
    63  	ro.off += int64(len(line))
    64  	return line, err
    65  }
    66  
    67  func (ro *rofile) Seek(offset int64, whence int) (n int64, err error) {
    68  	switch whence {
    69  	case 0:
    70  		if ro.off <= offset && offset <= ro.off+int64(ro.br.Buffered()) {
    71  			ro.br.Discard(int(offset - ro.off))
    72  			ro.off = offset
    73  		} else {
    74  			ro.off, err = ro.File.Seek(offset, 0)
    75  			ro.br.Reset(ro.File)
    76  		}
    77  	case 1:
    78  		if 0 <= offset && offset <= int64(ro.br.Buffered()) {
    79  			ro.br.Discard(int(offset))
    80  			ro.off += offset
    81  		} else {
    82  			ro.off, err = ro.File.Seek(ro.off+offset, 0)
    83  			ro.br.Reset(ro.File)
    84  		}
    85  	case 2:
    86  		ro.off, err = ro.File.Seek(offset, 2)
    87  		ro.br.Reset(ro.File)
    88  	}
    89  
    90  	n = ro.off
    91  
    92  	return
    93  }
    94  
    95  func (ro *rofile) Setvbuf(mode int, size int) (err error) {
    96  	_, err = ro.File.Seek(ro.off, 0)
    97  
    98  	if size > 0 {
    99  		ro.br = bufio.NewReaderSize(ro.File, size)
   100  	}
   101  
   102  	return
   103  }