mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
string.c: add mrb_utf8_to_buf() to consolidate UTF-8 encoding
Extract duplicated UTF-8 codepoint-to-bytes encoding into a shared
function in src/string.c. Update all gems to use it:
- mruby-sprintf: %c specifier
- mruby-io: putc
- mruby-string-ext: Integer#chr
- mruby-pack: pack("U")
- mruby-compiler: Unicode escapes in parser
Also use existing mrb_utf8len() in io.c for character length detection.
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -316,6 +316,39 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str)
|
||||
#define MASK01 0x01010101ul
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encode a Unicode codepoint to UTF-8 bytes.
|
||||
* buf must have at least 4 bytes of space.
|
||||
* Returns the number of bytes written (1-4), or 0 for invalid codepoint.
|
||||
*/
|
||||
mrb_int
|
||||
mrb_utf8_to_buf(char *buf, uint32_t cp)
|
||||
{
|
||||
if (cp < 0x80) {
|
||||
buf[0] = (char)cp;
|
||||
return 1;
|
||||
}
|
||||
else if (cp < 0x800) {
|
||||
buf[0] = (char)(0xC0 | (cp >> 6));
|
||||
buf[1] = (char)(0x80 | (cp & 0x3F));
|
||||
return 2;
|
||||
}
|
||||
else if (cp < 0x10000) {
|
||||
buf[0] = (char)(0xE0 | (cp >> 12));
|
||||
buf[1] = (char)(0x80 | ((cp >> 6) & 0x3F));
|
||||
buf[2] = (char)(0x80 | (cp & 0x3F));
|
||||
return 3;
|
||||
}
|
||||
else if (cp <= 0x10FFFF) {
|
||||
buf[0] = (char)(0xF0 | (cp >> 18));
|
||||
buf[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
|
||||
buf[2] = (char)(0x80 | ((cp >> 6) & 0x3F));
|
||||
buf[3] = (char)(0x80 | (cp & 0x3F));
|
||||
return 4;
|
||||
}
|
||||
return 0; /* invalid codepoint */
|
||||
}
|
||||
|
||||
#ifdef MRB_UTF8_STRING
|
||||
|
||||
#define NOASCII(c) ((c) & 0x80)
|
||||
|
||||
Reference in New Issue
Block a user