efi-string: add new xstr16_to_ascii() helper

This commit is contained in:
Lennart Poettering
2025-02-11 19:22:28 +01:00
parent e577d7d94a
commit d9d3e9d6c1
3 changed files with 82 additions and 11 deletions

View File

@@ -188,8 +188,10 @@ static unsigned utf8_to_unichar(const char *utf8, size_t n, char32_t *c) {
/* Convert UTF-8 to UCS-2, skipping any invalid or short byte sequences. */
char16_t *xstrn8_to_16(const char *str8, size_t n) {
if (!str8 || n == 0)
return NULL;
assert(str8 || n == 0);
if (n == SIZE_MAX)
n = strlen8(str8);
size_t i = 0;
char16_t *str16 = xnew(char16_t, n + 1);
@@ -209,10 +211,34 @@ char16_t *xstrn8_to_16(const char *str8, size_t n) {
}
}
str16[i] = '\0';
str16[i] = u'\0';
return str16;
}
char *xstrn16_to_ascii(const char16_t *str16, size_t n) {
assert(str16 || n == 0);
if (n == SIZE_MAX)
n = strlen16(str16);
_cleanup_free_ char *str8 = xnew(char, n + 1);
size_t i = 0;
while (n > 0 && *str16 != u'\0') {
if ((uint16_t) *str16 > 127U) /* Not ASCII? Fail! */
return NULL;
str8[i++] = (char) (uint16_t) *str16;
str16++;
n--;
}
str8[i] = '\0';
return TAKE_PTR(str8);
}
char* startswith8(const char *s, const char *prefix) {
size_t l;

View File

@@ -98,7 +98,12 @@ static inline char16_t *xstrdup16(const char16_t *s) {
char16_t *xstrn8_to_16(const char *str8, size_t n);
static inline char16_t *xstr8_to_16(const char *str8) {
return xstrn8_to_16(str8, strlen8(str8));
return xstrn8_to_16(str8, SIZE_MAX);
}
char *xstrn16_to_ascii(const char16_t *str16, size_t n);
static inline char *xstr16_to_ascii(const char16_t *str16) {
return xstrn16_to_ascii(str16, SIZE_MAX);
}
char* startswith8(const char *s, const char *prefix);

View File

@@ -332,30 +332,70 @@ TEST(xstrdup16) {
TEST(xstrn8_to_16) {
char16_t *s = NULL;
assert_se(xstrn8_to_16(NULL, 1) == NULL);
assert_se(xstrn8_to_16("a", 0) == NULL);
assert_se(s = xstrn8_to_16(NULL, 0));
ASSERT_TRUE(streq16(s, u""));
free(s);
assert_se(s = xstrn8_to_16("", 0));
ASSERT_TRUE(streq16(s, u""));
free(s);
assert_se(s = xstrn8_to_16("a", 0));
ASSERT_TRUE(streq16(s, u""));
free(s);
assert_se(s = xstrn8_to_16("", 1));
assert_se(streq16(s, u""));
ASSERT_TRUE(streq16(s, u""));
free(s);
assert_se(s = xstrn8_to_16("1", 1));
assert_se(streq16(s, u"1"));
ASSERT_TRUE(streq16(s, u"1"));
free(s);
assert_se(s = xstr8_to_16("abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
assert_se(streq16(s, u"abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
ASSERT_TRUE(streq16(s, u"abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
free(s);
assert_se(s = xstr8_to_16("ÿⱿ𝇉 😺"));
assert_se(streq16(s, u"ÿⱿ "));
ASSERT_TRUE(streq16(s, u"ÿⱿ "));
free(s);
assert_se(s = xstrn8_to_16("¶¶", 3));
assert_se(streq16(s, u""));
ASSERT_TRUE(streq16(s, u""));
free(s);
}
TEST(xstrn16_to_ascii) {
char *s;
assert_se(s = xstrn16_to_ascii(NULL, 0));
ASSERT_TRUE(streq8(s, ""));
free(s);
assert_se(s = xstrn16_to_ascii(u"", 0));
ASSERT_TRUE(streq8(s, ""));
free(s);
assert_se(s = xstrn16_to_ascii(u"a", 0));
ASSERT_TRUE(streq8(s, ""));
free(s);
assert_se(s = xstrn16_to_ascii(u"", 1));
ASSERT_TRUE(streq8(s, ""));
free(s);
assert_se(s = xstrn16_to_ascii(u"1", 1));
ASSERT_TRUE(streq8(s, "1"));
free(s);
assert_se(s = xstr16_to_ascii(u"abcxyzABCXYZ09 .,-_#*!\"$%&/()=?`~"));
ASSERT_TRUE(streq8(s, "abcxyzABCXYZ09 .,-_#*!\"$%&/()=?`~"));
free(s);
assert_se(!xstr16_to_ascii(u"ÿⱿ𝇉 😺"));
assert_se(!xstr16_to_ascii(u"¶¶"));
}
TEST(startswith8) {
assert_se(streq8(startswith8("", ""), ""));
assert_se(streq8(startswith8("x", ""), "x"));