efi_loader: new function utf8_to_utf16
Provide a conversion function from utf8 to utf16. Add missing #include <linux/types.h> in include/charset.h. Remove superfluous #include <common.h> in lib/charset.c. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
30a0045a54
commit
f58c5ecb87
@ -9,6 +9,8 @@
|
||||
#ifndef __CHARSET_H_
|
||||
#define __CHARSET_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define MAX_UTF8_PER_UTF16 3
|
||||
|
||||
/**
|
||||
@ -62,4 +64,17 @@ uint16_t *utf16_strdup(const uint16_t *s);
|
||||
*/
|
||||
uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size);
|
||||
|
||||
/**
|
||||
* utf8_to_utf16() - Convert an utf8 string to utf16
|
||||
*
|
||||
* Converts up to 'size' characters of the utf16 string 'src' to utf8
|
||||
* written to the 'dest' buffer. Stops at 0x00.
|
||||
*
|
||||
* @dest the destination buffer to write the utf8 characters
|
||||
* @src the source utf16 string
|
||||
* @size maximum number of utf16 characters to convert
|
||||
* @return the pointer to the first unwritten byte in 'dest'
|
||||
*/
|
||||
uint16_t *utf8_to_utf16(uint16_t *dest, const uint8_t *src, size_t size);
|
||||
|
||||
#endif /* __CHARSET_H_ */
|
||||
|
@ -6,7 +6,6 @@
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <charset.h>
|
||||
#include <malloc.h>
|
||||
|
||||
@ -99,3 +98,59 @@ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
uint16_t *utf8_to_utf16(uint16_t *dest, const uint8_t *src, size_t size)
|
||||
{
|
||||
while (size--) {
|
||||
int extension_bytes;
|
||||
uint32_t code;
|
||||
|
||||
extension_bytes = 0;
|
||||
if (*src <= 0x7f) {
|
||||
code = *src++;
|
||||
/* Exit on zero byte */
|
||||
if (!code)
|
||||
size = 0;
|
||||
} else if (*src <= 0xbf) {
|
||||
/* Illegal code */
|
||||
code = '?';
|
||||
} else if (*src <= 0xdf) {
|
||||
code = *src++ & 0x1f;
|
||||
extension_bytes = 1;
|
||||
} else if (*src <= 0xef) {
|
||||
code = *src++ & 0x0f;
|
||||
extension_bytes = 2;
|
||||
} else if (*src <= 0xf7) {
|
||||
code = *src++ & 0x07;
|
||||
extension_bytes = 3;
|
||||
} else {
|
||||
/* Illegal code */
|
||||
code = '?';
|
||||
}
|
||||
|
||||
for (; extension_bytes && size; --size, --extension_bytes) {
|
||||
if ((*src & 0xc0) == 0x80) {
|
||||
code <<= 6;
|
||||
code |= *src++ & 0x3f;
|
||||
} else {
|
||||
/* Illegal code */
|
||||
code = '?';
|
||||
++src;
|
||||
--size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code < 0x10000) {
|
||||
*dest++ = code;
|
||||
} else {
|
||||
/*
|
||||
* Simplified expression for
|
||||
* (((code - 0x10000) >> 10) & 0x3ff) | 0xd800
|
||||
*/
|
||||
*dest++ = (code >> 10) + 0xd7c0;
|
||||
*dest++ = (code & 0x3ff) | 0xdc00;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user