GCC Code Coverage Report


Directory: Svc/DpZLibCompressor/
File: DpZLibCompressor.cpp
Date: 2026-09-03 21:17:40
Exec Total Coverage
Lines: 74 79 93.7%
Functions: 7 7 100.0%
Branches: 74 92 80.4%

Line Branch Exec Source
1 // ======================================================================
2 // \title DpZLibCompressor.cpp
3 // \author kubiak
4 // \brief cpp file for DpZLibCompressor component implementation class
5 // ======================================================================
6
7 #include "Svc/DpZLibCompressor/DpZLibCompressor.hpp"
8
9 #include <cstring>
10
11 #include <Fw/Prm/ParamValid.hpp>
12
13 namespace Svc {
14
15 // ----------------------------------------------------------------------
16 // Component construction and destruction
17 // ----------------------------------------------------------------------
18
19 8 DpZLibCompressor ::DpZLibCompressor(const char* const compName) : DpZLibCompressorComponentBase(compName) {}
20
21 16 DpZLibCompressor ::~DpZLibCompressor() {}
22
23 // ----------------------------------------------------------------------
24 // Handler implementations for typed input ports
25 // ----------------------------------------------------------------------
26
27 8 void DpZLibCompressor::cleanupContext(ZLibCtx& ctx) {
28
2/2
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
8 if (ctx.compression_buffer.getSize() != 0) {
29 7 bufferCompressionReturn_out(0, ctx.compression_buffer);
30 }
31
32
2/2
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 2 times.
8 if (ctx.zlib_alloc_buffer.getSize() != 0) {
33 6 bufferZLibReturn_out(0, ctx.zlib_alloc_buffer);
34 }
35 8 }
36
37 8 Svc::CompressionAlgorithm DpZLibCompressor ::compressChunk_handler(FwIndexType portNum,
38 Fw::Buffer& buffer,
39 FwSizeType min_compression,
40 FwSizeType write_offset) {
41
1/1
✓ Branch 3 taken 8 times.
8 ZLibCtx ctx(*this);
42
43
2/2
✓ Branch 3 taken 8 times.
✓ Branch 8 taken 8 times.
8 ctx.compression_buffer = bufferCompressionGet_out(0, min_compression);
44
3/3
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
8 if (ctx.compression_buffer.getSize() == 0) {
45
1/1
✓ Branch 5 taken 1 times.
1 log_WARNING_LO_ZLibCompressionBadBuffer(min_compression);
46
47
1/1
✓ Branch 4 taken 1 times.
1 cleanupContext(ctx);
48
1/1
✓ Branch 1 taken 1 times.
1 return CompressionAlgorithm::UNCOMPRESSED;
49 }
50
51
1/1
✓ Branch 2 taken 7 times.
7 Fw::ParamValid param_valid;
52
1/1
✓ Branch 5 taken 7 times.
7 const FwSizeType zlib_alloc_size = paramGet_ZLibBufferSize(param_valid);
53 7 FW_ASSERT(FW_PARAM_OK(param_valid), param_valid);
54
55
2/2
✓ Branch 3 taken 7 times.
✓ Branch 8 taken 7 times.
7 ctx.zlib_alloc_buffer = bufferZLibGet_out(0, zlib_alloc_size);
56
3/3
✓ Branch 2 taken 7 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 6 times.
7 if (ctx.zlib_alloc_buffer.getSize() == 0) {
57
1/1
✓ Branch 5 taken 1 times.
1 log_WARNING_LO_ZLibAllocBadBuffer(zlib_alloc_size);
58
59
1/1
✓ Branch 4 taken 1 times.
1 cleanupContext(ctx);
60
1/1
✓ Branch 1 taken 1 times.
1 return CompressionAlgorithm::UNCOMPRESSED;
61 }
62
63 6 ctx.zlib_stream.zalloc = DpZLibCompressor::zlib_alloc_fn;
64 6 ctx.zlib_stream.zfree = DpZLibCompressor::zlib_free_fn;
65 6 ctx.zlib_stream.opaque = &ctx;
66
67
1/1
✓ Branch 3 taken 6 times.
6 const CompressionAlgorithm alg = zlibCompressionHelper(ctx, buffer);
68
69
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
6 if (alg != CompressionAlgorithm::UNCOMPRESSED) {
70 // Compression completed and the size is <= min size
71 // Copy the compressed data into the original buffer
72
73 // Check that there is sufficient room in the buffer
74 // for the compressed data. This should be guaranteed
75 // by the caller, but double checking
76 3 FW_ASSERT(buffer.getSize() - write_offset >= ctx.compression_buffer.getSize(),
77 static_cast<FwAssertArgType>(buffer.getSize()), static_cast<FwAssertArgType>(write_offset),
78 static_cast<FwAssertArgType>(ctx.compression_buffer.getSize()));
79
80
5/7
✓ Branch 1 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 11 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
3 (void)std::memcpy(buffer.getData() + write_offset, ctx.compression_buffer.getData(),
81 3 ctx.compression_buffer.getSize());
82
2/2
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
3 buffer.setSize(ctx.compression_buffer.getSize() + write_offset);
83 }
84
85
1/1
✓ Branch 4 taken 6 times.
6 cleanupContext(ctx);
86
1/1
✓ Branch 1 taken 6 times.
6 return alg;
87 8 }
88
89 6 CompressionAlgorithm DpZLibCompressor::zlibCompressionHelper(ZLibCtx& ctx, const Fw::Buffer& in_buffer) {
90
1/1
✓ Branch 2 taken 6 times.
6 Fw::ParamValid param_valid;
91
1/1
✓ Branch 5 taken 6 times.
6 const I8 compression_level = paramGet_CompressionLevel(param_valid);
92 6 FW_ASSERT(FW_PARAM_OK(param_valid), param_valid);
93
94 6 int zlib_ok = 0;
95
1/1
✓ Branch 3 taken 6 times.
6 zlib_ok = deflateInit(&ctx.zlib_stream, compression_level);
96
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (zlib_ok != Z_OK) {
97
1/1
✓ Branch 9 taken 1 times.
2 ctx.comp.log_WARNING_LO_ZLibInitError(
98
2/4
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 1 times.
2 zlib_ok, ctx.zlib_stream.msg == nullptr ? Fw::String("") : Fw::String(ctx.zlib_stream.msg));
99
1/1
✓ Branch 1 taken 1 times.
1 return CompressionAlgorithm::UNCOMPRESSED;
100 }
101
102
3/5
✓ Branch 4 taken 5 times.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
10 if (in_buffer.getSize() > std::numeric_limits<uInt>::max() ||
103
2/3
✓ Branch 5 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 5 times.
5 ctx.compression_buffer.getSize() > std::numeric_limits<uInt>::max()) {
104 ctx.comp.log_WARNING_LO_BufferTooBigForZLib(in_buffer.getSize(), ctx.compression_buffer.getSize(),
105 std::numeric_limits<uInt>::max());
106 return CompressionAlgorithm::UNCOMPRESSED;
107 }
108
109
1/1
✓ Branch 4 taken 5 times.
5 ctx.zlib_stream.next_in = in_buffer.getData();
110
1/1
✓ Branch 4 taken 5 times.
5 ctx.zlib_stream.avail_in = static_cast<uInt>(in_buffer.getSize());
111
112
1/1
✓ Branch 5 taken 5 times.
5 ctx.zlib_stream.next_out = ctx.compression_buffer.getData();
113
1/1
✓ Branch 5 taken 5 times.
5 ctx.zlib_stream.avail_out = static_cast<uInt>(ctx.compression_buffer.getSize());
114
115
1/1
✓ Branch 3 taken 5 times.
5 zlib_ok = deflate(&ctx.zlib_stream, Z_FINISH);
116
117
6/7
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
✓ Branch 9 taken 3 times.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✓ Branch 14 taken 2 times.
5 if (zlib_ok == Z_STREAM_END && ctx.zlib_stream.total_out <= ctx.compression_buffer.getSize()) {
118
1/1
✓ Branch 7 taken 3 times.
3 ctx.compression_buffer.setSize(ctx.zlib_stream.total_out);
119
120
3/3
✓ Branch 11 taken 3 times.
✓ Branch 17 taken 3 times.
✓ Branch 20 taken 3 times.
3 ctx.comp.log_DIAGNOSTIC_ZLibCompression(in_buffer.getSize(), ctx.compression_buffer.getSize());
121
122
2/2
✓ Branch 12 taken 3 times.
✓ Branch 17 taken 3 times.
3 ctx.comp.log_DIAGNOSTIC_ZLibMemoryUsage(ctx.bump_allocator, ctx.zlib_alloc_buffer.getSize());
123
124
1/1
✓ Branch 1 taken 3 times.
3 return CompressionAlgorithm::ZLIB_DEFLATE;
125 } else {
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (zlib_ok != Z_OK) {
127 ctx.comp.log_WARNING_LO_ZLibDeflateError(
128 zlib_ok, ctx.zlib_stream.msg == nullptr ? Fw::String("") : Fw::String(ctx.zlib_stream.msg));
129 }
130
131
3/3
✓ Branch 11 taken 2 times.
✓ Branch 17 taken 2 times.
✓ Branch 20 taken 2 times.
2 ctx.comp.log_DIAGNOSTIC_ZLibNoCompression(in_buffer.getSize(), ctx.compression_buffer.getSize());
132
1/1
✓ Branch 1 taken 2 times.
2 return CompressionAlgorithm::UNCOMPRESSED;
133 }
134
135 // Note: Skipping call to deflateEnd. Per the documentation this
136 // call frees the dynamically allocated data structures, but this
137 // is not necessary with the bump allocator.
138 // The call to deflateEnd does not flush any additional output data
139 6 }
140
141 30 voidpf DpZLibCompressor::zlib_alloc_fn(voidpf opaque, uInt items, uInt size) {
142 30 FW_ASSERT(opaque != nullptr);
143 30 ZLibCtx* ctx = reinterpret_cast<ZLibCtx*>(opaque);
144
145 30 FW_ASSERT(ctx->bump_allocator <= ctx->zlib_alloc_buffer.getSize(),
146 static_cast<FwAssertArgType>(ctx->bump_allocator),
147 static_cast<FwAssertArgType>(ctx->zlib_alloc_buffer.getSize()));
148 30 const FwSizeType free_space = ctx->zlib_alloc_buffer.getSize() - ctx->bump_allocator;
149
150 30 const FwSizeType alloc_size = static_cast<FwSizeType>(items) * static_cast<FwSizeType>(size);
151
152
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
30 if (free_space < alloc_size) {
153 1 return Z_NULL;
154 }
155
156 29 U8* alloc_ptr = ctx->zlib_alloc_buffer.getData() + ctx->bump_allocator;
157 29 ctx->bump_allocator += alloc_size;
158
159 29 return alloc_ptr;
160 }
161
162 4 void DpZLibCompressor::zlib_free_fn(voidpf opaque, voidpf address) {
163 // No work. Cannot free from bump allocator
164 4 }
165
166 } // namespace Svc
167