-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement a better buffer-reading abstraction #2914
Comments
Issue-Label Bot is automatically applying the label Links: app homepage, dashboard and code for this bot. |
Oh, and I guess all the approaches here have the main drawback of doing length checks on every read instead of one up-front length check and then a bunch of reads. I think that the latter is much more error-prone (e.g. due to people adding a read without updating the length check, or conditional reads or whatnot), and that the codesize/performance hit here is pretty minimal and likely to be worth it. |
I believe I had brought this up in the past but ended up stepping back as it seemed we had a solution in place but SmartThings has a generic buffer management C module we would potentially be willing to open source for use in CHIP if it's deemed of interest. In short, our implementation is very closely aligned with #1 above with a generic |
I think one important question there is whether we want a C++-style API for this (which would then need to be built on top of the module SmartThings has). If not, I think taking the module might make sense. If we do, it might be simpler to just write a thing per one of my options above: it would be less code because it could use the existing CHIP and nl facilities for endian-specific reading. |
Problem
We have a lot of places where we have a buffer (
uint8_t*
) and size and want to execute the following logic:Various places get this wrong (e.g. by forgetting step 4), and it's a bit error-prone to force consumers to think about this set of steps all the time.
Proposed Solution
Implement a class that encapsulates the "buffer and length" state and the corresponding logic.
PacketBuffer
sort of has similar logic already, in that you can update the start position, but not everything we are dealing with in this code is necessarily aPacketBuffer
.We wanted something like this in #2168 anyway.
There are three main approaches I've thought of so far here:
BufferReader
) exposes APIs that do all the above and call various*Endian::Read*
functions under the hood. So it might have a function calledRead16LE
orRead32BE
.LittleEndianReader
andBigEndianReader
classes. This avoids theLE
/BE
suffixing, at the cost of not allowing mixed-endianness reads from the same buffer. In practice, I don't expect this to be an issue: right now there is no big-endian reading going on in CHIP, much less mixed-endian reading.*Endian::Read*
functions to take instances of someBoundedBuffer
class and operate on them. These could either be in addition to the existing functions or replacing them. Some confusion possible here withBufBound
, but maybe we can figure out better naming.From the point of view of minimizing footguns, it seems like option 3 and "replacing" is the way to go. It has the drawback of forcing all reads through a fallible (if there is not enough buffer left) API.
From the point of view of having composable simple pieces, I think option 2 is probably the right one. We would then need to go through our existing
Read*
calls and replace them as it makes sense, and keep an eye on what option people use in new code.@andy31415 @rwalker-apple @mspang @bhaskar-apple @shana-apple @BroderickCarlin any preferences amongst the options here?
The text was updated successfully, but these errors were encountered: