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

     1  package file
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"errors"
     7  	"os"
     8  	"strings"
     9  )
    10  
    11  type wofile struct {
    12  	*os.File
    13  	bw     *bufio.Writer
    14  	mode   int
    15  	closed bool
    16  	std    bool
    17  	probe  [1]byte // workaround for https://github.com/golang/go/issues/19122
    18  }
    19  
    20  func (wo *wofile) IsClosed() bool {
    21  	return wo.closed
    22  }
    23  
    24  func (wo *wofile) Close() error {
    25  	if wo.std {
    26  		return errors.New("cannot close standard file")
    27  	}
    28  
    29  	if err := wo.bw.Flush(); err != nil {
    30  		return err
    31  	}
    32  
    33  	if err := wo.File.Close(); err != nil {
    34  		return err
    35  	}
    36  
    37  	wo.closed = true
    38  
    39  	return nil
    40  }
    41  
    42  func (wo *wofile) Write(p []byte) (nn int, err error) {
    43  	switch wo.mode {
    44  	case IONBF:
    45  		nn, err = wo.File.Write(p)
    46  	case IOFBF:
    47  		nn, err = wo.bw.Write(p)
    48  	case IOLBF:
    49  		i := bytes.LastIndexByte(p, '\n')
    50  		if i == -1 {
    51  			nn, err = wo.bw.Write(p)
    52  		} else {
    53  			nn, err = wo.bw.Write(p[:i+1])
    54  			if err != nil {
    55  				return
    56  			}
    57  			err = wo.bw.Flush()
    58  			if err != nil {
    59  				return
    60  			}
    61  
    62  			nn, err = wo.bw.Write(p[i+1:])
    63  		}
    64  	}
    65  
    66  	return
    67  }
    68  
    69  func (wo *wofile) WriteString(s string) (nn int, err error) {
    70  	switch wo.mode {
    71  	case IONBF:
    72  		nn, err = wo.File.WriteString(s)
    73  	case IOFBF:
    74  		nn, err = wo.bw.WriteString(s)
    75  	case IOLBF:
    76  		i := strings.LastIndexByte(s, '\n')
    77  		if i == -1 {
    78  			nn, err = wo.bw.WriteString(s)
    79  		} else {
    80  			nn, err = wo.bw.WriteString(s[:i+1])
    81  			if err != nil {
    82  				return
    83  			}
    84  			err = wo.bw.Flush()
    85  			if err != nil {
    86  				return
    87  			}
    88  
    89  			nn, err = wo.bw.WriteString(s[i+1:])
    90  		}
    91  	}
    92  
    93  	return
    94  }
    95  
    96  func (wo *wofile) Flush() error {
    97  	return wo.bw.Flush()
    98  }
    99  
   100  func (wo *wofile) UnreadByte() error {
   101  	return os.ErrInvalid
   102  }
   103  
   104  func (wo *wofile) ReadByte() (c byte, err error) {
   105  	_, err = wo.Read(wo.probe[:])
   106  
   107  	return 0, err
   108  }
   109  
   110  func (wo *wofile) ReadBytes(delim byte) (line []byte, err error) {
   111  	_, err = wo.Read(wo.probe[:])
   112  
   113  	return nil, err
   114  }
   115  
   116  func (wo *wofile) Seek(offset int64, whence int) (n int64, err error) {
   117  	if err := wo.bw.Flush(); err != nil {
   118  		return 0, err
   119  	}
   120  
   121  	return wo.File.Seek(offset, whence)
   122  }
   123  
   124  func (wo *wofile) Setvbuf(mode int, size int) (err error) {
   125  	err = wo.bw.Flush()
   126  	if err != nil {
   127  		return
   128  	}
   129  
   130  	wo.mode = mode
   131  
   132  	if size > 0 {
   133  		wo.bw = bufio.NewWriterSize(wo.File, size)
   134  	}
   135  
   136  	return
   137  }