diff options
author | Mattias EngdegÄrd <mattiase@acm.org> | 2022-07-10 18:02:08 +0200 |
---|---|---|
committer | Mattias EngdegÄrd <mattiase@acm.org> | 2022-07-10 18:20:37 +0200 |
commit | cfda663282b788972c344e6733a8aa60a3e0f545 (patch) | |
tree | 988cf3745e6057b79180a659aa4c9071acf6a1da /src/fns.c | |
parent | 4bab499ed0d40d4e5ca68e5a17bcf5341125f734 (diff) | |
download | emacs-cfda663282b788972c344e6733a8aa60a3e0f545.tar.gz emacs-cfda663282b788972c344e6733a8aa60a3e0f545.tar.bz2 emacs-cfda663282b788972c344e6733a8aa60a3e0f545.zip |
Speed up string-to-unibyte
* src/character.h (str_to_unibyte):
* src/character.c (str_to_unibyte): Remove.
* src/fns.c (Fstring_to_unibyte): Ditch the call to str_to_unibyte and
the unnecessary heap allocation. Write new, faster code.
* test/src/fns-tests.el (fns--string-to-unibyte): New test.
Diffstat (limited to 'src/fns.c')
-rw-r--r-- | src/fns.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/fns.c b/src/fns.c index 49d76a0e7c7..61ed01eee4e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1413,19 +1413,24 @@ an error is signaled. */) (Lisp_Object string) { CHECK_STRING (string); + if (!STRING_MULTIBYTE (string)) + return string; - if (STRING_MULTIBYTE (string)) + ptrdiff_t chars = SCHARS (string); + Lisp_Object ret = make_uninit_string (chars); + unsigned char *src = SDATA (string); + unsigned char *dst = SDATA (ret); + for (ptrdiff_t i = 0; i < chars; i++) { - ptrdiff_t chars = SCHARS (string); - unsigned char *str = xmalloc (chars); - ptrdiff_t converted = str_to_unibyte (SDATA (string), str, chars); - - if (converted < chars) - error ("Can't convert the %"pD"dth character to unibyte", converted); - string = make_unibyte_string ((char *) str, chars); - xfree (str); + unsigned char b = *src++; + if (b <= 0x7f) + *dst++ = b; /* ASCII */ + else if (CHAR_BYTE8_HEAD_P (b)) + *dst++ = 0x80 | (b & 1) << 6 | (*src++ & 0x3f); /* raw byte */ + else + error ("Cannot convert character at index %"pD"d to unibyte", i); } - return string; + return ret; } |