github.com/influx6/npkg@v0.8.8/nbytes/seeker/seeker.go (about)

     1  package seeker
     2  
     3  // BufferedPeeker implements a custom buffer structure which
     4  // allows peeks, reversal of index location of provided byte slice.
     5  // It helps to minimize memory allocation.
     6  type BufferedPeeker struct {
     7  	l int
     8  	d []byte
     9  	c int
    10  }
    11  
    12  // NewBufferedPeeker returns new instance of BufferedPeeker.
    13  func NewBufferedPeeker(d []byte) *BufferedPeeker {
    14  	return &BufferedPeeker{
    15  		d: d,
    16  		l: len(d),
    17  	}
    18  }
    19  
    20  // Reset sets giving buffers memory slice and sets appropriate
    21  // settings.
    22  func (b *BufferedPeeker) Reset(bm []byte) {
    23  	b.d = bm
    24  	b.l = len(bm)
    25  	b.c = 0
    26  }
    27  
    28  // Length returns total length of slice.
    29  func (b *BufferedPeeker) Length() int {
    30  	return len(b.d)
    31  }
    32  
    33  // Area returns current available length from current index.
    34  func (b *BufferedPeeker) Area() int {
    35  	return len(b.d[b.c:])
    36  }
    37  
    38  // Reverse reverses previous index back a giving length
    39  // It reverse any length back to 0 if length provided exceeds
    40  // underline slice length.
    41  func (b *BufferedPeeker) Reverse(n int) {
    42  	back := b.c - n
    43  	if back <= 0 && b.c == 0 {
    44  		return
    45  	}
    46  
    47  	if back <= 0 {
    48  		b.c = 0
    49  		return
    50  	}
    51  
    52  	b.c = back
    53  }
    54  
    55  // Next returns bytes around giving range.
    56  // If area is beyond slice length, then the rest of slice is returned.
    57  func (b *BufferedPeeker) Next(n int) []byte {
    58  	if b.c+n >= b.l {
    59  		p := b.c
    60  		b.c = b.l
    61  		return b.d[p:]
    62  	}
    63  
    64  	area := b.d[b.c : b.c+n]
    65  	b.c += n
    66  	return area
    67  }
    68  
    69  // Peek returns the next bytes of giving n length. It
    70  // will not move index beyond current bounds, but returns
    71  // current area if within slice length.
    72  // If area is beyond slice length, then the rest of slice is returned.
    73  func (b *BufferedPeeker) Peek(n int) []byte {
    74  	if b.c+n >= b.l {
    75  		return b.d[b.c:]
    76  	}
    77  
    78  	return b.d[b.c : b.c+n]
    79  }