Validating UTF8 Strings via Lookup Tables
darkcephas.blogspot.com
darkcephas.blogspot.com
ٳٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٳٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٳٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٳٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٳٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰٰ
ه꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲҉꙰꙱҈̿꙲
#oͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦͦ
╰̩̩̩̩̩̻̍̍̍̍̍̊●̩̩̩̩̩̩̩̻̍̍̍̍̍̍̍̊ᴗ̩̩̩̩̩̩̩̩̩̩̪̺̍̍̍̍̍̍̍̍̍̍̆̑●̩̩̩̩̩̩̩̻̍̍̍̍̍̍̍̊╯̩̩̩̩̩̩̻̍̍̍̍̍̊
فͤ҈ͨͥ҉҉ͦ҈҉ͨ҈ͩ҉ͪ҈ͣͯͫ҉ͥͬͨ҈ͭ҉ͮ҈ͯ҉ͨ҈ͭͭͬ҉ͧͥ҈ͣ҉ͨ҉҉҈ͧͥ҉ͯ҈ͮͥ҉ͭ҈ͤ҈ͦ҈ͥ҉ͧ҈ͩͯ҉ͭ҈ͨ҉ͨͥ҉҉ͣ҉ͣͪ҉ͧ҈ͭ҉ͩ҈ͤ҉ͮ҈ͯͥ҈ͬ҈ͭ҈ͦ҈ͨͣ҉ͥ҈ͯ҉҉ͣͧ҈ͫ҉ͭ҈ͥͯͯ҉ͦ҈ͥ҉ͧ҉҈ͩ҉ͭ҈ͣͨ҉ͣͥ҈ͪ҉ͧ҈ͭ
Ick. That violates the aliasing rules in many cases and is therefore UB. And it’s wrong on big-endian systems.
Just do src[i] | ((size_t)(src[i+1]) << 8).
#include <stddef.h>
#include <stdint.h>
uint16_t read_2byte_le(const uint8_t *src)
{
return (uint16_t)(src[0] |
((uint16_t)(src[1]) << 8));
}
This generates the correct code with gcc and with clang. Sadly, clang is a bit fragile in this regard: https://bugs.llvm.org/show_bug.cgi?id=39438lea r10,[r10+8] shl rcx,8 or rcx,rax shl r9,8 movzx eax,byte ptr [r10-8] shl rax,8 or rdx,rax shl r8,8
etc
Similarly, I've yet to see a gamedev codebase that doesn't use MSVC as the primary compiler for Windows builds.
[1] Technically you can consume C++/CX APIs as straight up COM in vanilla C++ but that's really not the intention, nor necessarily supported for some things.
Focus on proving it's well-defined, or rewrite it until it is.
[1]: https://lemire.me/blog/2012/05/31/data-alignment-for-speed-m...
It sounds like what you were doing is marking a struct as "packed", and accessing the fields directly (instead of through a pointer to the field). That should be fine.
Constexpr has tons of promise, but the compiler support just isn't there yet - we still have to think really hard about it and look at the generated code to verify.
What do you mean by "mixing 11 and 14"?
Some people have used trampoline techniques to get around the depth limits. CRTP just did this for compile time regex.
This is interesting. Considering validating utf8 is something a computer does a lot these days, would it be practical to provide this lookup table and associated instruction hardwired in a processor ? I'm thinkink about the ISA extensions possibilities provided by RiscV for example.
I may be way off, this table is 64kB in size right ? I have no idea about how much silicon real estate that represents relatively speaking...
"\xff", // invalid byte
"\x82", // unexpected continuation byte
"\xc0", // not enough continuation bytes
"\xed\xa0", // not enough continuation bytes
"\xc0\x80", // "modified UTF-8's not really NUL (over-long encoding)
"\xf0\x82\x82\x8c", // over-long euro symbol
"\xed\xa0\x80", // invalid surrogate character U+d800I don't think he missed anything.