mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-23 08:47:42 -05:00
12a1f914f4
* update github.com/alecthomas/chroma v0.8.0 -> v0.8.1 * github.com/blevesearch/bleve v1.0.10 -> v1.0.12 * editorconfig-core-go v2.1.1 -> v2.3.7 * github.com/gliderlabs/ssh v0.2.2 -> v0.3.1 * migrate editorconfig.ParseBytes to Parse * github.com/shurcooL/vfsgen to 0d455de96546 * github.com/go-git/go-git/v5 v5.1.0 -> v5.2.0 * github.com/google/uuid v1.1.1 -> v1.1.2 * github.com/huandu/xstrings v1.3.0 -> v1.3.2 * github.com/klauspost/compress v1.10.11 -> v1.11.1 * github.com/markbates/goth v1.61.2 -> v1.65.0 * github.com/mattn/go-sqlite3 v1.14.0 -> v1.14.4 * github.com/mholt/archiver v3.3.0 -> v3.3.2 * github.com/microcosm-cc/bluemonday 4f7140c49acb -> v1.0.4 * github.com/minio/minio-go v7.0.4 -> v7.0.5 * github.com/olivere/elastic v7.0.9 -> v7.0.20 * github.com/urfave/cli v1.20.0 -> v1.22.4 * github.com/prometheus/client_golang v1.1.0 -> v1.8.0 * github.com/xanzy/go-gitlab v0.37.0 -> v0.38.1 * mvdan.cc/xurls v2.1.0 -> v2.2.0 Co-authored-by: Lauris BH <lauris@nix.lv>
156 lines
4 KiB
Go
Vendored
156 lines
4 KiB
Go
Vendored
// Copyright 2014-2019 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
|
|
|
|
// Constants used by the distance codec.
|
|
const (
|
|
// minimum supported distance
|
|
minDistance = 1
|
|
// maximum supported distance, value is used for the eos marker.
|
|
maxDistance = 1 << 32
|
|
// number of the supported len states
|
|
lenStates = 4
|
|
// start for the position models
|
|
startPosModel = 4
|
|
// first index with align bits support
|
|
endPosModel = 14
|
|
// bits for the position slots
|
|
posSlotBits = 6
|
|
// number of align bits
|
|
alignBits = 4
|
|
// maximum position slot
|
|
maxPosSlot = 63
|
|
)
|
|
|
|
// distCodec provides encoding and decoding of distance values.
|
|
type distCodec struct {
|
|
posSlotCodecs [lenStates]treeCodec
|
|
posModel [endPosModel - startPosModel]treeReverseCodec
|
|
alignCodec treeReverseCodec
|
|
}
|
|
|
|
// deepcopy initializes dc as deep copy of the source.
|
|
func (dc *distCodec) deepcopy(src *distCodec) {
|
|
if dc == src {
|
|
return
|
|
}
|
|
for i := range dc.posSlotCodecs {
|
|
dc.posSlotCodecs[i].deepcopy(&src.posSlotCodecs[i])
|
|
}
|
|
for i := range dc.posModel {
|
|
dc.posModel[i].deepcopy(&src.posModel[i])
|
|
}
|
|
dc.alignCodec.deepcopy(&src.alignCodec)
|
|
}
|
|
|
|
// distBits returns the number of bits required to encode dist.
|
|
func distBits(dist uint32) int {
|
|
if dist < startPosModel {
|
|
return 6
|
|
}
|
|
// slot s > 3, dist d
|
|
// s = 2(bits(d)-1) + bit(d, bits(d)-2)
|
|
// s>>1 = bits(d)-1
|
|
// bits(d) = 32-nlz32(d)
|
|
// s>>1=31-nlz32(d)
|
|
// n = 5 + (s>>1) = 36 - nlz32(d)
|
|
return 36 - nlz32(dist)
|
|
}
|
|
|
|
// newDistCodec creates a new distance codec.
|
|
func (dc *distCodec) init() {
|
|
for i := range dc.posSlotCodecs {
|
|
dc.posSlotCodecs[i] = makeTreeCodec(posSlotBits)
|
|
}
|
|
for i := range dc.posModel {
|
|
posSlot := startPosModel + i
|
|
bits := (posSlot >> 1) - 1
|
|
dc.posModel[i] = makeTreeReverseCodec(bits)
|
|
}
|
|
dc.alignCodec = makeTreeReverseCodec(alignBits)
|
|
}
|
|
|
|
// lenState converts the value l to a supported lenState value.
|
|
func lenState(l uint32) uint32 {
|
|
if l >= lenStates {
|
|
l = lenStates - 1
|
|
}
|
|
return l
|
|
}
|
|
|
|
// Encode encodes the distance using the parameter l. Dist can have values from
|
|
// the full range of uint32 values. To get the distance offset the actual match
|
|
// distance has to be decreased by 1. A distance offset of 0xffffffff (eos)
|
|
// indicates the end of the stream.
|
|
func (dc *distCodec) Encode(e *rangeEncoder, dist uint32, l uint32) (err error) {
|
|
// Compute the posSlot using nlz32
|
|
var posSlot uint32
|
|
var bits uint32
|
|
if dist < startPosModel {
|
|
posSlot = dist
|
|
} else {
|
|
bits = uint32(30 - nlz32(dist))
|
|
posSlot = startPosModel - 2 + (bits << 1)
|
|
posSlot += (dist >> uint(bits)) & 1
|
|
}
|
|
|
|
if err = dc.posSlotCodecs[lenState(l)].Encode(e, posSlot); err != nil {
|
|
return
|
|
}
|
|
|
|
switch {
|
|
case posSlot < startPosModel:
|
|
return nil
|
|
case posSlot < endPosModel:
|
|
tc := &dc.posModel[posSlot-startPosModel]
|
|
return tc.Encode(dist, e)
|
|
}
|
|
dic := directCodec(bits - alignBits)
|
|
if err = dic.Encode(e, dist>>alignBits); err != nil {
|
|
return
|
|
}
|
|
return dc.alignCodec.Encode(dist, e)
|
|
}
|
|
|
|
// Decode decodes the distance offset using the parameter l. The dist value
|
|
// 0xffffffff (eos) indicates the end of the stream. Add one to the distance
|
|
// offset to get the actual match distance.
|
|
func (dc *distCodec) Decode(d *rangeDecoder, l uint32) (dist uint32, err error) {
|
|
posSlot, err := dc.posSlotCodecs[lenState(l)].Decode(d)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// posSlot equals distance
|
|
if posSlot < startPosModel {
|
|
return posSlot, nil
|
|
}
|
|
|
|
// posSlot uses the individual models
|
|
bits := (posSlot >> 1) - 1
|
|
dist = (2 | (posSlot & 1)) << bits
|
|
var u uint32
|
|
if posSlot < endPosModel {
|
|
tc := &dc.posModel[posSlot-startPosModel]
|
|
if u, err = tc.Decode(d); err != nil {
|
|
return 0, err
|
|
}
|
|
dist += u
|
|
return dist, nil
|
|
}
|
|
|
|
// posSlots use direct encoding and a single model for the four align
|
|
// bits.
|
|
dic := directCodec(bits - alignBits)
|
|
if u, err = dic.Decode(d); err != nil {
|
|
return 0, err
|
|
}
|
|
dist += u << alignBits
|
|
if u, err = dc.alignCodec.Decode(d); err != nil {
|
|
return 0, err
|
|
}
|
|
dist += u
|
|
return dist, nil
|
|
}
|