mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 11:22:27 -05:00 
			
		
		
		
	Bumps [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) from 7.0.77 to 7.0.78. - [Release notes](https://github.com/minio/minio-go/releases) - [Commits](https://github.com/minio/minio-go/compare/v7.0.77...v7.0.78) --- updated-dependencies: - dependency-name: github.com/minio/minio-go/v7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
		
			
				
	
	
		
			414 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2011 The Snappy-Go Authors. All rights reserved.
 | |
| // Copyright (c) 2019 Klaus Post. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package s2
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"math"
 | |
| 	"math/bits"
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/klauspost/compress/internal/race"
 | |
| )
 | |
| 
 | |
| // Encode returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func Encode(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if cap(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	} else {
 | |
| 		dst = dst[:n]
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	n := encodeBlock(dst[d:], src)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| var estblockPool [2]sync.Pool
 | |
| 
 | |
| // EstimateBlockSize will perform a very fast compression
 | |
| // without outputting the result and return the compressed output size.
 | |
| // The function returns -1 if no improvement could be achieved.
 | |
| // Using actual compression will most often produce better compression than the estimate.
 | |
| func EstimateBlockSize(src []byte) (d int) {
 | |
| 	if len(src) <= inputMargin || int64(len(src)) > 0xffffffff {
 | |
| 		return -1
 | |
| 	}
 | |
| 	if len(src) <= 1024 {
 | |
| 		const sz, pool = 2048, 0
 | |
| 		tmp, ok := estblockPool[pool].Get().(*[sz]byte)
 | |
| 		if !ok {
 | |
| 			tmp = &[sz]byte{}
 | |
| 		}
 | |
| 		race.WriteSlice(tmp[:])
 | |
| 		defer estblockPool[pool].Put(tmp)
 | |
| 
 | |
| 		d = calcBlockSizeSmall(src, tmp)
 | |
| 	} else {
 | |
| 		const sz, pool = 32768, 1
 | |
| 		tmp, ok := estblockPool[pool].Get().(*[sz]byte)
 | |
| 		if !ok {
 | |
| 			tmp = &[sz]byte{}
 | |
| 		}
 | |
| 		race.WriteSlice(tmp[:])
 | |
| 		defer estblockPool[pool].Put(tmp)
 | |
| 
 | |
| 		d = calcBlockSize(src, tmp)
 | |
| 	}
 | |
| 
 | |
| 	if d == 0 {
 | |
| 		return -1
 | |
| 	}
 | |
| 	// Size of the varint encoded block size.
 | |
| 	d += (bits.Len64(uint64(len(src))) + 7) / 7
 | |
| 
 | |
| 	if d >= len(src) {
 | |
| 		return -1
 | |
| 	}
 | |
| 	return d
 | |
| }
 | |
| 
 | |
| // EncodeBetter returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // EncodeBetter compresses better than Encode but typically with a
 | |
| // 10-40% speed decrease on both compression and decompression.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func EncodeBetter(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if len(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	n := encodeBlockBetter(dst[d:], src)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| // EncodeBest returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // EncodeBest compresses as good as reasonably possible but with a
 | |
| // big speed decrease.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func EncodeBest(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if len(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	n := encodeBlockBest(dst[d:], src, nil)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| // EncodeSnappy returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // The output is Snappy compatible and will likely decompress faster.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func EncodeSnappy(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if cap(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	} else {
 | |
| 		dst = dst[:n]
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 
 | |
| 	n := encodeBlockSnappy(dst[d:], src)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| // EncodeSnappyBetter returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // The output is Snappy compatible and will likely decompress faster.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func EncodeSnappyBetter(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if cap(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	} else {
 | |
| 		dst = dst[:n]
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 
 | |
| 	n := encodeBlockBetterSnappy(dst[d:], src)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| // EncodeSnappyBest returns the encoded form of src. The returned slice may be a sub-
 | |
| // slice of dst if dst was large enough to hold the entire encoded block.
 | |
| // Otherwise, a newly allocated slice will be returned.
 | |
| //
 | |
| // The output is Snappy compatible and will likely decompress faster.
 | |
| //
 | |
| // The dst and src must not overlap. It is valid to pass a nil dst.
 | |
| //
 | |
| // The blocks will require the same amount of memory to decode as encoding,
 | |
| // and does not make for concurrent decoding.
 | |
| // Also note that blocks do not contain CRC information, so corruption may be undetected.
 | |
| //
 | |
| // If you need to encode larger amounts of data, consider using
 | |
| // the streaming interface which gives all of these features.
 | |
| func EncodeSnappyBest(dst, src []byte) []byte {
 | |
| 	if n := MaxEncodedLen(len(src)); n < 0 {
 | |
| 		panic(ErrTooLarge)
 | |
| 	} else if cap(dst) < n {
 | |
| 		dst = make([]byte, n)
 | |
| 	} else {
 | |
| 		dst = dst[:n]
 | |
| 	}
 | |
| 
 | |
| 	// The block starts with the varint-encoded length of the decompressed bytes.
 | |
| 	d := binary.PutUvarint(dst, uint64(len(src)))
 | |
| 
 | |
| 	if len(src) == 0 {
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	if len(src) < minNonLiteralBlockSize {
 | |
| 		d += emitLiteral(dst[d:], src)
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 
 | |
| 	n := encodeBlockBestSnappy(dst[d:], src)
 | |
| 	if n > 0 {
 | |
| 		d += n
 | |
| 		return dst[:d]
 | |
| 	}
 | |
| 	// Not compressible
 | |
| 	d += emitLiteral(dst[d:], src)
 | |
| 	return dst[:d]
 | |
| }
 | |
| 
 | |
| // ConcatBlocks will concatenate the supplied blocks and append them to the supplied destination.
 | |
| // If the destination is nil or too small, a new will be allocated.
 | |
| // The blocks are not validated, so garbage in = garbage out.
 | |
| // dst may not overlap block data.
 | |
| // Any data in dst is preserved as is, so it will not be considered a block.
 | |
| func ConcatBlocks(dst []byte, blocks ...[]byte) ([]byte, error) {
 | |
| 	totalSize := uint64(0)
 | |
| 	compSize := 0
 | |
| 	for _, b := range blocks {
 | |
| 		l, hdr, err := decodedLen(b)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		totalSize += uint64(l)
 | |
| 		compSize += len(b) - hdr
 | |
| 	}
 | |
| 	if totalSize == 0 {
 | |
| 		dst = append(dst, 0)
 | |
| 		return dst, nil
 | |
| 	}
 | |
| 	if totalSize > math.MaxUint32 {
 | |
| 		return nil, ErrTooLarge
 | |
| 	}
 | |
| 	var tmp [binary.MaxVarintLen32]byte
 | |
| 	hdrSize := binary.PutUvarint(tmp[:], totalSize)
 | |
| 	wantSize := hdrSize + compSize
 | |
| 
 | |
| 	if cap(dst)-len(dst) < wantSize {
 | |
| 		dst = append(make([]byte, 0, wantSize+len(dst)), dst...)
 | |
| 	}
 | |
| 	dst = append(dst, tmp[:hdrSize]...)
 | |
| 	for _, b := range blocks {
 | |
| 		_, hdr, err := decodedLen(b)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		dst = append(dst, b[hdr:]...)
 | |
| 	}
 | |
| 	return dst, nil
 | |
| }
 | |
| 
 | |
| // inputMargin is the minimum number of extra input bytes to keep, inside
 | |
| // encodeBlock's inner loop. On some architectures, this margin lets us
 | |
| // implement a fast path for emitLiteral, where the copy of short (<= 16 byte)
 | |
| // literals can be implemented as a single load to and store from a 16-byte
 | |
| // register. That literal's actual length can be as short as 1 byte, so this
 | |
| // can copy up to 15 bytes too much, but that's OK as subsequent iterations of
 | |
| // the encoding loop will fix up the copy overrun, and this inputMargin ensures
 | |
| // that we don't overrun the dst and src buffers.
 | |
| const inputMargin = 8
 | |
| 
 | |
| // minNonLiteralBlockSize is the minimum size of the input to encodeBlock that
 | |
| // will be accepted by the encoder.
 | |
| const minNonLiteralBlockSize = 32
 | |
| 
 | |
| const intReduction = 2 - (1 << (^uint(0) >> 63)) // 1 (32 bits) or 0 (64 bits)
 | |
| 
 | |
| // MaxBlockSize is the maximum value where MaxEncodedLen will return a valid block size.
 | |
| // Blocks this big are highly discouraged, though.
 | |
| // Half the size on 32 bit systems.
 | |
| const MaxBlockSize = (1<<(32-intReduction) - 1) - binary.MaxVarintLen32 - 5
 | |
| 
 | |
| // MaxEncodedLen returns the maximum length of a snappy block, given its
 | |
| // uncompressed length.
 | |
| //
 | |
| // It will return a negative value if srcLen is too large to encode.
 | |
| // 32 bit platforms will have lower thresholds for rejecting big content.
 | |
| func MaxEncodedLen(srcLen int) int {
 | |
| 	n := uint64(srcLen)
 | |
| 	if intReduction == 1 {
 | |
| 		// 32 bits
 | |
| 		if n > math.MaxInt32 {
 | |
| 			// Also includes negative.
 | |
| 			return -1
 | |
| 		}
 | |
| 	} else if n > 0xffffffff {
 | |
| 		// 64 bits
 | |
| 		// Also includes negative.
 | |
| 		return -1
 | |
| 	}
 | |
| 	// Size of the varint encoded block size.
 | |
| 	n = n + uint64((bits.Len64(n)+7)/7)
 | |
| 
 | |
| 	// Add maximum size of encoding block as literals.
 | |
| 	n += uint64(literalExtraSize(int64(srcLen)))
 | |
| 	if intReduction == 1 {
 | |
| 		// 32 bits
 | |
| 		if n > math.MaxInt32 {
 | |
| 			return -1
 | |
| 		}
 | |
| 	} else if n > 0xffffffff {
 | |
| 		// 64 bits
 | |
| 		// Also includes negative.
 | |
| 		return -1
 | |
| 	}
 | |
| 	return int(n)
 | |
| }
 |