1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file stream_flags_encoder.c 6 /// \brief Encodes Stream Header and Stream Footer for .xz files 7 // 8 // Author: Lasse Collin 9 // 10 /////////////////////////////////////////////////////////////////////////////// 11 12 #include "stream_flags_common.h" 13 14 15 static bool 16 stream_flags_encode(const lzma_stream_flags *options, uint8_t *out) 17 { 18 if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX) 19 return true; 20 21 out[0] = 0x00; 22 out[1] = options->check; 23 24 return false; 25 } 26 27 28 extern LZMA_API(lzma_ret) 29 lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out) 30 { 31 assert(sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE 32 + 4 == LZMA_STREAM_HEADER_SIZE); 33 34 if (options->version != 0) 35 return LZMA_OPTIONS_ERROR; 36 37 // Magic 38 memcpy(out, lzma_header_magic, sizeof(lzma_header_magic)); 39 40 // Stream Flags 41 if (stream_flags_encode(options, out + sizeof(lzma_header_magic))) 42 return LZMA_PROG_ERROR; 43 44 // CRC32 of the Stream Header 45 const uint32_t crc = lzma_crc32(out + sizeof(lzma_header_magic), 46 LZMA_STREAM_FLAGS_SIZE, 0); 47 48 write32le(out + sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE, 49 crc); 50 51 return LZMA_OK; 52 } 53 54 55 extern LZMA_API(lzma_ret) 56 lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out) 57 { 58 assert(2 * 4 + LZMA_STREAM_FLAGS_SIZE + sizeof(lzma_footer_magic) 59 == LZMA_STREAM_HEADER_SIZE); 60 61 if (options->version != 0) 62 return LZMA_OPTIONS_ERROR; 63 64 // Backward Size 65 if (!is_backward_size_valid(options)) 66 return LZMA_PROG_ERROR; 67 68 write32le(out + 4, options->backward_size / 4 - 1); 69 70 // Stream Flags 71 if (stream_flags_encode(options, out + 2 * 4)) 72 return LZMA_PROG_ERROR; 73 74 // CRC32 75 const uint32_t crc = lzma_crc32( 76 out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0); 77 78 write32le(out, crc); 79 80 // Magic 81 memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE, 82 lzma_footer_magic, sizeof(lzma_footer_magic)); 83 84 return LZMA_OK; 85 } 86