readListPackEntry returns: string content, int content, entry length(encoding+content+backlen), error
(buf []byte, cursor *int)
| 57 | |
| 58 | // readListPackEntry returns: string content, int content, entry length(encoding+content+backlen), error |
| 59 | func (dec *Decoder) readListPackEntry(buf []byte, cursor *int) ([]byte, int64, uint32, error) { |
| 60 | header, err := readByte(buf, cursor) |
| 61 | if err != nil { |
| 62 | return nil, 0, 0, err |
| 63 | } |
| 64 | switch header >> 6 { |
| 65 | case 0, 1: // 0xxxxxxx, uint7 |
| 66 | result := int64(int8(header)) |
| 67 | var contentLen uint32 = 1 |
| 68 | backlen := getBackLen(contentLen) |
| 69 | *cursor += int(backlen) |
| 70 | return nil, result, contentLen + backlen, nil |
| 71 | case 2: // 10xxxxxx + content, string(len<=63) |
| 72 | strLen := int(header & 0x3f) |
| 73 | result, err := readBytes(buf, cursor, strLen) |
| 74 | if err != nil { |
| 75 | return nil, 0, 0, err |
| 76 | } |
| 77 | var contentLen = uint32(1 + strLen) |
| 78 | backlen := getBackLen(contentLen) |
| 79 | *cursor += int(backlen) |
| 80 | return result, 0, contentLen + backlen, nil |
| 81 | } |
| 82 | // assert header == 11xxxxxx |
| 83 | switch header >> 4 { |
| 84 | case 12, 13: // 110xxxxx yyyyyyyy, int13 |
| 85 | // see https://github.com/CN-annotation-team/redis7.0-chinese-annotated/blob/fba43c524524cbdb54955a28af228b513420d78d/src/listpack.c#L586 |
| 86 | next, err := readByte(buf, cursor) |
| 87 | if err != nil { |
| 88 | return nil, 0, 0, err |
| 89 | } |
| 90 | val := ((uint(header) & 0x1F) << 8) | uint(next) |
| 91 | if val >= uint(1<<12) { |
| 92 | val = -(8191 - val) - 1 // val is uint, must use -(8191 - val), val - 8191 will cause overflow |
| 93 | } |
| 94 | result := int64(val) |
| 95 | var contentLen uint32 = 2 |
| 96 | backlen := getBackLen(contentLen) |
| 97 | *cursor += int(backlen) |
| 98 | return nil, result, contentLen + backlen, nil |
| 99 | case 14: // 1110xxxx yyyyyyyy + content, string(len < 1<<12) |
| 100 | dec.buffer[0] = header & 0x0f |
| 101 | dec.buffer[1], err = readByte(buf, cursor) |
| 102 | if err != nil { |
| 103 | return nil, 0, 0, err |
| 104 | } |
| 105 | strLen := binary.BigEndian.Uint16(dec.buffer[:2]) |
| 106 | result, err := readBytes(buf, cursor, int(strLen)) |
| 107 | if err != nil { |
| 108 | return nil, 0, 0, err |
| 109 | } |
| 110 | var contentLen = uint32(2 + strLen) |
| 111 | backlen := getBackLen(contentLen) |
| 112 | *cursor += int(backlen) |
| 113 | return result, 0, contentLen + backlen, nil |
| 114 | } |
| 115 | // assert header == 1111xxxx |
| 116 | switch header & 0x0f { |
no test coverage detected