github.com/biogo/biogo@v1.0.4/util/wrapper.go (about)

     1  // Copyright ©2013 The bíogo 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 util
     6  
     7  import (
     8  	"io"
     9  )
    10  
    11  // A Wrapper provides hard line wrapping and output limits to an io.Writer.
    12  type Wrapper struct {
    13  	w     io.Writer
    14  	n     int
    15  	width int
    16  	limit int
    17  }
    18  
    19  // NewWrapper returns a Wrapper that causes wraps lines at width bytes and
    20  // limits the number of bytes written to the provided limit.
    21  func NewWrapper(w io.Writer, width, limit int) *Wrapper {
    22  	return &Wrapper{
    23  		w:     w,
    24  		width: width,
    25  		limit: limit,
    26  	}
    27  }
    28  
    29  func min(a, b int) int {
    30  	if a < b {
    31  		return a
    32  	}
    33  	return b
    34  }
    35  
    36  // Write writes the lesser of len(p) or the Writer's limit bytes from p to
    37  // the underlying data stream. It returns the number of bytes written from
    38  // p (0 <= n <= len(p)) and any error encountered that caused the write to
    39  // stop early, except the Writer's own limit.
    40  func (w *Wrapper) Write(p []byte) (n int, err error) {
    41  	if w.limit >= 0 {
    42  		if w.n >= w.limit {
    43  			return 0, nil
    44  		}
    45  		p = p[:min(w.limit-w.n, len(p))]
    46  	}
    47  	if w.width <= 0 {
    48  		return w.w.Write(p)
    49  	}
    50  	var _n int
    51  	for len(p) > 0 {
    52  		if w.n != 0 && w.n%w.width == 0 {
    53  			_n, err = w.w.Write([]byte{'\n'})
    54  			n += _n
    55  			if err != nil {
    56  				return
    57  			}
    58  		}
    59  		_n, err = w.w.Write(p[:min(w.width-w.n%w.width, len(p))])
    60  		n += _n
    61  		w.n += _n
    62  		if err != nil {
    63  			return
    64  		}
    65  		p = p[_n:]
    66  	}
    67  	return n, err
    68  }