66 lines
1.5 KiB
C
66 lines
1.5 KiB
C
#include <stddef.h>
|
|
|
|
#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;
|
|
}
|