4 ms·
Yep ":>" does parse as 114. ";;" parses as 121. "<>" as 134. "999" parses as 231. Lots of work to do and nowhere close to being a magically clever and correct s
by 1letterunixname 3y ago
Yep ":>" does parse as 114. ";;" parses as 121. "<>" as 134. "999" parses as 231. Lots of work to do and nowhere close to being a magically clever and correct solution.
Note: \0 is implicit and redundant in C string literals. There is a fudge factor in some string handling semantics and it sort-of works without it with some UB risks that are platform specific. (It worked on GCC-13 on Linux on AMD EPYC.)
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int parse_uint8_fastswar(const char *str, size_t len, uint8_t *num) {
union {
uint8_t as_str[4];
uint32_t as_int;
} digits;
memcpy(&digits.as_int, str, sizeof(digits));
digits.as_int ^= 0x30303030lu;
digits.as_int <<= (4 - (len & 0x3)) * 8;
uint32_t y = ((UINT64_C(0x640a0100) * digits.as_int)>>32)&0xff;
*num = (uint8_t)(y);
return (digits.as_int & 0xf0f0f0f0) == 0 && y < 256 && len != 0
&& len < 4;
}
int main(int argc, char **argv) {
uint8_t num;
if (argc != 2 || !parse_uint8_fastswar(argv[1], strlen(argv[1]), &num))
return 1;
printf("parsed as %d (%02Xh)\n", num, num);
return 0;
}
- vinkelhake 3y agoThe literal ":>\0" gives us a 4 byte char array with the last two bytes being 0. I did this since the algorithm always does a 4 byte read from the passed pointer.