github.com/richardwilkes/toolbox@v1.121.0/xio/linewriter.go (about)

     1  // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, version 2.0. If a copy of the MPL was not distributed with
     5  // this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  //
     7  // This Source Code Form is "Incompatible With Secondary Licenses", as
     8  // defined by the Mozilla Public License, version 2.0.
     9  
    10  package xio
    11  
    12  import (
    13  	"bytes"
    14  )
    15  
    16  // LineWriter buffers its input into lines before sending each line to an output function without the trailing line
    17  // feed.
    18  type LineWriter struct {
    19  	buffer *bytes.Buffer
    20  	out    func([]byte)
    21  }
    22  
    23  // NewLineWriter creates a new LineWriter.
    24  func NewLineWriter(out func([]byte)) *LineWriter {
    25  	return &LineWriter{buffer: &bytes.Buffer{}, out: out}
    26  }
    27  
    28  // Write implements the io.Writer interface.
    29  func (w *LineWriter) Write(data []byte) (n int, err error) {
    30  	n = len(data)
    31  	for len(data) > 0 {
    32  		i := bytes.IndexByte(data, '\n')
    33  		if i == -1 {
    34  			_, err = w.buffer.Write(data)
    35  			return n, err
    36  		}
    37  		if i > 0 {
    38  			if _, err = w.buffer.Write(data[:i]); err != nil {
    39  				return n, err
    40  			}
    41  		}
    42  		w.out(w.buffer.Bytes())
    43  		w.buffer.Reset()
    44  		data = data[i+1:]
    45  	}
    46  	return n, nil
    47  }
    48  
    49  // Close implements the io.Closer interface.
    50  func (w *LineWriter) Close() error {
    51  	if w.buffer.Len() > 0 {
    52  		w.out(w.buffer.Bytes())
    53  		w.buffer.Reset()
    54  	}
    55  	return nil
    56  }