| /////////////////////////////////////////////////////////////////////////////// |
| // |
| /// \file vli_encoder.c |
| /// \brief Encodes variable-length integers |
| // |
| // Copyright (C) 2007 Lasse Collin |
| // |
| // This library is free software; you can redistribute it and/or |
| // modify it under the terms of the GNU Lesser General Public |
| // License as published by the Free Software Foundation; either |
| // version 2.1 of the License, or (at your option) any later version. |
| // |
| // This library is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| // Lesser General Public License for more details. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include "common.h" |
| |
| |
| extern LZMA_API lzma_ret |
| lzma_vli_encode(lzma_vli vli, size_t *restrict vli_pos, size_t vli_size, |
| uint8_t *restrict out, size_t *restrict out_pos, |
| size_t out_size) |
| { |
| if (vli > LZMA_VLI_VALUE_MAX || *vli_pos >= 9 || vli_size > 9 |
| || (vli != 0 && (vli >> (7 * *vli_pos)) == 0)) |
| return LZMA_PROG_ERROR; |
| |
| if (*out_pos >= out_size) |
| return LZMA_BUF_ERROR; |
| |
| if (*vli_pos == 0) { |
| *vli_pos = 1; |
| |
| if (vli <= 0x7F && *vli_pos >= vli_size) { |
| // Single-byte integer |
| out[(*out_pos)++] = vli; |
| return LZMA_STREAM_END; |
| } |
| |
| // First byte of a multibyte integer |
| out[(*out_pos)++] = (vli & 0x7F) | 0x80; |
| } |
| |
| while (*out_pos < out_size) { |
| const lzma_vli b = vli >> (7 * *vli_pos); |
| ++*vli_pos; |
| |
| if (b <= 0x7F && *vli_pos >= vli_size) { |
| // Last byte of a multibyte integer |
| out[(*out_pos)++] = (b & 0xFF) | 0x80; |
| return LZMA_STREAM_END; |
| } |
| |
| // Middle byte of a multibyte integer |
| out[(*out_pos)++] = b & 0x7F; |
| } |
| |
| // vli is not yet completely written out. |
| return LZMA_OK; |
| } |
| |
| |
| extern LZMA_API size_t |
| lzma_vli_size(lzma_vli vli) |
| { |
| if (vli > LZMA_VLI_VALUE_MAX) |
| return 0; |
| |
| size_t i = 0; |
| do { |
| vli >>= 7; |
| ++i; |
| } while (vli != 0); |
| |
| assert(i <= 9); |
| return i; |
| } |