]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/vli_reverse_decoder.c
Imported to git.
[icculus/xz.git] / src / liblzma / common / vli_reverse_decoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       vli_reverse_decoder.c
4 /// \brief      Decodes variable-length integers starting at end of the buffer
5 //
6 //  Copyright (C) 2007 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_reverse_decode(lzma_vli *vli, const uint8_t *in, size_t *in_size)
25 {
26         if (*in_size == 0)
27                 return LZMA_BUF_ERROR;
28
29         size_t i = *in_size - 1;
30         *vli = in[i] & 0x7F;
31
32         if (!(in[i] & 0x80)) {
33                 *in_size = i;
34                 return LZMA_OK;
35         }
36
37         const size_t end = *in_size > LZMA_VLI_BYTES_MAX
38                         ? *in_size - LZMA_VLI_BYTES_MAX : 0;
39
40         do {
41                 if (i-- == end) {
42                         if (*in_size < LZMA_VLI_BYTES_MAX)
43                                 return LZMA_BUF_ERROR;
44
45                         return LZMA_DATA_ERROR;
46                 }
47
48                 *vli <<= 7;
49                 *vli = in[i] & 0x7F;
50
51         } while (!(in[i] & 0x80));
52
53         *in_size = i;
54         return LZMA_OK;
55 }