lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xbufio/xbufio.go (about)

     1  // Copyright (C) 2017-2019  Nexedi SA and Contributors.
     2  //                          Kirill Smelkov <kirr@nexedi.com>
     3  //
     4  // This program is free software: you can Use, Study, Modify and Redistribute
     5  // it under the terms of the GNU General Public License version 3, or (at your
     6  // option) any later version, as published by the Free Software Foundation.
     7  //
     8  // You can also Link and Combine this program with other software covered by
     9  // the terms of any of the Free Software licenses or any of the Open Source
    10  // Initiative approved licenses and Convey the resulting work. Corresponding
    11  // source of such a combination shall include the source code for all other
    12  // software used.
    13  //
    14  // This program is distributed WITHOUT ANY WARRANTY; without even the implied
    15  // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    16  //
    17  // See COPYING file for full licensing terms.
    18  // See https://www.nexedi.com/licensing for rationale and options.
    19  
    20  // Package xbufio provides addons to std package bufio.
    21  package xbufio
    22  
    23  import (
    24  	"bufio"
    25  	"context"
    26  	"io"
    27  
    28  	"lab.nexedi.com/kirr/go123/xio"
    29  )
    30  
    31  // Reader is a bufio.Reader that also reports current logical position in input stream.
    32  type Reader struct {
    33  	*bufio.Reader
    34  	cr *xio.CountedReader
    35  }
    36  
    37  func NewReader(r io.Reader) *Reader {
    38  	// idempotent(Reader)
    39  	if r, ok := r.(*Reader); ok {
    40  		return r
    41  	}
    42  
    43  	// idempotent(xio.CountedReader)
    44  	xr := xio.WithCtxR(r)
    45  	cr, ok := xr.(*xio.CountedReader)
    46  	if !ok {
    47  		cr = xio.CountReader(xr)
    48  	}
    49  
    50  	return &Reader{bufio.NewReader(xio.BindCtxR(cr, context.Background())), cr}
    51  }
    52  
    53  // InputOffset returns current logical position in input stream.
    54  func (r *Reader) InputOffset() int64 {
    55  	return r.cr.InputOffset() - int64(r.Reader.Buffered())
    56  }