mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-26 15:03:53 +01:00
sys/bcd: add bcd_buf_to_u32() and bcd_buf_from_str()
This commit is contained in:
parent
f045ccc34a
commit
2c43918792
@ -56,3 +56,61 @@ int bcd_buf_from_u32(uint32_t val, void *dst, size_t len)
|
||||
|
||||
return (uintptr_t)tgt - (uintptr_t)dst;
|
||||
}
|
||||
|
||||
/* Use the same code for 32 bit and 64 bit sum */
|
||||
#define _BCD_CONVERT(sum, len) \
|
||||
for (int i = len * 2 - 1; i >= 0; --i) { \
|
||||
uint8_t digit = i & 1 \
|
||||
? bcd[i >> 1] >> 4 \
|
||||
: bcd[i >> 1] & 0xF; \
|
||||
sum = sum * 10 + digit; \
|
||||
}
|
||||
|
||||
uint32_t bcd_buf_to_u32(const void *src, size_t len)
|
||||
{
|
||||
const uint8_t *bcd = src;
|
||||
uint32_t sum = 0;
|
||||
|
||||
_BCD_CONVERT(sum, len);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint64_t bcd_buf_to_u64(const void *src, size_t len)
|
||||
{
|
||||
const uint8_t *bcd = src;
|
||||
uint64_t sum = 0;
|
||||
|
||||
_BCD_CONVERT(sum, len);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static bool _is_digit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
int bcd_buf_from_str(const char *str, size_t len, void *dst, size_t dst_len)
|
||||
{
|
||||
uint8_t *bcd = dst;
|
||||
memset(dst, 0, dst_len);
|
||||
dst_len *= 2;
|
||||
|
||||
uint8_t i = 0;
|
||||
for (int j = len; j >= 0; --j) {
|
||||
if (i == dst_len) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
if (!_is_digit(str[j])) {
|
||||
continue;
|
||||
}
|
||||
uint8_t d = str[j] & 0xF;
|
||||
bcd[i >> 1] |= i & 1
|
||||
? d << 4
|
||||
: d;
|
||||
++i;
|
||||
}
|
||||
|
||||
return (i & 1) + (i >> 1);
|
||||
}
|
||||
|
||||
@ -16,10 +16,12 @@
|
||||
* @brief BCD definitions
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*/
|
||||
#ifndef BCD_H
|
||||
#define BCD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -64,11 +66,48 @@ static inline uint8_t bcd_to_byte(uint8_t bcd)
|
||||
* @param[in] len Size of the destination buffer
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @return -ENOBUFS if @p dst is not large enough
|
||||
* @retval -ENOBUFS if @p dst is not large enough
|
||||
* In that case the state of @p dst is undefined.
|
||||
*/
|
||||
int bcd_buf_from_u32(uint32_t val, void *dst, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Convert a BCD buffer into it's binary representation
|
||||
* (This will reverse @ref bcd_buf_from_u32)
|
||||
*
|
||||
* @param[in] src The BCD buffer to convert
|
||||
* @param[in] len Bytes in @p src
|
||||
*
|
||||
* @returns decimal representation of @p src
|
||||
*/
|
||||
uint32_t bcd_buf_to_u32(const void *src, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Convert a BCD buffer into it's binary representation
|
||||
*
|
||||
* @param[in] src The BCD buffer to convert
|
||||
* @param[in] len Bytes in @p src
|
||||
*
|
||||
* @returns decimal representation of @p src
|
||||
*/
|
||||
uint64_t bcd_buf_to_u64(const void *src, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Convert a string into a BCD buffer
|
||||
* Digits may be separated by any character.
|
||||
*
|
||||
* @param[in] str Input string
|
||||
* @param[in] str_len Length of the input string
|
||||
* @param[out] dst Destination buffer
|
||||
* @param[in] dst_len Size of the destination buffer
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @retval -ENOBUFS if @p dst is not large enough
|
||||
* In that case the state of @p dst is undefined.
|
||||
*/
|
||||
int bcd_buf_from_str(const char *str, size_t str_len,
|
||||
void *dst, size_t dst_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user