#ifndef UTF8_H #define UTF8_H #include #include #include #include typedef struct { bool ignore_bom; bool bom_seen; uint8_t pend_buf[3]; int pend_pos; } utf8_dec_t; typedef struct { uint16_t prefix_surrogate; uint16_t suffix_surrogate; } utf16_range_splits_t; typedef struct { const unsigned char *next; const unsigned char *end; uint16_t trailing_surrogate; } utf16_iterator_t; utf8proc_ssize_t utf8_whatwg_decode( utf8_dec_t *dec, const uint8_t *src, size_t len, char *out, bool fatal, bool stream ); int utf16_index_to_byte_offset( const char *str, size_t byte_len, size_t utf16_idx, size_t *out_char_bytes ); size_t utf16_index_to_byte_offset_floor( const char *str, size_t byte_len, size_t utf16_idx ); utf16_range_splits_t utf16_range_to_byte_range( const char *str, size_t byte_len, size_t utf16_start, size_t utf16_end, size_t *byte_start, size_t *byte_end ); void utf8_thread_cleanup(void); size_t utf16_strlen(const char *str, size_t byte_len); size_t byte_offset_to_utf16(const char *str, size_t byte_off); size_t utf8_char_len_at(const char *str, size_t byte_len, size_t pos); char *utf8_json_quote(const char *str, size_t byte_len, size_t *out_len); char *latin1_to_utf8(const uint8_t *src, size_t len, size_t *out_len); bool utf16_next_code_unit(utf16_iterator_t *iterator, uint16_t *unit); bool utf8_validate_bytes(const char *str, size_t byte_len); bool wtf8_validate_bytes(const char *str, size_t byte_len); bool wtf8_is_well_formed(const char *str, size_t byte_len); uint8_t *utf8_to_latin1(const char *src, size_t len, size_t *out_len, bool *is_latin1); uint32_t utf16_code_unit_at(const char *str, size_t byte_len, size_t utf16_idx); uint32_t utf16_codepoint_at(const char *str, size_t byte_len, size_t utf16_idx); static inline int utf8_sequence_length(unsigned char first_byte) { if ((first_byte & 0x80) == 0) return 1; if ((first_byte & 0xE0) == 0xC0) return 2; if ((first_byte & 0xF0) == 0xE0) return 3; if ((first_byte & 0xF8) == 0xF0) return 4; return -1; } static inline int utf8_encode(uint32_t cp, char *out) { return (int) utf8proc_encode_char((utf8proc_int32_t)cp, (utf8proc_uint8_t *)out); } static inline utf16_iterator_t utf16_iterator(const char *str, size_t byte_len) { const unsigned char *bytes = (const unsigned char *)str; return (utf16_iterator_t){ .next = bytes, .end = bytes + byte_len }; } static inline utf8proc_ssize_t utf8_next( const utf8proc_uint8_t *p, utf8proc_ssize_t len, utf8proc_int32_t *cp ) { utf8proc_ssize_t n = utf8proc_iterate(p, len, cp); return n > 0 ? n : 1; } #endif