| 195 | } // namespace |
| 196 | |
| 197 | size_t MaxCompressedLength(size_t source_bytes) { |
| 198 | // Avoid integer overflow that could cause undersized buffer allocations. |
| 199 | // Return std::numeric_limits<size_t>::max() to force a controlled allocation |
| 200 | // failure. |
| 201 | if (source_bytes > (std::numeric_limits<size_t>::max() - 32) / 7 * 6) { |
| 202 | return std::numeric_limits<size_t>::max(); |
| 203 | } |
| 204 | // Compressed data can be defined as: |
| 205 | // compressed := item* literal* |
| 206 | // item := literal* copy |
| 207 | // |
| 208 | // The trailing literal sequence has a space blowup of at most 62/60 |
| 209 | // since a literal of length 60 needs one tag byte + one extra byte |
| 210 | // for length information. |
| 211 | // |
| 212 | // Item blowup is trickier to measure. Suppose the "copy" op copies |
| 213 | // 4 bytes of data. Because of a special check in the encoding code, |
| 214 | // we produce a 4-byte copy only if the offset is < 65536. Therefore |
| 215 | // the copy op takes 3 bytes to encode, and this type of item leads |
| 216 | // to at most the 62/60 blowup for representing literals. |
| 217 | // |
| 218 | // Suppose the "copy" op copies 5 bytes of data. If the offset is big |
| 219 | // enough, it will take 5 bytes to encode the copy op. Therefore the |
| 220 | // worst case here is a one-byte literal followed by a five-byte copy. |
| 221 | // I.e., 6 bytes of input turn into 7 bytes of "compressed" data. |
| 222 | // |
| 223 | // This last factor dominates the blowup, so the final estimate is: |
| 224 | return 32 + source_bytes + source_bytes / 6; |
| 225 | } |
| 226 | |
| 227 | namespace { |
| 228 |
no outgoing calls