blob: b975954c1cd1cdc5a91be9f9f2b58d341080bc53 [file] [log] [blame]
Dinesh Belwalkare63f7f92019-11-22 23:11:16 +00001// Package zstd provides decompression of zstandard files.
2//
3// For advanced usage and examples, go to the README: https://github.com/klauspost/compress/tree/master/zstd#zstd
4package zstd
5
6import (
7 "errors"
8 "log"
9 "math/bits"
10)
11
12const debug = false
13const debugSequences = false
14
15// force encoder to use predefined tables.
16const forcePreDef = false
17
18// zstdMinMatch is the minimum zstd match length.
19const zstdMinMatch = 3
20
21var (
22 // ErrReservedBlockType is returned when a reserved block type is found.
23 // Typically this indicates wrong or corrupted input.
24 ErrReservedBlockType = errors.New("invalid input: reserved block type encountered")
25
26 // ErrCompressedSizeTooBig is returned when a block is bigger than allowed.
27 // Typically this indicates wrong or corrupted input.
28 ErrCompressedSizeTooBig = errors.New("invalid input: compressed size too big")
29
30 // ErrBlockTooSmall is returned when a block is too small to be decoded.
31 // Typically returned on invalid input.
32 ErrBlockTooSmall = errors.New("block too small")
33
34 // ErrMagicMismatch is returned when a "magic" number isn't what is expected.
35 // Typically this indicates wrong or corrupted input.
36 ErrMagicMismatch = errors.New("invalid input: magic number mismatch")
37
38 // ErrWindowSizeExceeded is returned when a reference exceeds the valid window size.
39 // Typically this indicates wrong or corrupted input.
40 ErrWindowSizeExceeded = errors.New("window size exceeded")
41
42 // ErrWindowSizeTooSmall is returned when no window size is specified.
43 // Typically this indicates wrong or corrupted input.
44 ErrWindowSizeTooSmall = errors.New("invalid input: window size was too small")
45
46 // ErrDecoderSizeExceeded is returned if decompressed size exceeds the configured limit.
47 ErrDecoderSizeExceeded = errors.New("decompressed size exceeds configured limit")
48
49 // ErrUnknownDictionary is returned if the dictionary ID is unknown.
50 // For the time being dictionaries are not supported.
51 ErrUnknownDictionary = errors.New("unknown dictionary")
52
53 // ErrFrameSizeExceeded is returned if the stated frame size is exceeded.
54 // This is only returned if SingleSegment is specified on the frame.
55 ErrFrameSizeExceeded = errors.New("frame size exceeded")
56
57 // ErrCRCMismatch is returned if CRC mismatches.
58 ErrCRCMismatch = errors.New("CRC check failed")
59
60 // ErrDecoderClosed will be returned if the Decoder was used after
61 // Close has been called.
62 ErrDecoderClosed = errors.New("decoder used after Close")
63)
64
65func println(a ...interface{}) {
66 if debug {
67 log.Println(a...)
68 }
69}
70
71func printf(format string, a ...interface{}) {
72 if debug {
73 log.Printf(format, a...)
74 }
75}
76
77// matchLen returns the maximum length.
78// a must be the shortest of the two.
79// The function also returns whether all bytes matched.
80func matchLen(a, b []byte) int {
81 b = b[:len(a)]
82 for i := 0; i < len(a)-7; i += 8 {
83 if diff := load64(a, i) ^ load64(b, i); diff != 0 {
84 return i + (bits.TrailingZeros64(diff) >> 3)
85 }
86 }
87 checked := (len(a) >> 3) << 3
88 a = a[checked:]
89 b = b[checked:]
90 // TODO: We could do a 4 check.
91 for i := range a {
92 if a[i] != b[i] {
93 return int(i) + checked
94 }
95 }
96 return len(a) + checked
97}
98
99// matchLen returns a match length in src between index s and t
100func matchLenIn(src []byte, s, t int32) int32 {
101 s1 := len(src)
102 b := src[t:]
103 a := src[s:s1]
104 b = b[:len(a)]
105 // Extend the match to be as long as possible.
106 for i := range a {
107 if a[i] != b[i] {
108 return int32(i)
109 }
110 }
111 return int32(len(a))
112}
113
114func load3232(b []byte, i int32) uint32 {
115 // Help the compiler eliminate bounds checks on the read so it can be done in a single read.
116 b = b[i:]
117 b = b[:4]
118 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
119}
120
121func load6432(b []byte, i int32) uint64 {
122 // Help the compiler eliminate bounds checks on the read so it can be done in a single read.
123 b = b[i:]
124 b = b[:8]
125 return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
126 uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
127}
128
129func load64(b []byte, i int) uint64 {
130 // Help the compiler eliminate bounds checks on the read so it can be done in a single read.
131 b = b[i:]
132 b = b[:8]
133 return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
134 uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
135}