1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file vli_decoder.c
4 /// \brief Decodes variable-length integers
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
16 extern LZMA_API(lzma_ret
)
17 lzma_vli_decode(lzma_vli
*restrict vli
, size_t *vli_pos
,
18 const uint8_t *restrict in
, size_t *restrict in_pos
,
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
;
27 // If there's no input, use LZMA_DATA_ERROR. This way it is
28 // easy to decode VLIs from buffers that have known size,
29 // and get the correct error code in case the buffer is
31 if (*in_pos
>= in_size
)
32 return LZMA_DATA_ERROR
;
35 // Initialize *vli when starting to decode a new integer.
39 // Validate the arguments.
40 if (*vli_pos
>= LZMA_VLI_BYTES_MAX
41 || (*vli
>> (*vli_pos
* 7)) != 0)
42 return LZMA_PROG_ERROR
;;
44 if (*in_pos
>= in_size
)
45 return LZMA_BUF_ERROR
;
49 // Read the next byte. Use a temporary variable so that we
50 // can update *in_pos immediately.
51 const uint8_t byte
= in
[*in_pos
];
54 // Add the newly read byte to *vli.
55 *vli
+= (lzma_vli
)(byte
& 0x7F) << (*vli_pos
* 7);
58 // Check if this is the last byte of a multibyte integer.
59 if ((byte
& 0x80) == 0) {
60 // We don't allow using variable-length integers as
61 // padding i.e. the encoding must use the most the
63 if (byte
== 0x00 && *vli_pos
> 1)
64 return LZMA_DATA_ERROR
;
66 return vli_pos
== &vli_pos_internal
67 ? LZMA_OK
: LZMA_STREAM_END
;
70 // There is at least one more byte coming. If we have already
71 // read maximum number of bytes, the integer is considered
74 // If we need bigger integers in future, old versions liblzma
75 // will confusingly indicate the file being corrupt istead of
76 // unsupported. I suppose it's still better this way, because
77 // in the foreseeable future (writing this in 2008) the only
78 // reason why files would appear having over 63-bit integers
79 // is that the files are simply corrupt.
80 if (*vli_pos
== LZMA_VLI_BYTES_MAX
)
81 return LZMA_DATA_ERROR
;
83 } while (*in_pos
< in_size
);
85 return vli_pos
== &vli_pos_internal
? LZMA_DATA_ERROR
: LZMA_OK
;