Minimal C++ SLIP encoder operating on buffers

The following encoder can be used to encode frames into a byte stream. It operates on complete buffers (i.e. this is not a streaming encoder) but is fast and easy to use.

/*
 * Author: Uli Köhler - techoverflow.net
 * License: CC0 1.0 Universal
 *
 * Description:
 * This is a C++ implementation of a buffer-based SLIP encoder.
 * It can be used to encode frames unambiguously into a stream of bytes.
 * The encoder does not use any memory allocation, but instead requires
 * the caller to provide a buffer for the encoded data - hence being
 * ideally suited for use in embedded systems
 */
#pragma once
#include <cstdint>
#include <cstddef>

#define SLIP_END             ((uint8_t)0300)   // SLIP end of packet character
#define SLIP_ESC             ((uint8_t)0333)   // SLIP escape character
#define SLIP_ESCEND         ((uint8_t)0334)    // Escaped END data byte
#define SLIP_ESCESC         ((uint8_t)0335)    // Escaped ESC data byte

// Return value of slip_encode_packet if the output buffer is not large enough
#define SLIP_ENCODE_ERROR SIZE_MAX // Maximum value of size_t

/**
 * Determine the packet length when sending the given buffer [p] using SLIP.
 * This DOES NOT ENCODE ANYTHING, it just determines the length
 * which an encoded version of the data would have
 * @return The number of bytes a SLIP encoded version of [in] would consume
 */
size_t slip_packet_length(const uint8_t* in, size_t inlen);

/**
 * Encode given input data using SLIP, saving it into the given output buffer.
 * WARNING! The output buffer MUST have a length of at least the return value of
 *    slip_packet_len(in, inlen)
 * In case the output buffer is not large enough, this function will return SLIP_ENCODE_ERROR and
 * the output buffer will be left in an undefined space.
 * Take special care that the input data does not change between the calls to
 * slip_packet_len() and slip_encode_packet()
 * @return The number of bytes in [out], or SLIP_ENCODE_ERROR
 */
size_t slip_encode_packet(const uint8_t* in, size_t inlen, uint8_t* out, size_t outlen);
/*
 * Author: Uli Köhler - techoverflow.net
 * License: CC0 1.0 Universal
 *
 * Description:
 * This is a C++ implementation of a buffer-based SLIP encoder.
 * It can be used to encode frames unambiguously into a stream of bytes.
 * The encoder does not use any memory allocation, but instead requires
 * the caller to provide a buffer for the encoded data - hence being
 * ideally suited for use in embedded systems
 */
#include "SLIPEncoder.hpp"

size_t slip_packet_length(const uint8_t* in, size_t inlen) {
    // This variable contains the length of the data
    size_t outlen = 0;
    const uint8_t* inend = in + inlen; // First character AFTER the
    for (; in < inend ; in++) {
        switch (*in) {
        case SLIP_END: // Need to escape END character to avoid RX seeing end of frame
            // Same as "case SLIP_ESC" so just continue.
        case SLIP_ESC: // Need to escape ESC character, we'll send
            outlen += 2; // Will send ESC + ESCESC
            break;
        default: // Any other character => will just copy
            outlen++; // Will only send the given character
        }
    }
    // + 1: SLIP END bytes
    return outlen + 1;
}

size_t slip_encode_packet(const uint8_t* in, size_t inlen, uint8_t* out, size_t outlen) {
    // This variable contains the length of the data
    uint8_t* out_start = out; // We will increment [out], hence copy the original value.

    // Output buffer must be AT LEAST as long as input data (sanity check)
    if(outlen < inlen) {
        return SLIP_ENCODE_ERROR;
    }

    uint8_t* outend = out + outlen; // First character AFTER the
    const uint8_t* inend = in + inlen; // First character AFTER the
    for (; in < inend ; in++) {
        switch (*in) {
        case SLIP_END: // Need to escape END character to avoid RX seeing end of frame
            // Check out of bounds memory acces
            if(out + 2 >= outend) {
                return SLIP_ENCODE_ERROR;
            }
            // Copy escaped END character
            *out++ = SLIP_ESC;
            *out++ = SLIP_ESCEND;
            break;
        case SLIP_ESC: // Need to escape ESC character, we'll send
            // Check out of bounds memory access
            if(out + 2 >= outend) {
                return SLIP_ENCODE_ERROR;
            }
            // Copy escaped END character
            *out++ = SLIP_ESC;
            *out++ = SLIP_ESCESC;
            break;
        default: // Any other character => just copy the character
            if(out + 1 >= outend) {
                return SLIP_ENCODE_ERROR;
            }
            *out++ = *in;
        }
    }
    // Check out of bounds access for END byte
    if(out + 1 > outend) { // NOTE: > instead of >= since there is only ONE character to be written
        return SLIP_ENCODE_ERROR;
    }
    // Insert END byte
    *out++ = SLIP_END;
    // Return number of bytes
    return (out - out_start);
}