OLD | NEW |
(Empty) | |
| 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 // |
| 3 /// \file vli_encoder.c |
| 4 /// \brief Encodes variable-length integers |
| 5 // |
| 6 // Author: Lasse Collin |
| 7 // |
| 8 // This file has been put into the public domain. |
| 9 // You can do whatever you want with this file. |
| 10 // |
| 11 /////////////////////////////////////////////////////////////////////////////// |
| 12 |
| 13 #include "common.h" |
| 14 |
| 15 |
| 16 extern LZMA_API(lzma_ret) |
| 17 lzma_vli_encode(lzma_vli vli, size_t *vli_pos, |
| 18 uint8_t *restrict out, size_t *restrict out_pos, |
| 19 size_t out_size) |
| 20 { |
| 21 // If we haven't been given vli_pos, work in single-call mode. |
| 22 size_t vli_pos_internal = 0; |
| 23 if (vli_pos == NULL) { |
| 24 vli_pos = &vli_pos_internal; |
| 25 |
| 26 // In single-call mode, we expect that the caller has |
| 27 // reserved enough output space. |
| 28 if (*out_pos >= out_size) |
| 29 return LZMA_PROG_ERROR; |
| 30 } else { |
| 31 // This never happens when we are called by liblzma, but |
| 32 // may happen if called directly from an application. |
| 33 if (*out_pos >= out_size) |
| 34 return LZMA_BUF_ERROR; |
| 35 } |
| 36 |
| 37 // Validate the arguments. |
| 38 if (*vli_pos >= LZMA_VLI_BYTES_MAX || vli > LZMA_VLI_MAX) |
| 39 return LZMA_PROG_ERROR; |
| 40 |
| 41 // Shift vli so that the next bits to encode are the lowest. In |
| 42 // single-call mode this never changes vli since *vli_pos is zero. |
| 43 vli >>= *vli_pos * 7; |
| 44 |
| 45 // Write the non-last bytes in a loop. |
| 46 while (vli >= 0x80) { |
| 47 // We don't need *vli_pos during this function call anymore, |
| 48 // but update it here so that it is ready if we need to |
| 49 // return before the whole integer has been decoded. |
| 50 ++*vli_pos; |
| 51 assert(*vli_pos < LZMA_VLI_BYTES_MAX); |
| 52 |
| 53 // Write the next byte. |
| 54 out[*out_pos] = (uint8_t)(vli) | 0x80; |
| 55 vli >>= 7; |
| 56 |
| 57 if (++*out_pos == out_size) |
| 58 return vli_pos == &vli_pos_internal |
| 59 ? LZMA_PROG_ERROR : LZMA_OK; |
| 60 } |
| 61 |
| 62 // Write the last byte. |
| 63 out[*out_pos] = (uint8_t)(vli); |
| 64 ++*out_pos; |
| 65 ++*vli_pos; |
| 66 |
| 67 return vli_pos == &vli_pos_internal ? LZMA_OK : LZMA_STREAM_END; |
| 68 |
| 69 } |
OLD | NEW |