1
0
Fork 0
forgejo/vendor/github.com/dsnet/compress/bzip2/rle1.go
PhilippHomann 684b7a999f
Dump: add output format tar and output to stdout (#10376)
* 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>
2020-06-05 16:47:39 -04:00

101 lines
2.5 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 bzip2
import "github.com/dsnet/compress/internal/errors"
// rleDone is a special "error" to indicate that the RLE stage is done.
var rleDone = errorf(errors.Unknown, "RLE1 stage is completed")
// runLengthEncoding implements the first RLE stage of bzip2. Every sequence
// of 4..255 duplicated bytes is replaced by only the first 4 bytes, and a
// single byte representing the repeat length. Similar to the C bzip2
// implementation, the encoder will always terminate repeat sequences with a
// count (even if it is the end of the buffer), and it will also never produce
// run lengths of 256..259. The decoder can handle the latter case.
//
// For example, if the input was:
// input: "AAAAAAABBBBCCCD"
//
// Then the output will be:
// output: "AAAA\x03BBBB\x00CCCD"
type runLengthEncoding struct {
buf []byte
idx int
lastVal byte
lastCnt int
}
func (rle *runLengthEncoding) Init(buf []byte) {
*rle = runLengthEncoding{buf: buf}
}
func (rle *runLengthEncoding) Write(buf []byte) (int, error) {
for i, b := range buf {
if rle.lastVal != b {
rle.lastCnt = 0
}
rle.lastCnt++
switch {
case rle.lastCnt < 4:
if rle.idx >= len(rle.buf) {
return i, rleDone
}
rle.buf[rle.idx] = b
rle.idx++
case rle.lastCnt == 4:
if rle.idx+1 >= len(rle.buf) {
return i, rleDone
}
rle.buf[rle.idx] = b
rle.idx++
rle.buf[rle.idx] = 0
rle.idx++
case rle.lastCnt < 256:
rle.buf[rle.idx-1]++
default:
if rle.idx >= len(rle.buf) {
return i, rleDone
}
rle.lastCnt = 1
rle.buf[rle.idx] = b
rle.idx++
}
rle.lastVal = b
}
return len(buf), nil
}
func (rle *runLengthEncoding) Read(buf []byte) (int, error) {
for i := range buf {
switch {
case rle.lastCnt == -4:
if rle.idx >= len(rle.buf) {
return i, errorf(errors.Corrupted, "missing terminating run-length repeater")
}
rle.lastCnt = int(rle.buf[rle.idx])
rle.idx++
if rle.lastCnt > 0 {
break // Break the switch
}
fallthrough // Count was zero, continue the work
case rle.lastCnt <= 0:
if rle.idx >= len(rle.buf) {
return i, rleDone
}
b := rle.buf[rle.idx]
rle.idx++
if b != rle.lastVal {
rle.lastCnt = 0
rle.lastVal = b
}
}
buf[i] = rle.lastVal
rle.lastCnt--
}
return len(buf), nil
}
func (rle *runLengthEncoding) Bytes() []byte { return rle.buf[:rle.idx] }