]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/vli_encoder.c
Update the code to mostly match the new simpler file format
[icculus/xz.git] / src / liblzma / common / vli_encoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       vli_encoder.c
4 /// \brief      Encodes variable-length integers
5 //
6 //  Copyright (C) 2007-2008 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "common.h"
21
22
23 extern LZMA_API lzma_ret
24 lzma_vli_encode(lzma_vli vli, size_t *restrict vli_pos,
25                 uint8_t *restrict out, size_t *restrict out_pos,
26                 size_t out_size)
27 {
28         // If we haven't been given vli_pos, work in single-call mode.
29         size_t vli_pos_internal = 0;
30         if (vli_pos == NULL)
31                 vli_pos = &vli_pos_internal;
32
33         // Validate the arguments.
34         if (*vli_pos >= LZMA_VLI_BYTES_MAX || *out_pos >= out_size
35                         || vli > LZMA_VLI_VALUE_MAX)
36                 return LZMA_PROG_ERROR;
37
38         // Write the non-last bytes in a loop.
39         while ((vli >> (*vli_pos * 7)) >= 0x80) {
40                 out[*out_pos] = (uint8_t)(vli >> (*vli_pos * 7)) | 0x80;
41
42                 ++*vli_pos;
43                 assert(*vli_pos < LZMA_VLI_BYTES_MAX);
44
45                 if (++*out_pos == out_size)
46                         return vli_pos == &vli_pos_internal
47                                         ? LZMA_PROG_ERROR : LZMA_OK;
48         }
49
50         // Write the last byte.
51         out[*out_pos] = (uint8_t)(vli >> (*vli_pos * 7));
52         ++*out_pos;
53         ++*vli_pos;
54
55         return vli_pos == &vli_pos_internal ? LZMA_OK : LZMA_STREAM_END;
56
57 }
58
59
60 extern LZMA_API uint32_t
61 lzma_vli_size(lzma_vli vli)
62 {
63         if (vli > LZMA_VLI_VALUE_MAX)
64                 return 0;
65
66         uint32_t i = 0;
67         do {
68                 vli >>= 7;
69                 ++i;
70         } while (vli != 0);
71
72         assert(i <= LZMA_VLI_BYTES_MAX);
73         return i;
74 }