Allow encoding into chunks#15
Conversation
The manually written generator is not preptty, but it allows writing from a single maximal message size frame into a UART (eg. by buffering in some reasonable buffer size of 16 bytes) without a double-sized buffer.
Rather than keeping running totals and always indexing into slices, the slices themselves are advanced, reducing the cognitive overhead of tracking indices in many places.
Rather than anticipating how much space is needed, this lets the slip encoder's general well-behavedness with empty buffers do its work. A state is reduced by observing that none of the headers need escaping anyway.
Rather than building a big state machine, this pulls out the common pattern of having some slice of data that progress is made on.
|
Thanks! This looks great! |
| /// Unlike many other write-style methods, this does *not* fill up the buffer to the last byte | ||
| /// except for the last block; this simplifies encoding escaped bytes. |
There was a problem hiding this comment.
But it does fill the buffer up the buffer to the last byte? Not if the buffer is very big but if the buffer is smaller than the data, it will always fill the buffer to the limit.
There was a problem hiding this comment.
If it's a large buffer, it fills it up to the last byte (and there's your existing test that covers this).
Repeated small buffers will eventually be reading up the whole message.
There was a problem hiding this comment.
There is a corner case where if there is a large fixed-size buffer, and the application only presents that buffer to slipmux picemeal, and that buffer is odd-sized, and then in a maximal message, there's only the End byte missing, and the application only has a single byte to hadn to the library, then the "panics if <2 byte buffer" triggers even though technically things would fit.
But that'd make the usage condition more complex to describe and to test, and I don't see why anyone would do that: Either it's a fixed buffer, then it can be passed to encode_chunk as a whole, or it's some kind of streaming interface, where you get fixed buffers every time. (Or it's a streaming interface that gives you as much buffer as is free, and then it just takes a jiffy longer for a 2-long buffer to get free so that the function can be called properly again).
Currently, if I have a 1200 byte CoAP buffer in a constrained device and want to send that to a UART (which is maybe buffered to a few bytes), I need to allocate a 2404-ish byte output buffer.
This PR adds a struct that can deal out pieces of data in chunks down to 2 bytes; it is a heavy refactoring of what used to be encode (which itself is now just driving that encoder through a single step).
It's a heavy PR in terms of LoC (+167-22 for a net +145, although 48 thereof is just tests), but I think it is useful for embedded applications. On the history, feel free to peruse if you feel like digging into history, but due to PR-internal refactoring, this is best reviewed as a single large diff.