#include #include "utf.h" #include "str.h" typedef struct Utf8Parser { String str; } Utf8Parser; bool Utf8ParserNextCodePoint(Utf8Parser *this, CodePoint *out_codepoint) { uitn8_t const flag_1_bytes = 0; uint8_t const mask_1_bytes = 1 << 7; uint8_t const flag_continuation = mask_1_bytes; uint8_t const mask_continuation = (1 << 7) | (1 << 6); uint8_t const flag_2_bytes = mask_continuation; uint8_t const mask_2_bytes = (1 << 7) | (1 << 6) | (1 << 5); uint8_t const flag_3_bytes = mask_2_bytes; uint8_t const mask_3_bytes = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4); uint8_t const flag_4_bytes = mask_3_bytes; uint8_t const mask_4_bytes = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3); if (this->str.size == 0) { *out_codepoint = 0; return false; } if ((this->str.buffer[0] & mask_1_bytes) == flag_1_bytes) { *out_codepoint = (CodePoint) str[0]; bool ok = StringSub(this->str, 1, -1, &this->str); assert(ok && "has to be ok since the size is not 0"); return ok; } else } // max must be less than or equal to the capacity of target. bool CodePointsFromUtf8String( uint8_t const *str, CodePoint *target, int max ) { for (size_t i = 0; str[i] != '\0' && max > 0;) { if ((str[i] & mask_1_bytes) == flag_1_bytes) { *target = (CodePoint) str[i]; target += 1; max -= 1; i += 1; } else if ((str[i] & mask_2_bytes) == flag_2_bytes) { } else if ((str[i] & mask_3_bytes) == flag_3_bytes) { } else if ((str[i] & mask_4_bytes) == flag_4_bytes) { } else { false; } } return true; }