cobs2/lib.rs
1//! Encoding and decoding of COBS (Consistent Overhead Byte Stuffing)
2//!
3//! ## Intro
4//!
5//! This crate provides functions for encoding and decoding of COBS, and a minor variant of COBS
6//! known as COBS/R.
7//!
8//! ### What Is COBS?
9//!
10//! COBS is a method of encoding a packet of bytes into a form that contains no bytes with value
11//! zero (`0x00`). The input packet of bytes can contain bytes in the full range of `0x00` to
12//! `0xFF`. The COBS encoded packet is guaranteed to generate packets with bytes only in the range
13//! `0x01` to `0xFF`. Thus, in a communication protocol, packet boundaries can be reliably
14//! delimited with `0x00` bytes.
15//!
16//! The COBS encoding does have to increase the packet size to achieve this encoding. However,
17//! compared to other byte-stuffing methods, the packet size increase is reasonable and
18//! predictable. COBS always adds 1 byte to the message length. Additionally, for longer packets
19//! of length *n*, it *may* add n/254 (rounded down) additional bytes to the encoded packet size.
20//!
21//! For example, compare to the PPP protocol, which uses `0x7E` bytes to delimit PPP packets. The
22//! PPP protocol uses an "escape" style of byte stuffing, replacing all occurences of `0x7E` bytes
23//! in the packet with `0x7D 0x5E`. But that byte-stuffing method can potentially double the size
24//! of the packet in the worst case. COBS uses a different method for byte-stuffing, which has a
25//! much more reasonable worst-case overhead.
26//!
27//! For more details about COBS, see the references.
28//!
29//! ### What is COBS/R?
30//!
31//! I have included a variant on COBS, COBS/R, which slightly modifies COBS to often avoid the +1
32//! byte overhead of COBS. So in many cases, especially for smaller packets, the size of a COBS/R
33//! encoded packet is the same size as the original packet. See the [cobsr] module for more details
34//! about COBS/R.
35//!
36//! ### References
37//!
38//! Consistent Overhead Byte Stuffing
39//! Stuart Cheshire and Mary Baker
40//! IEEE/ACM Transations on Networking, Vol. 7, No. 2, April 1999
41//!
42//! Consistent Overhead Byte Stuffing (for IEEE)
43//! <http://www.stuartcheshire.org/papers/COBSforToN.pdf>
44//!
45//! PPP Consistent Overhead Byte Stuffing (COBS)
46//! PPP Working Group Internet Draft
47//! James Carlson, IronBridge Networks
48//! Stuart Cheshire and Mary Baker, Stanford University
49//! November 1997
50//!
51//! PPP Consistent Overhead Byte Stuffing (COBS)
52//! <http://tools.ietf.org/html/draft-ietf-pppext-cobs-00>
53//!
54//! ## License
55//!
56//! The code is released under the MIT license. See LICENSE.txt for details.
57
58#![allow(dead_code)]
59#![forbid(unsafe_code)]
60#![cfg_attr(not(feature = "std"), no_std)]
61
62use core::fmt;
63
64#[cfg(feature = "alloc")]
65extern crate alloc;
66
67/// Errors that can occur during COBS encoding/decoding.
68#[derive(Debug, PartialEq, Eq, Clone)]
69pub enum Error {
70 /// For functions that generate output in an array, such as [cobs::encode_array()], it
71 /// indicates that the output array size is too small for the output data.
72 OutputBufferTooSmall,
73 /// For decoding functions, it indicates that an unexpected zero-byte was found in the
74 /// input data. Valid COBS-encoded data should not contain any zero-bytes.
75 /// This error is only applicable for decoding.
76 ZeroInEncodedData,
77 /// For COBS decoding functions, it indicates that the COBS-encoded data was not valid;
78 /// the data appears to be truncated. Or it may be invalid due to data corruption.
79 /// More data was expected given the last length-byte value in the data.
80 /// This error is only applicable for COBS decoding (not COBS/R).
81 TruncatedEncodedData,
82}
83
84/// Apply trait [std::error::Error].
85#[cfg(feature = "std")]
86impl std::error::Error for Error {}
87
88/// Implement trait [fmt::Display].
89impl fmt::Display for Error {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 match *self {
92 Error::OutputBufferTooSmall => {
93 write!(f, "Output buffer is too small")
94 }
95 Error::ZeroInEncodedData => {
96 write!(f, "Zero found in encoded input data")
97 }
98 Error::TruncatedEncodedData => {
99 write!(f, "Unexpected end of encoded input data")
100 }
101 }
102 }
103}
104
105/// The return type for encoding and decoding functions, based on [core::result::Result],
106/// in which the error type is [Error].
107pub type Result<T> = core::result::Result<T, crate::Error>;
108
109pub mod cobs;
110
111pub mod cobsr;