1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file vli_encoder.c 4207753Smm/// \brief Encodes variable-length integers 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "common.h" 14207753Smm 15207753Smm 16207753Smmextern LZMA_API(lzma_ret) 17207753Smmlzma_vli_encode(lzma_vli vli, size_t *vli_pos, 18207753Smm uint8_t *restrict out, size_t *restrict out_pos, 19207753Smm size_t out_size) 20207753Smm{ 21207753Smm // If we haven't been given vli_pos, work in single-call mode. 22207753Smm size_t vli_pos_internal = 0; 23207753Smm if (vli_pos == NULL) { 24207753Smm vli_pos = &vli_pos_internal; 25207753Smm 26207753Smm // In single-call mode, we expect that the caller has 27207753Smm // reserved enough output space. 28207753Smm if (*out_pos >= out_size) 29207753Smm return LZMA_PROG_ERROR; 30207753Smm } else { 31207753Smm // This never happens when we are called by liblzma, but 32207753Smm // may happen if called directly from an application. 33207753Smm if (*out_pos >= out_size) 34207753Smm return LZMA_BUF_ERROR; 35207753Smm } 36207753Smm 37207753Smm // Validate the arguments. 38207753Smm if (*vli_pos >= LZMA_VLI_BYTES_MAX || vli > LZMA_VLI_MAX) 39207753Smm return LZMA_PROG_ERROR; 40207753Smm 41207753Smm // Shift vli so that the next bits to encode are the lowest. In 42207753Smm // single-call mode this never changes vli since *vli_pos is zero. 43207753Smm vli >>= *vli_pos * 7; 44207753Smm 45207753Smm // Write the non-last bytes in a loop. 46207753Smm while (vli >= 0x80) { 47207753Smm // We don't need *vli_pos during this function call anymore, 48207753Smm // but update it here so that it is ready if we need to 49207753Smm // return before the whole integer has been decoded. 50207753Smm ++*vli_pos; 51207753Smm assert(*vli_pos < LZMA_VLI_BYTES_MAX); 52207753Smm 53207753Smm // Write the next byte. 54207753Smm out[*out_pos] = (uint8_t)(vli) | 0x80; 55207753Smm vli >>= 7; 56207753Smm 57207753Smm if (++*out_pos == out_size) 58207753Smm return vli_pos == &vli_pos_internal 59207753Smm ? LZMA_PROG_ERROR : LZMA_OK; 60207753Smm } 61207753Smm 62207753Smm // Write the last byte. 63207753Smm out[*out_pos] = (uint8_t)(vli); 64207753Smm ++*out_pos; 65207753Smm ++*vli_pos; 66207753Smm 67207753Smm return vli_pos == &vli_pos_internal ? LZMA_OK : LZMA_STREAM_END; 68207753Smm 69207753Smm} 70