You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.4 KiB
77 lines
1.4 KiB
package structure
|
|
|
|
import (
|
|
"github.com/alibaba/RedisShake/internal/log"
|
|
"io"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
RDBEncInt8 = 0 // RDB_ENC_INT8
|
|
RDBEncInt16 = 1 // RDB_ENC_INT16
|
|
RDBEncInt32 = 2 // RDB_ENC_INT32
|
|
RDBEncLZF = 3 // RDB_ENC_LZF
|
|
)
|
|
|
|
func ReadString(rd io.Reader) string {
|
|
length, special, err := readEncodedLength(rd)
|
|
if err != nil {
|
|
log.PanicError(err)
|
|
}
|
|
if special {
|
|
switch length {
|
|
case RDBEncInt8:
|
|
b := ReadInt8(rd)
|
|
return strconv.Itoa(int(b))
|
|
case RDBEncInt16:
|
|
b := ReadInt16(rd)
|
|
return strconv.Itoa(int(b))
|
|
case RDBEncInt32:
|
|
b := ReadInt32(rd)
|
|
return strconv.Itoa(int(b))
|
|
case RDBEncLZF:
|
|
inLen := ReadLength(rd)
|
|
outLen := ReadLength(rd)
|
|
in := ReadBytes(rd, int(inLen))
|
|
|
|
return lzfDecompress(in, int(outLen))
|
|
default:
|
|
log.Panicf("Unknown string encode type %d", length)
|
|
}
|
|
}
|
|
return string(ReadBytes(rd, int(length)))
|
|
}
|
|
|
|
func lzfDecompress(in []byte, outLen int) string {
|
|
out := make([]byte, outLen)
|
|
|
|
i, o := 0, 0
|
|
for i < len(in) {
|
|
ctrl := int(in[i])
|
|
i++
|
|
if ctrl < 32 {
|
|
for x := 0; x <= ctrl; x++ {
|
|
out[o] = in[i]
|
|
i++
|
|
o++
|
|
}
|
|
} else {
|
|
length := ctrl >> 5
|
|
if length == 7 {
|
|
length = length + int(in[i])
|
|
i++
|
|
}
|
|
ref := o - ((ctrl & 0x1f) << 8) - int(in[i]) - 1
|
|
i++
|
|
for x := 0; x <= length+1; x++ {
|
|
out[o] = out[ref]
|
|
ref++
|
|
o++
|
|
}
|
|
}
|
|
}
|
|
if o != outLen {
|
|
log.Panicf("lzf decompress failed: outLen: %d, o: %d", outLen, o)
|
|
}
|
|
return string(out)
|
|
}
|
|
|