mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 17:24:22 +00:00 
			
		
		
		
	* Dump: Use mholt/archive/v3 to support tar including many compressions Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Dump: Allow dump output to stdout Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Dump: Fixed bug present since #6677 where SessionConfig.Provider is never "file" Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Dump: never pack RepoRootPath, LFS.ContentPath and LogRootPath when they are below AppDataPath Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Dump: also dump LFS (fixes #10058) Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Dump: never dump CustomPath if CustomPath is a subdir of or equal to AppDataPath (fixes #10365) Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * Use log.Info instead of fmt.Fprintf Signed-off-by: Philipp Homann <homann.philipp@googlemail.com> * import ordering * make fmt Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: Matti R <matti@mdranta.net>
		
			
				
	
	
		
			167 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
// Copyright 2015, Joe Tsai. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE.md file.
 | 
						|
 | 
						|
package prefix
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/binary"
 | 
						|
	"io"
 | 
						|
 | 
						|
	"github.com/dsnet/compress/internal/errors"
 | 
						|
)
 | 
						|
 | 
						|
// Writer implements a prefix encoder. For performance reasons, Writer will not
 | 
						|
// write bytes immediately to the underlying stream.
 | 
						|
type Writer struct {
 | 
						|
	Offset int64 // Number of bytes written to the underlying io.Writer
 | 
						|
 | 
						|
	wr        io.Writer
 | 
						|
	bufBits   uint64 // Buffer to hold some bits
 | 
						|
	numBits   uint   // Number of valid bits in bufBits
 | 
						|
	bigEndian bool   // Are bits written in big-endian order?
 | 
						|
 | 
						|
	buf    [512]byte
 | 
						|
	cntBuf int
 | 
						|
}
 | 
						|
 | 
						|
// Init initializes the bit Writer to write to w. If bigEndian is true, then
 | 
						|
// bits will be written starting from the most-significant bits of a byte
 | 
						|
// (as done in bzip2), otherwise it will write starting from the
 | 
						|
// least-significant bits of a byte (such as for deflate and brotli).
 | 
						|
func (pw *Writer) Init(w io.Writer, bigEndian bool) {
 | 
						|
	*pw = Writer{wr: w, bigEndian: bigEndian}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// BitsWritten reports the total number of bits issued to any Write method.
 | 
						|
func (pw *Writer) BitsWritten() int64 {
 | 
						|
	return 8*pw.Offset + 8*int64(pw.cntBuf) + int64(pw.numBits)
 | 
						|
}
 | 
						|
 | 
						|
// WritePads writes 0-7 bits to the bit buffer to achieve byte-alignment.
 | 
						|
func (pw *Writer) WritePads(v uint) {
 | 
						|
	nb := -pw.numBits & 7
 | 
						|
	pw.bufBits |= uint64(v) << pw.numBits
 | 
						|
	pw.numBits += nb
 | 
						|
}
 | 
						|
 | 
						|
// Write writes bytes from buf.
 | 
						|
// The bit-ordering mode does not affect this method.
 | 
						|
func (pw *Writer) Write(buf []byte) (cnt int, err error) {
 | 
						|
	if pw.numBits > 0 || pw.cntBuf > 0 {
 | 
						|
		if pw.numBits%8 != 0 {
 | 
						|
			return 0, errorf(errors.Invalid, "non-aligned bit buffer")
 | 
						|
		}
 | 
						|
		if _, err := pw.Flush(); err != nil {
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	cnt, err = pw.wr.Write(buf)
 | 
						|
	pw.Offset += int64(cnt)
 | 
						|
	return cnt, err
 | 
						|
}
 | 
						|
 | 
						|
// WriteOffset writes ofs in a (sym, extra) fashion using the provided prefix
 | 
						|
// Encoder and RangeEncoder.
 | 
						|
func (pw *Writer) WriteOffset(ofs uint, pe *Encoder, re *RangeEncoder) {
 | 
						|
	sym := re.Encode(ofs)
 | 
						|
	pw.WriteSymbol(sym, pe)
 | 
						|
	rc := re.rcs[sym]
 | 
						|
	pw.WriteBits(ofs-uint(rc.Base), uint(rc.Len))
 | 
						|
}
 | 
						|
 | 
						|
// TryWriteBits attempts to write nb bits using the contents of the bit buffer
 | 
						|
// alone. It reports whether it succeeded.
 | 
						|
//
 | 
						|
// This method is designed to be inlined for performance reasons.
 | 
						|
func (pw *Writer) TryWriteBits(v, nb uint) bool {
 | 
						|
	if 64-pw.numBits < nb {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	pw.bufBits |= uint64(v) << pw.numBits
 | 
						|
	pw.numBits += nb
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
// WriteBits writes nb bits of v to the underlying writer.
 | 
						|
func (pw *Writer) WriteBits(v, nb uint) {
 | 
						|
	if _, err := pw.PushBits(); err != nil {
 | 
						|
		errors.Panic(err)
 | 
						|
	}
 | 
						|
	pw.bufBits |= uint64(v) << pw.numBits
 | 
						|
	pw.numBits += nb
 | 
						|
}
 | 
						|
 | 
						|
// TryWriteSymbol attempts to encode the next symbol using the contents of the
 | 
						|
// bit buffer alone. It reports whether it succeeded.
 | 
						|
//
 | 
						|
// This method is designed to be inlined for performance reasons.
 | 
						|
func (pw *Writer) TryWriteSymbol(sym uint, pe *Encoder) bool {
 | 
						|
	chunk := pe.chunks[uint32(sym)&pe.chunkMask]
 | 
						|
	nb := uint(chunk & countMask)
 | 
						|
	if 64-pw.numBits < nb {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	pw.bufBits |= uint64(chunk>>countBits) << pw.numBits
 | 
						|
	pw.numBits += nb
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
// WriteSymbol writes the symbol using the provided prefix Encoder.
 | 
						|
func (pw *Writer) WriteSymbol(sym uint, pe *Encoder) {
 | 
						|
	if _, err := pw.PushBits(); err != nil {
 | 
						|
		errors.Panic(err)
 | 
						|
	}
 | 
						|
	chunk := pe.chunks[uint32(sym)&pe.chunkMask]
 | 
						|
	nb := uint(chunk & countMask)
 | 
						|
	pw.bufBits |= uint64(chunk>>countBits) << pw.numBits
 | 
						|
	pw.numBits += nb
 | 
						|
}
 | 
						|
 | 
						|
// Flush flushes all complete bytes from the bit buffer to the byte buffer, and
 | 
						|
// then flushes all bytes in the byte buffer to the underlying writer.
 | 
						|
// After this call, the bit Writer is will only withhold 7 bits at most.
 | 
						|
func (pw *Writer) Flush() (int64, error) {
 | 
						|
	if pw.numBits < 8 && pw.cntBuf == 0 {
 | 
						|
		return pw.Offset, nil
 | 
						|
	}
 | 
						|
	if _, err := pw.PushBits(); err != nil {
 | 
						|
		return pw.Offset, err
 | 
						|
	}
 | 
						|
	cnt, err := pw.wr.Write(pw.buf[:pw.cntBuf])
 | 
						|
	pw.cntBuf -= cnt
 | 
						|
	pw.Offset += int64(cnt)
 | 
						|
	return pw.Offset, err
 | 
						|
}
 | 
						|
 | 
						|
// PushBits pushes as many bytes as possible from the bit buffer to the byte
 | 
						|
// buffer, reporting the number of bits pushed.
 | 
						|
func (pw *Writer) PushBits() (uint, error) {
 | 
						|
	if pw.cntBuf >= len(pw.buf)-8 {
 | 
						|
		cnt, err := pw.wr.Write(pw.buf[:pw.cntBuf])
 | 
						|
		pw.cntBuf -= cnt
 | 
						|
		pw.Offset += int64(cnt)
 | 
						|
		if err != nil {
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	u := pw.bufBits
 | 
						|
	if pw.bigEndian {
 | 
						|
		// Swap all the bits within each byte.
 | 
						|
		u = (u&0xaaaaaaaaaaaaaaaa)>>1 | (u&0x5555555555555555)<<1
 | 
						|
		u = (u&0xcccccccccccccccc)>>2 | (u&0x3333333333333333)<<2
 | 
						|
		u = (u&0xf0f0f0f0f0f0f0f0)>>4 | (u&0x0f0f0f0f0f0f0f0f)<<4
 | 
						|
	}
 | 
						|
	// Starting with Go 1.7, the compiler should use a wide integer
 | 
						|
	// store here if the architecture supports it.
 | 
						|
	binary.LittleEndian.PutUint64(pw.buf[pw.cntBuf:], u)
 | 
						|
 | 
						|
	nb := pw.numBits / 8 // Number of bytes to copy from bit buffer
 | 
						|
	pw.cntBuf += int(nb)
 | 
						|
	pw.bufBits >>= 8 * nb
 | 
						|
	pw.numBits -= 8 * nb
 | 
						|
	return 8 * nb, nil
 | 
						|
}
 |