1
0
mirror of https://github.com/astaxie/beego.git synced 2025-07-04 09:20:18 +00:00

add vendor

This commit is contained in:
astaxie
2018-07-30 12:05:51 +08:00
parent d55f54a8ab
commit 48acfa08be
496 changed files with 327583 additions and 0 deletions

64
vendor/github.com/cupcake/rdb/crc64/crc64.go generated vendored Normal file

File diff suppressed because one or more lines are too long

824
vendor/github.com/cupcake/rdb/decoder.go generated vendored Normal file
View File

@ -0,0 +1,824 @@
// Package rdb implements parsing and encoding of the Redis RDB file format.
package rdb
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
"math"
"strconv"
"github.com/cupcake/rdb/crc64"
)
// A Decoder must be implemented to parse a RDB file.
type Decoder interface {
// StartRDB is called when parsing of a valid RDB file starts.
StartRDB()
// StartDatabase is called when database n starts.
// Once a database starts, another database will not start until EndDatabase is called.
StartDatabase(n int)
// AUX field
Aux(key, value []byte)
// ResizeDB hint
ResizeDatabase(dbSize, expiresSize uint32)
// Set is called once for each string key.
Set(key, value []byte, expiry int64)
// StartHash is called at the beginning of a hash.
// Hset will be called exactly length times before EndHash.
StartHash(key []byte, length, expiry int64)
// Hset is called once for each field=value pair in a hash.
Hset(key, field, value []byte)
// EndHash is called when there are no more fields in a hash.
EndHash(key []byte)
// StartSet is called at the beginning of a set.
// Sadd will be called exactly cardinality times before EndSet.
StartSet(key []byte, cardinality, expiry int64)
// Sadd is called once for each member of a set.
Sadd(key, member []byte)
// EndSet is called when there are no more fields in a set.
EndSet(key []byte)
// StartList is called at the beginning of a list.
// Rpush will be called exactly length times before EndList.
// If length of the list is not known, then length is -1
StartList(key []byte, length, expiry int64)
// Rpush is called once for each value in a list.
Rpush(key, value []byte)
// EndList is called when there are no more values in a list.
EndList(key []byte)
// StartZSet is called at the beginning of a sorted set.
// Zadd will be called exactly cardinality times before EndZSet.
StartZSet(key []byte, cardinality, expiry int64)
// Zadd is called once for each member of a sorted set.
Zadd(key []byte, score float64, member []byte)
// EndZSet is called when there are no more members in a sorted set.
EndZSet(key []byte)
// EndDatabase is called at the end of a database.
EndDatabase(n int)
// EndRDB is called when parsing of the RDB file is complete.
EndRDB()
}
// Decode parses a RDB file from r and calls the decode hooks on d.
func Decode(r io.Reader, d Decoder) error {
decoder := &decode{d, make([]byte, 8), bufio.NewReader(r)}
return decoder.decode()
}
// Decode a byte slice from the Redis DUMP command. The dump does not contain the
// database, key or expiry, so they must be included in the function call (but
// can be zero values).
func DecodeDump(dump []byte, db int, key []byte, expiry int64, d Decoder) error {
err := verifyDump(dump)
if err != nil {
return err
}
decoder := &decode{d, make([]byte, 8), bytes.NewReader(dump[1:])}
decoder.event.StartRDB()
decoder.event.StartDatabase(db)
err = decoder.readObject(key, ValueType(dump[0]), expiry)
decoder.event.EndDatabase(db)
decoder.event.EndRDB()
return err
}
type byteReader interface {
io.Reader
io.ByteReader
}
type decode struct {
event Decoder
intBuf []byte
r byteReader
}
type ValueType byte
const (
TypeString ValueType = 0
TypeList ValueType = 1
TypeSet ValueType = 2
TypeZSet ValueType = 3
TypeHash ValueType = 4
TypeHashZipmap ValueType = 9
TypeListZiplist ValueType = 10
TypeSetIntset ValueType = 11
TypeZSetZiplist ValueType = 12
TypeHashZiplist ValueType = 13
TypeListQuicklist ValueType = 14
)
const (
rdb6bitLen = 0
rdb14bitLen = 1
rdb32bitLen = 2
rdbEncVal = 3
rdbFlagAux = 0xfa
rdbFlagResizeDB = 0xfb
rdbFlagExpiryMS = 0xfc
rdbFlagExpiry = 0xfd
rdbFlagSelectDB = 0xfe
rdbFlagEOF = 0xff
rdbEncInt8 = 0
rdbEncInt16 = 1
rdbEncInt32 = 2
rdbEncLZF = 3
rdbZiplist6bitlenString = 0
rdbZiplist14bitlenString = 1
rdbZiplist32bitlenString = 2
rdbZiplistInt16 = 0xc0
rdbZiplistInt32 = 0xd0
rdbZiplistInt64 = 0xe0
rdbZiplistInt24 = 0xf0
rdbZiplistInt8 = 0xfe
rdbZiplistInt4 = 15
)
func (d *decode) decode() error {
err := d.checkHeader()
if err != nil {
return err
}
d.event.StartRDB()
var db uint32
var expiry int64
firstDB := true
for {
objType, err := d.r.ReadByte()
if err != nil {
return err
}
switch objType {
case rdbFlagAux:
auxKey, err := d.readString()
if err != nil {
return err
}
auxVal, err := d.readString()
if err != nil {
return err
}
d.event.Aux(auxKey, auxVal)
case rdbFlagResizeDB:
dbSize, _, err := d.readLength()
if err != nil {
return err
}
expiresSize, _, err := d.readLength()
if err != nil {
return err
}
d.event.ResizeDatabase(dbSize, expiresSize)
case rdbFlagExpiryMS:
_, err := io.ReadFull(d.r, d.intBuf)
if err != nil {
return err
}
expiry = int64(binary.LittleEndian.Uint64(d.intBuf))
case rdbFlagExpiry:
_, err := io.ReadFull(d.r, d.intBuf[:4])
if err != nil {
return err
}
expiry = int64(binary.LittleEndian.Uint32(d.intBuf)) * 1000
case rdbFlagSelectDB:
if !firstDB {
d.event.EndDatabase(int(db))
}
db, _, err = d.readLength()
if err != nil {
return err
}
d.event.StartDatabase(int(db))
case rdbFlagEOF:
d.event.EndDatabase(int(db))
d.event.EndRDB()
return nil
default:
key, err := d.readString()
if err != nil {
return err
}
err = d.readObject(key, ValueType(objType), expiry)
if err != nil {
return err
}
expiry = 0
}
}
panic("not reached")
}
func (d *decode) readObject(key []byte, typ ValueType, expiry int64) error {
switch typ {
case TypeString:
value, err := d.readString()
if err != nil {
return err
}
d.event.Set(key, value, expiry)
case TypeList:
length, _, err := d.readLength()
if err != nil {
return err
}
d.event.StartList(key, int64(length), expiry)
for i := uint32(0); i < length; i++ {
value, err := d.readString()
if err != nil {
return err
}
d.event.Rpush(key, value)
}
d.event.EndList(key)
case TypeListQuicklist:
length, _, err := d.readLength()
if err != nil {
return err
}
d.event.StartList(key, int64(-1), expiry)
for i := uint32(0); i < length; i++ {
d.readZiplist(key, 0, false)
}
d.event.EndList(key)
case TypeSet:
cardinality, _, err := d.readLength()
if err != nil {
return err
}
d.event.StartSet(key, int64(cardinality), expiry)
for i := uint32(0); i < cardinality; i++ {
member, err := d.readString()
if err != nil {
return err
}
d.event.Sadd(key, member)
}
d.event.EndSet(key)
case TypeZSet:
cardinality, _, err := d.readLength()
if err != nil {
return err
}
d.event.StartZSet(key, int64(cardinality), expiry)
for i := uint32(0); i < cardinality; i++ {
member, err := d.readString()
if err != nil {
return err
}
score, err := d.readFloat64()
if err != nil {
return err
}
d.event.Zadd(key, score, member)
}
d.event.EndZSet(key)
case TypeHash:
length, _, err := d.readLength()
if err != nil {
return err
}
d.event.StartHash(key, int64(length), expiry)
for i := uint32(0); i < length; i++ {
field, err := d.readString()
if err != nil {
return err
}
value, err := d.readString()
if err != nil {
return err
}
d.event.Hset(key, field, value)
}
d.event.EndHash(key)
case TypeHashZipmap:
return d.readZipmap(key, expiry)
case TypeListZiplist:
return d.readZiplist(key, expiry, true)
case TypeSetIntset:
return d.readIntset(key, expiry)
case TypeZSetZiplist:
return d.readZiplistZset(key, expiry)
case TypeHashZiplist:
return d.readZiplistHash(key, expiry)
default:
return fmt.Errorf("rdb: unknown object type %d for key %s", typ, key)
}
return nil
}
func (d *decode) readZipmap(key []byte, expiry int64) error {
var length int
zipmap, err := d.readString()
if err != nil {
return err
}
buf := newSliceBuffer(zipmap)
lenByte, err := buf.ReadByte()
if err != nil {
return err
}
if lenByte >= 254 { // we need to count the items manually
length, err = countZipmapItems(buf)
length /= 2
if err != nil {
return err
}
} else {
length = int(lenByte)
}
d.event.StartHash(key, int64(length), expiry)
for i := 0; i < length; i++ {
field, err := readZipmapItem(buf, false)
if err != nil {
return err
}
value, err := readZipmapItem(buf, true)
if err != nil {
return err
}
d.event.Hset(key, field, value)
}
d.event.EndHash(key)
return nil
}
func readZipmapItem(buf *sliceBuffer, readFree bool) ([]byte, error) {
length, free, err := readZipmapItemLength(buf, readFree)
if err != nil {
return nil, err
}
if length == -1 {
return nil, nil
}
value, err := buf.Slice(length)
if err != nil {
return nil, err
}
_, err = buf.Seek(int64(free), 1)
return value, err
}
func countZipmapItems(buf *sliceBuffer) (int, error) {
n := 0
for {
strLen, free, err := readZipmapItemLength(buf, n%2 != 0)
if err != nil {
return 0, err
}
if strLen == -1 {
break
}
_, err = buf.Seek(int64(strLen)+int64(free), 1)
if err != nil {
return 0, err
}
n++
}
_, err := buf.Seek(0, 0)
return n, err
}
func readZipmapItemLength(buf *sliceBuffer, readFree bool) (int, int, error) {
b, err := buf.ReadByte()
if err != nil {
return 0, 0, err
}
switch b {
case 253:
s, err := buf.Slice(5)
if err != nil {
return 0, 0, err
}
return int(binary.BigEndian.Uint32(s)), int(s[4]), nil
case 254:
return 0, 0, fmt.Errorf("rdb: invalid zipmap item length")
case 255:
return -1, 0, nil
}
var free byte
if readFree {
free, err = buf.ReadByte()
}
return int(b), int(free), err
}
func (d *decode) readZiplist(key []byte, expiry int64, addListEvents bool) error {
ziplist, err := d.readString()
if err != nil {
return err
}
buf := newSliceBuffer(ziplist)
length, err := readZiplistLength(buf)
if err != nil {
return err
}
if addListEvents {
d.event.StartList(key, length, expiry)
}
for i := int64(0); i < length; i++ {
entry, err := readZiplistEntry(buf)
if err != nil {
return err
}
d.event.Rpush(key, entry)
}
if addListEvents {
d.event.EndList(key)
}
return nil
}
func (d *decode) readZiplistZset(key []byte, expiry int64) error {
ziplist, err := d.readString()
if err != nil {
return err
}
buf := newSliceBuffer(ziplist)
cardinality, err := readZiplistLength(buf)
if err != nil {
return err
}
cardinality /= 2
d.event.StartZSet(key, cardinality, expiry)
for i := int64(0); i < cardinality; i++ {
member, err := readZiplistEntry(buf)
if err != nil {
return err
}
scoreBytes, err := readZiplistEntry(buf)
if err != nil {
return err
}
score, err := strconv.ParseFloat(string(scoreBytes), 64)
if err != nil {
return err
}
d.event.Zadd(key, score, member)
}
d.event.EndZSet(key)
return nil
}
func (d *decode) readZiplistHash(key []byte, expiry int64) error {
ziplist, err := d.readString()
if err != nil {
return err
}
buf := newSliceBuffer(ziplist)
length, err := readZiplistLength(buf)
if err != nil {
return err
}
length /= 2
d.event.StartHash(key, length, expiry)
for i := int64(0); i < length; i++ {
field, err := readZiplistEntry(buf)
if err != nil {
return err
}
value, err := readZiplistEntry(buf)
if err != nil {
return err
}
d.event.Hset(key, field, value)
}
d.event.EndHash(key)
return nil
}
func readZiplistLength(buf *sliceBuffer) (int64, error) {
buf.Seek(8, 0) // skip the zlbytes and zltail
lenBytes, err := buf.Slice(2)
if err != nil {
return 0, err
}
return int64(binary.LittleEndian.Uint16(lenBytes)), nil
}
func readZiplistEntry(buf *sliceBuffer) ([]byte, error) {
prevLen, err := buf.ReadByte()
if err != nil {
return nil, err
}
if prevLen == 254 {
buf.Seek(4, 1) // skip the 4-byte prevlen
}
header, err := buf.ReadByte()
if err != nil {
return nil, err
}
switch {
case header>>6 == rdbZiplist6bitlenString:
return buf.Slice(int(header & 0x3f))
case header>>6 == rdbZiplist14bitlenString:
b, err := buf.ReadByte()
if err != nil {
return nil, err
}
return buf.Slice((int(header&0x3f) << 8) | int(b))
case header>>6 == rdbZiplist32bitlenString:
lenBytes, err := buf.Slice(4)
if err != nil {
return nil, err
}
return buf.Slice(int(binary.BigEndian.Uint32(lenBytes)))
case header == rdbZiplistInt16:
intBytes, err := buf.Slice(2)
if err != nil {
return nil, err
}
return []byte(strconv.FormatInt(int64(int16(binary.LittleEndian.Uint16(intBytes))), 10)), nil
case header == rdbZiplistInt32:
intBytes, err := buf.Slice(4)
if err != nil {
return nil, err
}
return []byte(strconv.FormatInt(int64(int32(binary.LittleEndian.Uint32(intBytes))), 10)), nil
case header == rdbZiplistInt64:
intBytes, err := buf.Slice(8)
if err != nil {
return nil, err
}
return []byte(strconv.FormatInt(int64(binary.LittleEndian.Uint64(intBytes)), 10)), nil
case header == rdbZiplistInt24:
intBytes := make([]byte, 4)
_, err := buf.Read(intBytes[1:])
if err != nil {
return nil, err
}
return []byte(strconv.FormatInt(int64(int32(binary.LittleEndian.Uint32(intBytes))>>8), 10)), nil
case header == rdbZiplistInt8:
b, err := buf.ReadByte()
return []byte(strconv.FormatInt(int64(int8(b)), 10)), err
case header>>4 == rdbZiplistInt4:
return []byte(strconv.FormatInt(int64(header&0x0f)-1, 10)), nil
}
return nil, fmt.Errorf("rdb: unknown ziplist header byte: %d", header)
}
func (d *decode) readIntset(key []byte, expiry int64) error {
intset, err := d.readString()
if err != nil {
return err
}
buf := newSliceBuffer(intset)
intSizeBytes, err := buf.Slice(4)
if err != nil {
return err
}
intSize := binary.LittleEndian.Uint32(intSizeBytes)
if intSize != 2 && intSize != 4 && intSize != 8 {
return fmt.Errorf("rdb: unknown intset encoding: %d", intSize)
}
lenBytes, err := buf.Slice(4)
if err != nil {
return err
}
cardinality := binary.LittleEndian.Uint32(lenBytes)
d.event.StartSet(key, int64(cardinality), expiry)
for i := uint32(0); i < cardinality; i++ {
intBytes, err := buf.Slice(int(intSize))
if err != nil {
return err
}
var intString string
switch intSize {
case 2:
intString = strconv.FormatInt(int64(int16(binary.LittleEndian.Uint16(intBytes))), 10)
case 4:
intString = strconv.FormatInt(int64(int32(binary.LittleEndian.Uint32(intBytes))), 10)
case 8:
intString = strconv.FormatInt(int64(int64(binary.LittleEndian.Uint64(intBytes))), 10)
}
d.event.Sadd(key, []byte(intString))
}
d.event.EndSet(key)
return nil
}
func (d *decode) checkHeader() error {
header := make([]byte, 9)
_, err := io.ReadFull(d.r, header)
if err != nil {
return err
}
if !bytes.Equal(header[:5], []byte("REDIS")) {
return fmt.Errorf("rdb: invalid file format")
}
version, _ := strconv.ParseInt(string(header[5:]), 10, 64)
if version < 1 || version > 7 {
return fmt.Errorf("rdb: invalid RDB version number %d", version)
}
return nil
}
func (d *decode) readString() ([]byte, error) {
length, encoded, err := d.readLength()
if err != nil {
return nil, err
}
if encoded {
switch length {
case rdbEncInt8:
i, err := d.readUint8()
return []byte(strconv.FormatInt(int64(int8(i)), 10)), err
case rdbEncInt16:
i, err := d.readUint16()
return []byte(strconv.FormatInt(int64(int16(i)), 10)), err
case rdbEncInt32:
i, err := d.readUint32()
return []byte(strconv.FormatInt(int64(int32(i)), 10)), err
case rdbEncLZF:
clen, _, err := d.readLength()
if err != nil {
return nil, err
}
ulen, _, err := d.readLength()
if err != nil {
return nil, err
}
compressed := make([]byte, clen)
_, err = io.ReadFull(d.r, compressed)
if err != nil {
return nil, err
}
decompressed := lzfDecompress(compressed, int(ulen))
if len(decompressed) != int(ulen) {
return nil, fmt.Errorf("decompressed string length %d didn't match expected length %d", len(decompressed), ulen)
}
return decompressed, nil
}
}
str := make([]byte, length)
_, err = io.ReadFull(d.r, str)
return str, err
}
func (d *decode) readUint8() (uint8, error) {
b, err := d.r.ReadByte()
return uint8(b), err
}
func (d *decode) readUint16() (uint16, error) {
_, err := io.ReadFull(d.r, d.intBuf[:2])
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint16(d.intBuf), nil
}
func (d *decode) readUint32() (uint32, error) {
_, err := io.ReadFull(d.r, d.intBuf[:4])
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint32(d.intBuf), nil
}
func (d *decode) readUint64() (uint64, error) {
_, err := io.ReadFull(d.r, d.intBuf)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint64(d.intBuf), nil
}
func (d *decode) readUint32Big() (uint32, error) {
_, err := io.ReadFull(d.r, d.intBuf[:4])
if err != nil {
return 0, err
}
return binary.BigEndian.Uint32(d.intBuf), nil
}
// Doubles are saved as strings prefixed by an unsigned
// 8 bit integer specifying the length of the representation.
// This 8 bit integer has special values in order to specify the following
// conditions:
// 253: not a number
// 254: + inf
// 255: - inf
func (d *decode) readFloat64() (float64, error) {
length, err := d.readUint8()
if err != nil {
return 0, err
}
switch length {
case 253:
return math.NaN(), nil
case 254:
return math.Inf(0), nil
case 255:
return math.Inf(-1), nil
default:
floatBytes := make([]byte, length)
_, err := io.ReadFull(d.r, floatBytes)
if err != nil {
return 0, err
}
f, err := strconv.ParseFloat(string(floatBytes), 64)
return f, err
}
panic("not reached")
}
func (d *decode) readLength() (uint32, bool, error) {
b, err := d.r.ReadByte()
if err != nil {
return 0, false, err
}
// The first two bits of the first byte are used to indicate the length encoding type
switch (b & 0xc0) >> 6 {
case rdb6bitLen:
// When the first two bits are 00, the next 6 bits are the length.
return uint32(b & 0x3f), false, nil
case rdb14bitLen:
// When the first two bits are 01, the next 14 bits are the length.
bb, err := d.r.ReadByte()
if err != nil {
return 0, false, err
}
return (uint32(b&0x3f) << 8) | uint32(bb), false, nil
case rdbEncVal:
// When the first two bits are 11, the next object is encoded.
// The next 6 bits indicate the encoding type.
return uint32(b & 0x3f), true, nil
default:
// When the first two bits are 10, the next 6 bits are discarded.
// The next 4 bytes are the length.
length, err := d.readUint32Big()
return length, false, err
}
panic("not reached")
}
func verifyDump(d []byte) error {
if len(d) < 10 {
return fmt.Errorf("rdb: invalid dump length")
}
version := binary.LittleEndian.Uint16(d[len(d)-10:])
if version != uint16(Version) {
return fmt.Errorf("rdb: invalid version %d, expecting %d", version, Version)
}
if binary.LittleEndian.Uint64(d[len(d)-8:]) != crc64.Digest(d[:len(d)-8]) {
return fmt.Errorf("rdb: invalid CRC checksum")
}
return nil
}
func lzfDecompress(in []byte, outlen int) []byte {
out := make([]byte, outlen)
for i, o := 0, 0; 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++
}
}
}
return out
}

130
vendor/github.com/cupcake/rdb/encoder.go generated vendored Normal file
View File

@ -0,0 +1,130 @@
package rdb
import (
"encoding/binary"
"fmt"
"hash"
"io"
"math"
"strconv"
"github.com/cupcake/rdb/crc64"
)
const Version = 6
type Encoder struct {
w io.Writer
crc hash.Hash
}
func NewEncoder(w io.Writer) *Encoder {
e := &Encoder{crc: crc64.New()}
e.w = io.MultiWriter(w, e.crc)
return e
}
func (e *Encoder) EncodeHeader() error {
_, err := fmt.Fprintf(e.w, "REDIS%04d", Version)
return err
}
func (e *Encoder) EncodeFooter() error {
e.w.Write([]byte{rdbFlagEOF})
_, err := e.w.Write(e.crc.Sum(nil))
return err
}
func (e *Encoder) EncodeDumpFooter() error {
binary.Write(e.w, binary.LittleEndian, uint16(Version))
_, err := e.w.Write(e.crc.Sum(nil))
return err
}
func (e *Encoder) EncodeDatabase(n int) error {
e.w.Write([]byte{rdbFlagSelectDB})
return e.EncodeLength(uint32(n))
}
func (e *Encoder) EncodeExpiry(expiry uint64) error {
b := make([]byte, 9)
b[0] = rdbFlagExpiryMS
binary.LittleEndian.PutUint64(b[1:], expiry)
_, err := e.w.Write(b)
return err
}
func (e *Encoder) EncodeType(v ValueType) error {
_, err := e.w.Write([]byte{byte(v)})
return err
}
func (e *Encoder) EncodeString(s []byte) error {
written, err := e.encodeIntString(s)
if written {
return err
}
e.EncodeLength(uint32(len(s)))
_, err = e.w.Write(s)
return err
}
func (e *Encoder) EncodeLength(l uint32) (err error) {
switch {
case l < 1<<6:
_, err = e.w.Write([]byte{byte(l)})
case l < 1<<14:
_, err = e.w.Write([]byte{byte(l>>8) | rdb14bitLen<<6, byte(l)})
default:
b := make([]byte, 5)
b[0] = rdb32bitLen << 6
binary.BigEndian.PutUint32(b[1:], l)
_, err = e.w.Write(b)
}
return
}
func (e *Encoder) EncodeFloat(f float64) (err error) {
switch {
case math.IsNaN(f):
_, err = e.w.Write([]byte{253})
case math.IsInf(f, 1):
_, err = e.w.Write([]byte{254})
case math.IsInf(f, -1):
_, err = e.w.Write([]byte{255})
default:
b := []byte(strconv.FormatFloat(f, 'g', 17, 64))
e.w.Write([]byte{byte(len(b))})
_, err = e.w.Write(b)
}
return
}
func (e *Encoder) encodeIntString(b []byte) (written bool, err error) {
s := string(b)
i, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return
}
// if the stringified parsed int isn't exactly the same, we can't encode it as an int
if s != strconv.FormatInt(i, 10) {
return
}
switch {
case i >= math.MinInt8 && i <= math.MaxInt8:
_, err = e.w.Write([]byte{rdbEncVal << 6, byte(int8(i))})
case i >= math.MinInt16 && i <= math.MaxInt16:
b := make([]byte, 3)
b[0] = rdbEncVal<<6 | rdbEncInt16
binary.LittleEndian.PutUint16(b[1:], uint16(int16(i)))
_, err = e.w.Write(b)
case i >= math.MinInt32 && i <= math.MaxInt32:
b := make([]byte, 5)
b[0] = rdbEncVal<<6 | rdbEncInt32
binary.LittleEndian.PutUint32(b[1:], uint32(int32(i)))
_, err = e.w.Write(b)
default:
return
}
return true, err
}

View File

@ -0,0 +1,24 @@
package nopdecoder
// NopDecoder may be embedded in a real Decoder to avoid implementing methods.
type NopDecoder struct{}
func (d NopDecoder) StartRDB() {}
func (d NopDecoder) StartDatabase(n int) {}
func (d NopDecoder) Aux(key, value []byte) {}
func (d NopDecoder) ResizeDatabase(dbSize, expiresSize uint32) {}
func (d NopDecoder) EndDatabase(n int) {}
func (d NopDecoder) EndRDB() {}
func (d NopDecoder) Set(key, value []byte, expiry int64) {}
func (d NopDecoder) StartHash(key []byte, length, expiry int64) {}
func (d NopDecoder) Hset(key, field, value []byte) {}
func (d NopDecoder) EndHash(key []byte) {}
func (d NopDecoder) StartSet(key []byte, cardinality, expiry int64) {}
func (d NopDecoder) Sadd(key, member []byte) {}
func (d NopDecoder) EndSet(key []byte) {}
func (d NopDecoder) StartList(key []byte, length, expiry int64) {}
func (d NopDecoder) Rpush(key, value []byte) {}
func (d NopDecoder) EndList(key []byte) {}
func (d NopDecoder) StartZSet(key []byte, cardinality, expiry int64) {}
func (d NopDecoder) Zadd(key []byte, score float64, member []byte) {}
func (d NopDecoder) EndZSet(key []byte) {}

67
vendor/github.com/cupcake/rdb/slice_buffer.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
package rdb
import (
"errors"
"io"
)
type sliceBuffer struct {
s []byte
i int
}
func newSliceBuffer(s []byte) *sliceBuffer {
return &sliceBuffer{s, 0}
}
func (s *sliceBuffer) Slice(n int) ([]byte, error) {
if s.i+n > len(s.s) {
return nil, io.EOF
}
b := s.s[s.i : s.i+n]
s.i += n
return b, nil
}
func (s *sliceBuffer) ReadByte() (byte, error) {
if s.i >= len(s.s) {
return 0, io.EOF
}
b := s.s[s.i]
s.i++
return b, nil
}
func (s *sliceBuffer) Read(b []byte) (int, error) {
if len(b) == 0 {
return 0, nil
}
if s.i >= len(s.s) {
return 0, io.EOF
}
n := copy(b, s.s[s.i:])
s.i += n
return n, nil
}
func (s *sliceBuffer) Seek(offset int64, whence int) (int64, error) {
var abs int64
switch whence {
case 0:
abs = offset
case 1:
abs = int64(s.i) + offset
case 2:
abs = int64(len(s.s)) + offset
default:
return 0, errors.New("invalid whence")
}
if abs < 0 {
return 0, errors.New("negative position")
}
if abs >= 1<<31 {
return 0, errors.New("position out of range")
}
s.i = int(abs)
return abs, nil
}