Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmliblzma/liblzma/common/alone_encoder.c
Line
Count
Source
1
// SPDX-License-Identifier: 0BSD
2
3
///////////////////////////////////////////////////////////////////////////////
4
//
5
/// \file       alone_encoder.c
6
/// \brief      Encoder for LZMA_Alone files
7
//
8
//  Author:     Lasse Collin
9
//
10
///////////////////////////////////////////////////////////////////////////////
11
12
#include "common.h"
13
#include "lzma_encoder.h"
14
15
16
0
#define ALONE_HEADER_SIZE (1 + 4 + 8)
17
18
19
typedef struct {
20
  lzma_next_coder next;
21
22
  enum {
23
    SEQ_HEADER,
24
    SEQ_CODE,
25
  } sequence;
26
27
  size_t header_pos;
28
  uint8_t header[ALONE_HEADER_SIZE];
29
} lzma_alone_coder;
30
31
32
static lzma_ret
33
alone_encode(void *coder_ptr, const lzma_allocator *allocator,
34
    const uint8_t *restrict in, size_t *restrict in_pos,
35
    size_t in_size, uint8_t *restrict out,
36
    size_t *restrict out_pos, size_t out_size,
37
    lzma_action action)
38
0
{
39
0
  lzma_alone_coder *coder = coder_ptr;
40
41
0
  while (*out_pos < out_size)
42
0
  switch (coder->sequence) {
43
0
  case SEQ_HEADER:
44
0
    lzma_bufcpy(coder->header, &coder->header_pos,
45
0
        ALONE_HEADER_SIZE,
46
0
        out, out_pos, out_size);
47
0
    if (coder->header_pos < ALONE_HEADER_SIZE)
48
0
      return LZMA_OK;
49
50
0
    coder->sequence = SEQ_CODE;
51
0
    break;
52
53
0
  case SEQ_CODE:
54
0
    return coder->next.code(coder->next.coder,
55
0
        allocator, in, in_pos, in_size,
56
0
        out, out_pos, out_size, action);
57
58
0
  default:
59
0
    assert(0);
60
0
    return LZMA_PROG_ERROR;
61
0
  }
62
63
0
  return LZMA_OK;
64
0
}
65
66
67
static void
68
alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
69
0
{
70
0
  lzma_alone_coder *coder = coder_ptr;
71
0
  lzma_next_end(&coder->next, allocator);
72
0
  lzma_free(coder, allocator);
73
0
  return;
74
0
}
75
76
77
static lzma_ret
78
alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
79
    const lzma_options_lzma *options)
80
0
{
81
0
  lzma_next_coder_init(&alone_encoder_init, next, allocator);
82
83
0
  lzma_alone_coder *coder = next->coder;
84
85
0
  if (coder == NULL) {
86
0
    coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
87
0
    if (coder == NULL)
88
0
      return LZMA_MEM_ERROR;
89
90
0
    next->coder = coder;
91
0
    next->code = &alone_encode;
92
0
    next->end = &alone_encoder_end;
93
0
    coder->next = LZMA_NEXT_CODER_INIT;
94
0
  }
95
96
  // Basic initializations
97
0
  coder->sequence = SEQ_HEADER;
98
0
  coder->header_pos = 0;
99
100
  // Encode the header:
101
  // - Properties (1 byte)
102
0
  if (lzma_lzma_lclppb_encode(options, coder->header))
103
0
    return LZMA_OPTIONS_ERROR;
104
105
  // - Dictionary size (4 bytes)
106
0
  if (options->dict_size < LZMA_DICT_SIZE_MIN)
107
0
    return LZMA_OPTIONS_ERROR;
108
109
  // Round up to the next 2^n or 2^n + 2^(n - 1) depending on which
110
  // one is the next unless it is UINT32_MAX. While the header would
111
  // allow any 32-bit integer, we do this to keep the decoder of liblzma
112
  // accepting the resulting files.
113
0
  uint32_t d = options->dict_size - 1;
114
0
  d |= d >> 2;
115
0
  d |= d >> 3;
116
0
  d |= d >> 4;
117
0
  d |= d >> 8;
118
0
  d |= d >> 16;
119
0
  if (d != UINT32_MAX)
120
0
    ++d;
121
122
0
  write32le(coder->header + 1, d);
123
124
  // - Uncompressed size (always unknown and using EOPM)
125
0
  memset(coder->header + 1 + 4, 0xFF, 8);
126
127
  // Initialize the LZMA encoder.
128
0
  const lzma_filter_info filters[2] = {
129
0
    {
130
0
      .id = LZMA_FILTER_LZMA1,
131
0
      .init = &lzma_lzma_encoder_init,
132
0
      .options = (void *)(options),
133
0
    }, {
134
0
      .init = NULL,
135
0
    }
136
0
  };
137
138
0
  return lzma_next_filter_init(&coder->next, allocator, filters);
139
0
}
140
141
142
extern LZMA_API(lzma_ret)
143
lzma_alone_encoder(lzma_stream *strm, const lzma_options_lzma *options)
144
0
{
145
0
  lzma_next_strm_init(alone_encoder_init, strm, options);
146
147
0
  strm->internal->supported_actions[LZMA_RUN] = true;
148
0
  strm->internal->supported_actions[LZMA_FINISH] = true;
149
150
0
  return LZMA_OK;
151
0
}