dal-c library ← coverage

§ Coverage

src/sc_cobs.c

1/*2 * sc_cobs.c -- implementation. Blocks are tagged with the low-level3 * requirement they satisfy; see requirements/sc_cobs.md.4 *5 * Encode uses "lazy" block splitting: a full 254-byte block is only6 * closed with a 0xFF code when there is a following byte, so a payload of7 * exactly 254 non-zero bytes encodes to 255 bytes, not 256.8 */9#include "sc_cobs.h"1011#define COBS_FULL_BLOCK  0xFFu   /* code value meaning "254 data bytes, no trailing zero" */121320uint32_t sc_cobs_max_encoded(uint32_t payload_len)14{15    uint32_t result;161720    if (payload_len == 0u)condition outcomes covered 2/218    {193        result = 1u;                                     /* LLR-COBS-1 */20    }21    else22    {2317        result = payload_len + ((payload_len - 1u) / 254u) + 1u;24    }252620    return result;27}282918uint32_t sc_cobs_encode(const uint8_t *in, uint32_t in_len,30                        uint8_t *out, uint32_t out_cap)31{3218    uint32_t result = 0u;333434    if ((in == NULL) || (out == NULL) ||condition outcomes covered 6/63516        (sc_cobs_max_encoded(in_len) > out_cap))36    {373        result = 0u;                                     /* LLR-COBS-2 */38    }39    else40    {4115        uint32_t rd = 0u;4215        uint32_t wr = 1u;      /* out[0] reserved for the first code */4315        uint32_t code_at = 0u;4415        uint8_t  code = 1u;45461569        while (rd < in_len)                               /* LLR-COBS-3 */condition outcomes covered 2/247        {481554            if (code == COBS_FULL_BLOCK)                  /* LLR-COBS-6: close a full block */condition outcomes covered 2/249            {503                out[code_at] = code;513                code_at = wr;523                wr++;533                code = 1u;54            }55561554            if (in[rd] == 0u)condition outcomes covered 2/257            {5812                out[code_at] = code;                     /* LLR-COBS-4: close block on zero */5912                code_at = wr;6012                wr++;6112                code = 1u;62            }63            else64            {651542                out[wr] = in[rd];                        /* LLR-COBS-5: copy non-zero */661542                wr++;671542                code = (uint8_t)(code + 1u);68            }691554            rd++;70        }717215        out[code_at] = code;                             /* LLR-COBS-7: final code */7315        result = wr;74    }757618    return result;77}787914uint32_t sc_cobs_decode(const uint8_t *in, uint32_t in_len,80                        uint8_t *out, uint32_t out_cap)81{8214    uint32_t result = 0u;838414    if ((in == NULL) || (out == NULL))condition outcomes covered 4/485    {862        result = 0u;                                     /* LLR-COBS-8 */87    }88    else89    {9012        uint32_t rd = 0u;9112        uint32_t wr = 0u;9212        bool     ok = true;939434        while ((rd < in_len) && ok)                       /* LLR-COBS-9 */condition outcomes covered 4/495        {9622            uint8_t code = in[rd];979822            rd++;9910022            if (code == 0u)condition outcomes covered 2/2101            {1021                ok = false;                              /* LLR-COBS-10: 0x00 is not a valid code */103            }104            else105            {10621                uint32_t span = (uint32_t)code - 1u;10710821                if ((span > (in_len - rd)) || (span > (out_cap - wr)))condition outcomes covered 4/4109                {1102                    ok = false;                          /* malformed / no room */111                }112                else113                {114                    uint32_t k;1151548                    for (k = 0u; k < span; k++)           /* LLR-COBS-11: copy block */condition outcomes covered 2/2116                    {1171529                        out[wr] = in[rd];1181529                        wr++;1191529                        rd++;120                    }12119                    if ((code != COBS_FULL_BLOCK) && (rd < in_len))condition outcomes covered 4/4122                    {1238                        if (wr >= out_cap)condition outcomes covered 2/2124                        {1251                            ok = false;126                        }127                        else128                        {1297                            out[wr] = 0u;                /* LLR-COBS-12: inter-block zero */1307                            wr++;131                        }132                    }133                }134            }135        }13613712        result = ok ? wr : 0u;                            /* LLR-COBS-13 */condition outcomes covered 2/2138    }13914014    return result;141}