Encode returns the encoded form of src. The returned slice may be a sub-slice of dst if dst was large enough to hold the entire encoded block. Otherwise, a newly allocated slice will be returned. It is valid to pass a nil dst.
(dst, src []byte)
| 117 | // of dst if dst was large enough to hold the entire encoded block. Otherwise, |
| 118 | // a newly allocated slice will be returned. It is valid to pass a nil dst. |
| 119 | func (ctx *SmazzContext) Encode(dst, src []byte) ([]byte, error) { |
| 120 | if len(src) == 0 { |
| 121 | return src, nil |
| 122 | } |
| 123 | if src[0] == 0 { |
| 124 | return []byte{}, fmt.Errorf("can't encode a string beginning with 0") |
| 125 | } |
| 126 | orig := src |
| 127 | dst = dst[:0] |
| 128 | root := ctx.codeTrie.Root() |
| 129 | currPos := 0 |
| 130 | nLeft := len(src) |
| 131 | tmp := src |
| 132 | code := 0 |
| 133 | prefixLen := 0 |
| 134 | for currPos < nLeft { |
| 135 | node := root |
| 136 | for i, c := range tmp { |
| 137 | next := node.Walk(c) |
| 138 | if next == nil { |
| 139 | break |
| 140 | } |
| 141 | node = next |
| 142 | if node.Terminal() { |
| 143 | prefixLen = i + 1 |
| 144 | code = node.Val() |
| 145 | } |
| 146 | } |
| 147 | if prefixLen == 0 { |
| 148 | currPos++ |
| 149 | tmp = tmp[1:] |
| 150 | continue |
| 151 | } |
| 152 | // if trace && len(src[:currPos]) > 0 { |
| 153 | // fmt.Printf("append %d: '%s'\n", len(src[:currPos]), src[:currPos]) |
| 154 | // } |
| 155 | dst = appendSrc(dst, src[:currPos]) |
| 156 | // if trace { |
| 157 | // fmt.Printf("code %d: '%s'\n", code, string(ctx.codes[code])) |
| 158 | // } |
| 159 | dst = append(dst, byte(code)) |
| 160 | src = src[currPos+prefixLen:] |
| 161 | currPos = 0 |
| 162 | nLeft = len(src) |
| 163 | tmp = src |
| 164 | prefixLen = 0 |
| 165 | } |
| 166 | // if trace && len(src) > 0 { |
| 167 | // fmt.Printf("append %d: '%s'\n", len(src), src) |
| 168 | // } |
| 169 | dst = appendSrc(dst, src) |
| 170 | // Prefix with 0 and return original source if it grew |
| 171 | dst = append([]byte{0}, dst...) |
| 172 | if len(dst) > len(orig) { |
| 173 | return orig, nil |
| 174 | } |
| 175 | return dst, nil |
| 176 | } |