MemoryRange
Embedded applications regularly handle blocks of memory. Such memory may
either be typed (for example, consisting of a number of characters) or
un-typed. Traditionally, blocks of memory are handled by having a
pointer to its first element and a separate size. Since passing around
two separate but related parameters is cumbersome at best and
error-prone at its worst, we have improved on dealing with blocks of
memory by introducing the class template MemoryRange
. A MemoryRange
is an object which defines a block of memory with a start and an end,
and which has a number of functions that makes dealing with those blocks
as a whole easier. This approach reduces the potential for buffer
overflows, since while it is easy to shrink a block or to split it; it
is much more difficult to create a larger block, thereby overflowing the
original block of memory.
The MemoryRanges that are most often used are MemoryRange<uint8_t>
,
which has an alias ByteRange
, and its const counterpart
ConstByteRange
which aliases to MemoryRange<const uint8_t>
.
Everywhere where untyped memory is used ByteRange
or ConstByteRange
is used to define where the data resides in memory. For example: the SPI
interface SendData
method takes a ConstByteRange
parameter
specifying the data which should be sent.
A MemoryRange
does not include the storage it points to. Modifying a
MemoryRange
does not modify the storage. If storage is needed,
std::array is a good candidate. After creating a std::array and filling
it with data, a MemoryRange can be constructed from it by using
MakeRange
, after which the MemoryRange
can be used for passing
around the data.
MemoryRange Accessors
These are the most used accessors of MemoryRange
:
Method | Description |
---|---|
|
Returns a pointer to the first element of the data |
|
Returns a pointer to one position beyond the last element of the data |
|
Returns true if and only if |
|
Returns the number of elements pointed to: |
|
Remove num elements from the front of the range |
|
Remove num elements from the back of the range |
|
If |
|
If |
Helper Functions
In addition to the members of MemoryRange, a number of helper functions exist:
Function | Description |
---|---|
|
Convert the parameter(s) to a |
|
Returns range if its size is less than size, otherwise a new range consisting of the first size elements of range |
|
Returns range if its size is less than size, otherwise a new range consisting of the last size elements of range |
|
Returns an empty range if size is greater
than |
|
Returns an empty range if size is greater
than |
Example
This example function shows how to use the MemoryRange functions to cut up a block of data into smaller pieces:
void SendInBlocks(infra::ConstByteRange sendData, std::size_t blockSize)
{
while (!sendData.empty())
{
Send(infra::Head(sendData, blockSize));
sendData = infra::DiscardHead(sendData, blockSize);
}
}
void Example()
{
std::array<uint8_t, 256> data = { ... };
SendInBlocks(data, 16);
}