Skip to content

Commit

Permalink
Merge pull request #24 from benpicco/nanocbor_get_uint8_16
Browse files Browse the repository at this point in the history
decoder: add functions to decode 8 & 16 bit integers
  • Loading branch information
bergzand authored Oct 5, 2020
2 parents bcce9f0 + 7f81c35 commit 16e5a83
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 4 deletions.
66 changes: 66 additions & 0 deletions include/nanocbor/nanocbor.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,41 @@ int nanocbor_get_type(const nanocbor_value_t *value);
*/
bool nanocbor_at_end(const nanocbor_value_t *it);

/**
* @brief Retrieve a positive integer as uint8_t from the stream
*
* If the value at `cvalue` is greater than 8 bit (> 255), error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
* @param[out] value returned positive integer
*
* @return number of bytes read
* @return negative on error
*/
int nanocbor_get_uint8(nanocbor_value_t *cvalue, uint8_t *value);

/**
* @brief Retrieve a positive integer as uint16_t from the stream
*
* If the value at `cvalue` is greater than 16 bit (> 65535), error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
* @param[out] value returned positive integer
*
* @return number of bytes read
* @return negative on error
*/
int nanocbor_get_uint16(nanocbor_value_t *cvalue, uint16_t *value);

/**
* @brief Retrieve a positive integer as uint32_t from the stream
*
* If the value at `cvalue` is greater than 32 bit, error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
Expand All @@ -210,9 +242,43 @@ bool nanocbor_at_end(const nanocbor_value_t *it);
*/
int nanocbor_get_uint32(nanocbor_value_t *cvalue, uint32_t *value);

/**
* @brief Retrieve a signed integer as int8_t from the stream
*
* If the value at `cvalue` is greater than 8 bit (< -128 or > 127),
* error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
* @param[out] value returned signed integer
*
* @return number of bytes read
* @return negative on error
*/
int nanocbor_get_int8(nanocbor_value_t *cvalue, int8_t *value);

/**
* @brief Retrieve a signed integer as int16_t from the stream
*
* If the value at `cvalue` is greater than 16 bit (< -32768 or > 32767),
* error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
* @param[out] value returned signed integer
*
* @return number of bytes read
* @return negative on error
*/
int nanocbor_get_int16(nanocbor_value_t *cvalue, int16_t *value);

/**
* @brief Retrieve a signed integer as int32_t from the stream
*
* If the value at `cvalue` is greater than 32 bit, error is returned.
*
* The resulting @p value is undefined if the result is an error condition
*
* @param[in] cvalue CBOR value to decode from
Expand Down
65 changes: 61 additions & 4 deletions src/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,28 @@ static int _get_uint64(nanocbor_value_t *cvalue, uint32_t *value, uint8_t max, i
return (int)(1 + bytes);
}

static int _get_and_advance_uint8(nanocbor_value_t *cvalue, uint8_t *value,
int type)
{
uint32_t tmp = 0;
int res = _get_uint64(cvalue, &tmp, NANOCBOR_SIZE_BYTE,
type);
*value = tmp;

return _advance_if(cvalue, res);
}

static int _get_and_advance_uint16(nanocbor_value_t *cvalue, uint16_t *value,
int type)
{
uint32_t tmp = 0;
int res = _get_uint64(cvalue, &tmp, NANOCBOR_SIZE_SHORT,
type);
*value = tmp;

return _advance_if(cvalue, res);
}

static int _get_and_advance_uint32(nanocbor_value_t *cvalue, uint32_t *value,
int type)
{
Expand All @@ -141,12 +163,23 @@ static int _get_and_advance_uint32(nanocbor_value_t *cvalue, uint32_t *value,
return _advance_if(cvalue, res);
}

int nanocbor_get_uint8(nanocbor_value_t *cvalue, uint8_t *value)
{
return _get_and_advance_uint8(cvalue, value, NANOCBOR_TYPE_UINT);
}

int nanocbor_get_uint16(nanocbor_value_t *cvalue, uint16_t *value)
{
return _get_and_advance_uint16(cvalue, value, NANOCBOR_TYPE_UINT);
}

int nanocbor_get_uint32(nanocbor_value_t *cvalue, uint32_t *value)
{
return _get_and_advance_uint32(cvalue, value, NANOCBOR_TYPE_UINT);
}

int nanocbor_get_int32(nanocbor_value_t *cvalue, int32_t *value)
static int _get_and_advance_int32(nanocbor_value_t *cvalue, int32_t *value, uint8_t max,
uint32_t bound)
{
int type = nanocbor_get_type(cvalue);
if (type < 0) {
Expand All @@ -155,9 +188,8 @@ int nanocbor_get_int32(nanocbor_value_t *cvalue, int32_t *value)
int res = NANOCBOR_ERR_INVALID_TYPE;
if (type == NANOCBOR_TYPE_NINT || type == NANOCBOR_TYPE_UINT) {
uint32_t intermediate = 0;
res = _get_uint64(cvalue, &intermediate,
NANOCBOR_SIZE_WORD, type);
if (intermediate > INT32_MAX) {
res = _get_uint64(cvalue, &intermediate, max, type);
if (intermediate > bound) {
res = NANOCBOR_ERR_OVERFLOW;
}
if (type == NANOCBOR_TYPE_NINT) {
Expand All @@ -170,6 +202,31 @@ int nanocbor_get_int32(nanocbor_value_t *cvalue, int32_t *value)
return _advance_if(cvalue, res);
}

int nanocbor_get_int8(nanocbor_value_t *cvalue, int8_t *value)
{
int32_t tmp = 0;
int res = _get_and_advance_int32(cvalue, &tmp, NANOCBOR_SIZE_BYTE, INT8_MAX);

*value = tmp;

return res;
}

int nanocbor_get_int16(nanocbor_value_t *cvalue, int16_t *value)
{
int32_t tmp = 0;
int res = _get_and_advance_int32(cvalue, &tmp, NANOCBOR_SIZE_SHORT, INT16_MAX);

*value = tmp;

return res;
}

int nanocbor_get_int32(nanocbor_value_t *cvalue, int32_t *value)
{
return _get_and_advance_int32(cvalue, value, NANOCBOR_SIZE_WORD, INT32_MAX);
}

int nanocbor_get_tag(nanocbor_value_t *cvalue, uint32_t *tag)
{
return _get_and_advance_uint32(cvalue, tag, NANOCBOR_TYPE_TAG);
Expand Down

0 comments on commit 16e5a83

Please sign in to comment.