* 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>
		
			
				
	
	
		
			247 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package rardecode
 | 
						|
 | 
						|
const (
 | 
						|
	mainSize      = 299
 | 
						|
	offsetSize    = 60
 | 
						|
	lowOffsetSize = 17
 | 
						|
	lengthSize    = 28
 | 
						|
	tableSize     = mainSize + offsetSize + lowOffsetSize + lengthSize
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	lengthBase = [28]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20,
 | 
						|
		24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224}
 | 
						|
	lengthExtraBits = [28]uint{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
 | 
						|
		2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}
 | 
						|
 | 
						|
	offsetBase = [60]int{0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96,
 | 
						|
		128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096,
 | 
						|
		6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,
 | 
						|
		131072, 196608, 262144, 327680, 393216, 458752, 524288,
 | 
						|
		589824, 655360, 720896, 786432, 851968, 917504, 983040,
 | 
						|
		1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2621440,
 | 
						|
		2883584, 3145728, 3407872, 3670016, 3932160}
 | 
						|
	offsetExtraBits = [60]uint{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
 | 
						|
		6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
 | 
						|
		15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
 | 
						|
		18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}
 | 
						|
 | 
						|
	shortOffsetBase      = [8]int{0, 4, 8, 16, 32, 64, 128, 192}
 | 
						|
	shortOffsetExtraBits = [8]uint{2, 2, 3, 4, 5, 6, 6, 6}
 | 
						|
)
 | 
						|
 | 
						|
type lz29Decoder struct {
 | 
						|
	codeLength [tableSize]byte
 | 
						|
 | 
						|
	mainDecoder      huffmanDecoder
 | 
						|
	offsetDecoder    huffmanDecoder
 | 
						|
	lowOffsetDecoder huffmanDecoder
 | 
						|
	lengthDecoder    huffmanDecoder
 | 
						|
 | 
						|
	offset           [4]int // history of previous offsets
 | 
						|
	length           int    // previous length
 | 
						|
	lowOffset        int
 | 
						|
	lowOffsetRepeats int
 | 
						|
 | 
						|
	br *rarBitReader
 | 
						|
}
 | 
						|
 | 
						|
func (d *lz29Decoder) reset() {
 | 
						|
	for i := range d.offset {
 | 
						|
		d.offset[i] = 0
 | 
						|
	}
 | 
						|
	d.length = 0
 | 
						|
	for i := range d.codeLength {
 | 
						|
		d.codeLength[i] = 0
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (d *lz29Decoder) init(br *rarBitReader) error {
 | 
						|
	d.br = br
 | 
						|
	d.lowOffset = 0
 | 
						|
	d.lowOffsetRepeats = 0
 | 
						|
 | 
						|
	n, err := d.br.readBits(1)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	addOld := n > 0
 | 
						|
 | 
						|
	cl := d.codeLength[:]
 | 
						|
	if err = readCodeLengthTable(d.br, cl, addOld); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	d.mainDecoder.init(cl[:mainSize])
 | 
						|
	cl = cl[mainSize:]
 | 
						|
	d.offsetDecoder.init(cl[:offsetSize])
 | 
						|
	cl = cl[offsetSize:]
 | 
						|
	d.lowOffsetDecoder.init(cl[:lowOffsetSize])
 | 
						|
	cl = cl[lowOffsetSize:]
 | 
						|
	d.lengthDecoder.init(cl)
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (d *lz29Decoder) readFilterData() (b []byte, err error) {
 | 
						|
	flags, err := d.br.ReadByte()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	n := (int(flags) & 7) + 1
 | 
						|
	switch n {
 | 
						|
	case 7:
 | 
						|
		n, err = d.br.readBits(8)
 | 
						|
		n += 7
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	case 8:
 | 
						|
		n, err = d.br.readBits(16)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	buf := make([]byte, n+1)
 | 
						|
	buf[0] = flags
 | 
						|
	err = d.br.readFull(buf[1:])
 | 
						|
 | 
						|
	return buf, err
 | 
						|
}
 | 
						|
 | 
						|
func (d *lz29Decoder) readEndOfBlock() error {
 | 
						|
	n, err := d.br.readBits(1)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if n > 0 {
 | 
						|
		return endOfBlock
 | 
						|
	}
 | 
						|
	n, err = d.br.readBits(1)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if n > 0 {
 | 
						|
		return endOfBlockAndFile
 | 
						|
	}
 | 
						|
	return endOfFile
 | 
						|
}
 | 
						|
 | 
						|
func (d *lz29Decoder) decode(win *window) ([]byte, error) {
 | 
						|
	sym, err := d.mainDecoder.readSym(d.br)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	switch {
 | 
						|
	case sym < 256:
 | 
						|
		// literal
 | 
						|
		win.writeByte(byte(sym))
 | 
						|
		return nil, nil
 | 
						|
	case sym == 256:
 | 
						|
		return nil, d.readEndOfBlock()
 | 
						|
	case sym == 257:
 | 
						|
		return d.readFilterData()
 | 
						|
	case sym == 258:
 | 
						|
		// use previous offset and length
 | 
						|
	case sym < 263:
 | 
						|
		i := sym - 259
 | 
						|
		offset := d.offset[i]
 | 
						|
		copy(d.offset[1:i+1], d.offset[:i])
 | 
						|
		d.offset[0] = offset
 | 
						|
 | 
						|
		i, err := d.lengthDecoder.readSym(d.br)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		d.length = lengthBase[i] + 2
 | 
						|
		bits := lengthExtraBits[i]
 | 
						|
		if bits > 0 {
 | 
						|
			n, err := d.br.readBits(bits)
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			}
 | 
						|
			d.length += n
 | 
						|
		}
 | 
						|
	case sym < 271:
 | 
						|
		i := sym - 263
 | 
						|
		copy(d.offset[1:], d.offset[:])
 | 
						|
		offset := shortOffsetBase[i] + 1
 | 
						|
		bits := shortOffsetExtraBits[i]
 | 
						|
		if bits > 0 {
 | 
						|
			n, err := d.br.readBits(bits)
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			}
 | 
						|
			offset += n
 | 
						|
		}
 | 
						|
		d.offset[0] = offset
 | 
						|
 | 
						|
		d.length = 2
 | 
						|
	default:
 | 
						|
		i := sym - 271
 | 
						|
		d.length = lengthBase[i] + 3
 | 
						|
		bits := lengthExtraBits[i]
 | 
						|
		if bits > 0 {
 | 
						|
			n, err := d.br.readBits(bits)
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			}
 | 
						|
			d.length += n
 | 
						|
		}
 | 
						|
 | 
						|
		i, err = d.offsetDecoder.readSym(d.br)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		offset := offsetBase[i] + 1
 | 
						|
		bits = offsetExtraBits[i]
 | 
						|
 | 
						|
		switch {
 | 
						|
		case bits >= 4:
 | 
						|
			if bits > 4 {
 | 
						|
				n, err := d.br.readBits(bits - 4)
 | 
						|
				if err != nil {
 | 
						|
					return nil, err
 | 
						|
				}
 | 
						|
				offset += n << 4
 | 
						|
			}
 | 
						|
 | 
						|
			if d.lowOffsetRepeats > 0 {
 | 
						|
				d.lowOffsetRepeats--
 | 
						|
				offset += d.lowOffset
 | 
						|
			} else {
 | 
						|
				n, err := d.lowOffsetDecoder.readSym(d.br)
 | 
						|
				if err != nil {
 | 
						|
					return nil, err
 | 
						|
				}
 | 
						|
				if n == 16 {
 | 
						|
					d.lowOffsetRepeats = 15
 | 
						|
					offset += d.lowOffset
 | 
						|
				} else {
 | 
						|
					offset += n
 | 
						|
					d.lowOffset = n
 | 
						|
				}
 | 
						|
			}
 | 
						|
		case bits > 0:
 | 
						|
			n, err := d.br.readBits(bits)
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			}
 | 
						|
			offset += n
 | 
						|
		}
 | 
						|
 | 
						|
		if offset >= 0x2000 {
 | 
						|
			d.length++
 | 
						|
			if offset >= 0x40000 {
 | 
						|
				d.length++
 | 
						|
			}
 | 
						|
		}
 | 
						|
		copy(d.offset[1:], d.offset[:])
 | 
						|
		d.offset[0] = offset
 | 
						|
	}
 | 
						|
	win.copyBytes(d.length, d.offset[0])
 | 
						|
	return nil, nil
 | 
						|
}
 |