1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD 2*3b35e7eeSXin LI 381ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 481ad8388SMartin Matuska // 581ad8388SMartin Matuska /// \file stream_flags_encoder.c 681ad8388SMartin Matuska /// \brief Encodes Stream Header and Stream Footer for .xz files 781ad8388SMartin Matuska // 881ad8388SMartin Matuska // Author: Lasse Collin 981ad8388SMartin Matuska // 1081ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 1181ad8388SMartin Matuska 1281ad8388SMartin Matuska #include "stream_flags_common.h" 1381ad8388SMartin Matuska 1481ad8388SMartin Matuska 1581ad8388SMartin Matuska static bool 1681ad8388SMartin Matuska stream_flags_encode(const lzma_stream_flags *options, uint8_t *out) 1781ad8388SMartin Matuska { 1881ad8388SMartin Matuska if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX) 1981ad8388SMartin Matuska return true; 2081ad8388SMartin Matuska 2181ad8388SMartin Matuska out[0] = 0x00; 2281ad8388SMartin Matuska out[1] = options->check; 2381ad8388SMartin Matuska 2481ad8388SMartin Matuska return false; 2581ad8388SMartin Matuska } 2681ad8388SMartin Matuska 2781ad8388SMartin Matuska 2881ad8388SMartin Matuska extern LZMA_API(lzma_ret) 2981ad8388SMartin Matuska lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out) 3081ad8388SMartin Matuska { 3181ad8388SMartin Matuska assert(sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE 3281ad8388SMartin Matuska + 4 == LZMA_STREAM_HEADER_SIZE); 3381ad8388SMartin Matuska 3481ad8388SMartin Matuska if (options->version != 0) 3581ad8388SMartin Matuska return LZMA_OPTIONS_ERROR; 3681ad8388SMartin Matuska 3781ad8388SMartin Matuska // Magic 3881ad8388SMartin Matuska memcpy(out, lzma_header_magic, sizeof(lzma_header_magic)); 3981ad8388SMartin Matuska 4081ad8388SMartin Matuska // Stream Flags 4181ad8388SMartin Matuska if (stream_flags_encode(options, out + sizeof(lzma_header_magic))) 4281ad8388SMartin Matuska return LZMA_PROG_ERROR; 4381ad8388SMartin Matuska 4481ad8388SMartin Matuska // CRC32 of the Stream Header 4581ad8388SMartin Matuska const uint32_t crc = lzma_crc32(out + sizeof(lzma_header_magic), 4681ad8388SMartin Matuska LZMA_STREAM_FLAGS_SIZE, 0); 4781ad8388SMartin Matuska 48a8675d92SXin LI write32le(out + sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE, 49a8675d92SXin LI crc); 5081ad8388SMartin Matuska 5181ad8388SMartin Matuska return LZMA_OK; 5281ad8388SMartin Matuska } 5381ad8388SMartin Matuska 5481ad8388SMartin Matuska 5581ad8388SMartin Matuska extern LZMA_API(lzma_ret) 5681ad8388SMartin Matuska lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out) 5781ad8388SMartin Matuska { 5881ad8388SMartin Matuska assert(2 * 4 + LZMA_STREAM_FLAGS_SIZE + sizeof(lzma_footer_magic) 5981ad8388SMartin Matuska == LZMA_STREAM_HEADER_SIZE); 6081ad8388SMartin Matuska 6181ad8388SMartin Matuska if (options->version != 0) 6281ad8388SMartin Matuska return LZMA_OPTIONS_ERROR; 6381ad8388SMartin Matuska 6481ad8388SMartin Matuska // Backward Size 6581ad8388SMartin Matuska if (!is_backward_size_valid(options)) 6681ad8388SMartin Matuska return LZMA_PROG_ERROR; 6781ad8388SMartin Matuska 68a8675d92SXin LI write32le(out + 4, options->backward_size / 4 - 1); 6981ad8388SMartin Matuska 7081ad8388SMartin Matuska // Stream Flags 7181ad8388SMartin Matuska if (stream_flags_encode(options, out + 2 * 4)) 7281ad8388SMartin Matuska return LZMA_PROG_ERROR; 7381ad8388SMartin Matuska 7481ad8388SMartin Matuska // CRC32 7581ad8388SMartin Matuska const uint32_t crc = lzma_crc32( 7681ad8388SMartin Matuska out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0); 7781ad8388SMartin Matuska 78a8675d92SXin LI write32le(out, crc); 7981ad8388SMartin Matuska 8081ad8388SMartin Matuska // Magic 8181ad8388SMartin Matuska memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE, 8281ad8388SMartin Matuska lzma_footer_magic, sizeof(lzma_footer_magic)); 8381ad8388SMartin Matuska 8481ad8388SMartin Matuska return LZMA_OK; 8581ad8388SMartin Matuska } 86