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