]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/stream_flags_encoder.c
Improved the Stream Flags handling API.
[icculus/xz.git] / src / liblzma / common / stream_flags_encoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       stream_flags_encoder.c
4 /// \brief      Encodes Stream Header and Stream Footer for .lzma files
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 "stream_flags_common.h"
21
22
23 static bool
24 stream_flags_encode(const lzma_stream_flags *options, uint8_t *out)
25 {
26         if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
27                 return true;
28
29         out[0] = 0x00;
30         out[1] = options->check;
31
32         return false;
33 }
34
35
36 extern LZMA_API lzma_ret
37 lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out)
38 {
39         assert(sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE
40                         + 4 == LZMA_STREAM_HEADER_SIZE);
41
42         if (options->version != 0)
43                 return LZMA_HEADER_ERROR;
44
45         // Magic
46         memcpy(out, lzma_header_magic, sizeof(lzma_header_magic));
47
48         // Stream Flags
49         if (stream_flags_encode(options, out + sizeof(lzma_header_magic)))
50                 return LZMA_PROG_ERROR;
51
52         // CRC32 of the Stream Header
53         const uint32_t crc = lzma_crc32(out + sizeof(lzma_header_magic),
54                         LZMA_STREAM_FLAGS_SIZE, 0);
55
56         integer_write_32(out + sizeof(lzma_header_magic)
57                         + LZMA_STREAM_FLAGS_SIZE, crc);
58
59         return LZMA_OK;
60 }
61
62
63 extern LZMA_API lzma_ret
64 lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out)
65 {
66         assert(2 * 4 + LZMA_STREAM_FLAGS_SIZE + sizeof(lzma_footer_magic)
67                         == LZMA_STREAM_HEADER_SIZE);
68
69         if (options->version != 0)
70                 return LZMA_HEADER_ERROR;
71
72         // Backward Size
73         if (!is_backward_size_valid(options))
74                 return LZMA_PROG_ERROR;
75
76         integer_write_32(out + 4, options->backward_size / 4 - 1);
77
78         // Stream Flags
79         if (stream_flags_encode(options, out + 2 * 4))
80                 return LZMA_PROG_ERROR;
81
82         // CRC32
83         const uint32_t crc = lzma_crc32(
84                         out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0);
85
86         integer_write_32(out, crc);
87
88         // Magic
89         memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE,
90                         lzma_footer_magic, sizeof(lzma_footer_magic));
91
92         return LZMA_OK;
93 }