sys/fmt: add hex/bytes sequence converters#8343
Conversation
sys/fmt/fmt.c
Outdated
| size_t fmt_bytes_hex(char *out, const uint8_t *ptr, size_t n) | ||
| { | ||
| size_t i = 0; | ||
| while (i < n) { |
There was a problem hiding this comment.
- all functions in fmt just return the number of bytes that would have written, should
outbeNULL - while your code might be more readable to some, better keep the style of the rest of the file.
Please replace the while loop with:
if (out) {
while (n--) {
out += fmt_byte_hex(out, *ptr++);
}
}
(untested, but should be equivalent)
|
Would you mind splitting this PR and move the hex to byte converter in another? |
|
See aabadie#5. It saves 16b on ARM. Not sure if it is much of an improvement. ;) What do you think? |
It looks good and smaller. |
54296bf to
d4364ae
Compare
|
@kaspar030, I integrated your PR and extended the unit tests (including converting hex >= A). |
| bytes = fmt_bytes_hex(out, val, 1); | ||
| out[bytes] = '\0'; | ||
| TEST_ASSERT_EQUAL_INT(2, bytes); | ||
| TEST_ASSERT_EQUAL_STRING("AA", (char *) out); |
There was a problem hiding this comment.
Can you please at a n == 0 test also?
| hex2[2] = '\0'; | ||
| val1[0] = 0; | ||
| fmt_hex_bytes(val1, hex2); | ||
| TEST_ASSERT_EQUAL_INT(0xAB, val1[0]); |
There was a problem hiding this comment.
Here it would also be nice to test what happens if you hand over an empty string ;-).
There was a problem hiding this comment.
And with strings "strlen(str) % 2 != 0" ;-)
d4364ae to
f0d4a8f
Compare
sys/include/fmt.h
Outdated
| /** | ||
| * @brief Converts a sequence of hex bytes to an array of bytes | ||
| * | ||
| * The sequence of hex characters must have an odd length: |
There was a problem hiding this comment.
The tests (and your code) suggest that they have to have an even length. Also it is undocumented what happens if you provide a string of the wrong length.
There was a problem hiding this comment.
The tests (and your code) suggest that they have to have an even length
Indeed, I always do this mistake...
| TEST_ASSERT_EQUAL_INT(3, bytes); | ||
| TEST_ASSERT_EQUAL_INT(1, val3[0]); | ||
| TEST_ASSERT_EQUAL_INT(2, val3[1]); | ||
| TEST_ASSERT_EQUAL_INT(0xAF, val3[2]); |
There was a problem hiding this comment.
What happens if a character in the string is not in [0-9a-fA-F]?
There was a problem hiding this comment.
it doesn't work. It's possible to update but I want to keep this simple and trust the user. I added a doxygen comment for this.
sys/fmt/fmt.c
Outdated
| if (out) { | ||
| while (n--) { | ||
| out += fmt_byte_hex(out, *ptr++); | ||
| len += 2; |
There was a problem hiding this comment.
This way len is broken if there's no out.
This should fix it: https://gist.github.com/06d9b04ed210aed79d42bd4bba885298
There was a problem hiding this comment.
Maybe add a unittest for out==NULL but n > 0.
|
@aabadie lot's of work for seemlingy simple functions, eh? ;) Thanks for doing it! |
I knew that would be the case but that's the game ;) |
sys/include/fmt.h
Outdated
| * | ||
| * The sequence of hex characters must have an even length: | ||
| * 2 hex character => 1 byte. If the sequence of hex has an odd length, this | ||
| * function returns 0 and a NULL out. |
There was a problem hiding this comment.
Maybe add the returns 0 to the documentation of @return as well.
sys/include/fmt.h
Outdated
| * | ||
| * The sequence of hex characters must have an even length: | ||
| * 2 hex character => 1 byte. If the sequence of hex has an odd length, this | ||
| * function returns 0 and a NULL out. |
There was a problem hiding this comment.
a NULL out.:
- use
@p outto reference a parameter. outis a pointer, not a pointer to a pointer, so returningNULLis not possible.
sys/include/fmt.h
Outdated
| * function returns 0 and a NULL out. | ||
| * | ||
| * The hex characters sequence must contain valid hexadecimal characters | ||
| * otherwise this function returns an invalid byte array. |
There was a problem hiding this comment.
What is "an invalid byte array" in this case? Maybe a better wording would be "[…] otherwise the result in out will be undefined."
| TEST_ASSERT_EQUAL_INT(1, bytes); | ||
| TEST_ASSERT_EQUAL_INT(0xEF, val1[0]); | ||
|
|
||
| char hex4[6] = "0102aF"; |
There was a problem hiding this comment.
More hex4[7] ? Or hex4[] ?
sys/include/fmt.h
Outdated
| * | ||
| * @param[out] out Pointer to converted bytes, or NULL | ||
| * @param[in] hex Pointer to input buffer | ||
| * @returns strlen(hex) / 2 for a valid sequence of hex bytes |
There was a problem hiding this comment.
Personal preference, but I would prefer another specification of what a "valid sequence" is here (e.g. "strlen(hex) / 2 when length of @p hex was even"
- fmt_bytes_hex: converts an array of bytes to an array of hex bytes - fmt_hex_bytes: convert an array of hex bytes to an array of bytes
578c6af to
2a8e34d
Compare
|
squashed and rebased |
2a8e34d to
2b6e426
Compare
Contribution description
This PR adds 2 new formatting function to the
fmtmodule:fmt_bytes_hex: converts an array of bytes to an array of hex bytesfmt_hex_bytes: converts an array of hex bytes to an array of bytesSince I twice had the same comment in #8264 and #7505 about this (because I need these converters there), I think it's useful to provide them in a common place.
I also added simple unittests for the new functions.
Issues/PRs references
Related to #8264 and #7505