mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			172 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
// Copyright 2014-2021 Ulrich Kunitz. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package lzma
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
)
 | 
						|
 | 
						|
// buffer provides a circular buffer of bytes. If the front index equals
 | 
						|
// the rear index the buffer is empty. As a consequence front cannot be
 | 
						|
// equal rear for a full buffer. So a full buffer has a length that is
 | 
						|
// one byte less the the length of the data slice.
 | 
						|
type buffer struct {
 | 
						|
	data  []byte
 | 
						|
	front int
 | 
						|
	rear  int
 | 
						|
}
 | 
						|
 | 
						|
// newBuffer creates a buffer with the given size.
 | 
						|
func newBuffer(size int) *buffer {
 | 
						|
	return &buffer{data: make([]byte, size+1)}
 | 
						|
}
 | 
						|
 | 
						|
// Cap returns the capacity of the buffer.
 | 
						|
func (b *buffer) Cap() int {
 | 
						|
	return len(b.data) - 1
 | 
						|
}
 | 
						|
 | 
						|
// Resets the buffer. The front and rear index are set to zero.
 | 
						|
func (b *buffer) Reset() {
 | 
						|
	b.front = 0
 | 
						|
	b.rear = 0
 | 
						|
}
 | 
						|
 | 
						|
// Buffered returns the number of bytes buffered.
 | 
						|
func (b *buffer) Buffered() int {
 | 
						|
	delta := b.front - b.rear
 | 
						|
	if delta < 0 {
 | 
						|
		delta += len(b.data)
 | 
						|
	}
 | 
						|
	return delta
 | 
						|
}
 | 
						|
 | 
						|
// Available returns the number of bytes available for writing.
 | 
						|
func (b *buffer) Available() int {
 | 
						|
	delta := b.rear - 1 - b.front
 | 
						|
	if delta < 0 {
 | 
						|
		delta += len(b.data)
 | 
						|
	}
 | 
						|
	return delta
 | 
						|
}
 | 
						|
 | 
						|
// addIndex adds a non-negative integer to the index i and returns the
 | 
						|
// resulting index. The function takes care of wrapping the index as
 | 
						|
// well as potential overflow situations.
 | 
						|
func (b *buffer) addIndex(i int, n int) int {
 | 
						|
	// subtraction of len(b.data) prevents overflow
 | 
						|
	i += n - len(b.data)
 | 
						|
	if i < 0 {
 | 
						|
		i += len(b.data)
 | 
						|
	}
 | 
						|
	return i
 | 
						|
}
 | 
						|
 | 
						|
// Read reads bytes from the buffer into p and returns the number of
 | 
						|
// bytes read. The function never returns an error but might return less
 | 
						|
// data than requested.
 | 
						|
func (b *buffer) Read(p []byte) (n int, err error) {
 | 
						|
	n, err = b.Peek(p)
 | 
						|
	b.rear = b.addIndex(b.rear, n)
 | 
						|
	return n, err
 | 
						|
}
 | 
						|
 | 
						|
// Peek reads bytes from the buffer into p without changing the buffer.
 | 
						|
// Peek will never return an error but might return less data than
 | 
						|
// requested.
 | 
						|
func (b *buffer) Peek(p []byte) (n int, err error) {
 | 
						|
	m := b.Buffered()
 | 
						|
	n = len(p)
 | 
						|
	if m < n {
 | 
						|
		n = m
 | 
						|
		p = p[:n]
 | 
						|
	}
 | 
						|
	k := copy(p, b.data[b.rear:])
 | 
						|
	if k < n {
 | 
						|
		copy(p[k:], b.data)
 | 
						|
	}
 | 
						|
	return n, nil
 | 
						|
}
 | 
						|
 | 
						|
// Discard skips the n next bytes to read from the buffer, returning the
 | 
						|
// bytes discarded.
 | 
						|
//
 | 
						|
// If Discards skips fewer than n bytes, it returns an error.
 | 
						|
func (b *buffer) Discard(n int) (discarded int, err error) {
 | 
						|
	if n < 0 {
 | 
						|
		return 0, errors.New("buffer.Discard: negative argument")
 | 
						|
	}
 | 
						|
	m := b.Buffered()
 | 
						|
	if m < n {
 | 
						|
		n = m
 | 
						|
		err = errors.New(
 | 
						|
			"buffer.Discard: discarded less bytes then requested")
 | 
						|
	}
 | 
						|
	b.rear = b.addIndex(b.rear, n)
 | 
						|
	return n, err
 | 
						|
}
 | 
						|
 | 
						|
// ErrNoSpace indicates that there is insufficient space for the Write
 | 
						|
// operation.
 | 
						|
var ErrNoSpace = errors.New("insufficient space")
 | 
						|
 | 
						|
// Write puts data into the  buffer. If less bytes are written than
 | 
						|
// requested ErrNoSpace is returned.
 | 
						|
func (b *buffer) Write(p []byte) (n int, err error) {
 | 
						|
	m := b.Available()
 | 
						|
	n = len(p)
 | 
						|
	if m < n {
 | 
						|
		n = m
 | 
						|
		p = p[:m]
 | 
						|
		err = ErrNoSpace
 | 
						|
	}
 | 
						|
	k := copy(b.data[b.front:], p)
 | 
						|
	if k < n {
 | 
						|
		copy(b.data, p[k:])
 | 
						|
	}
 | 
						|
	b.front = b.addIndex(b.front, n)
 | 
						|
	return n, err
 | 
						|
}
 | 
						|
 | 
						|
// WriteByte writes a single byte into the buffer. The error ErrNoSpace
 | 
						|
// is returned if no single byte is available in the buffer for writing.
 | 
						|
func (b *buffer) WriteByte(c byte) error {
 | 
						|
	if b.Available() < 1 {
 | 
						|
		return ErrNoSpace
 | 
						|
	}
 | 
						|
	b.data[b.front] = c
 | 
						|
	b.front = b.addIndex(b.front, 1)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// prefixLen returns the length of the common prefix of a and b.
 | 
						|
func prefixLen(a, b []byte) int {
 | 
						|
	if len(a) > len(b) {
 | 
						|
		a, b = b, a
 | 
						|
	}
 | 
						|
	for i, c := range a {
 | 
						|
		if b[i] != c {
 | 
						|
			return i
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return len(a)
 | 
						|
}
 | 
						|
 | 
						|
// matchLen returns the length of the common prefix for the given
 | 
						|
// distance from the rear and the byte slice p.
 | 
						|
func (b *buffer) matchLen(distance int, p []byte) int {
 | 
						|
	var n int
 | 
						|
	i := b.rear - distance
 | 
						|
	if i < 0 {
 | 
						|
		if n = prefixLen(p, b.data[len(b.data)+i:]); n < -i {
 | 
						|
			return n
 | 
						|
		}
 | 
						|
		p = p[n:]
 | 
						|
		i = 0
 | 
						|
	}
 | 
						|
	n += prefixLen(p, b.data[i:])
 | 
						|
	return n
 | 
						|
}
 |