charset.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * charset conversion utils
  4. *
  5. * Copyright (c) 2017 Rob Clark
  6. */
  7. #include <common.h>
  8. #include <charset.h>
  9. #include <capitalization.h>
  10. #include <efi_loader.h>
  11. #include <malloc.h>
  12. static struct capitalization_table capitalization_table[] =
  13. #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
  14. UNICODE_CAPITALIZATION_TABLE;
  15. #elif CONFIG_FAT_DEFAULT_CODEPAGE == 1250
  16. CP1250_CAPITALIZATION_TABLE;
  17. #else
  18. CP437_CAPITALIZATION_TABLE;
  19. #endif
  20. /**
  21. * get_code() - read Unicode code point from UTF-8 stream
  22. *
  23. * @read_u8: - stream reader
  24. * @src: - string buffer passed to stream reader, optional
  25. * Return: - Unicode code point
  26. */
  27. static int get_code(u8 (*read_u8)(void *data), void *data)
  28. {
  29. s32 ch = 0;
  30. ch = read_u8(data);
  31. if (!ch)
  32. return 0;
  33. if (ch >= 0xc2 && ch <= 0xf4) {
  34. int code = 0;
  35. if (ch >= 0xe0) {
  36. if (ch >= 0xf0) {
  37. /* 0xf0 - 0xf4 */
  38. ch &= 0x07;
  39. code = ch << 18;
  40. ch = read_u8(data);
  41. if (ch < 0x80 || ch > 0xbf)
  42. goto error;
  43. ch &= 0x3f;
  44. } else {
  45. /* 0xe0 - 0xef */
  46. ch &= 0x0f;
  47. }
  48. code += ch << 12;
  49. if ((code >= 0xD800 && code <= 0xDFFF) ||
  50. code >= 0x110000)
  51. goto error;
  52. ch = read_u8(data);
  53. if (ch < 0x80 || ch > 0xbf)
  54. goto error;
  55. }
  56. /* 0xc0 - 0xdf or continuation byte (0x80 - 0xbf) */
  57. ch &= 0x3f;
  58. code += ch << 6;
  59. ch = read_u8(data);
  60. if (ch < 0x80 || ch > 0xbf)
  61. goto error;
  62. ch &= 0x3f;
  63. ch += code;
  64. } else if (ch >= 0x80) {
  65. goto error;
  66. }
  67. return ch;
  68. error:
  69. return '?';
  70. }
  71. /**
  72. * read_string() - read byte from character string
  73. *
  74. * @data: - pointer to string
  75. * Return: - byte read
  76. *
  77. * The string pointer is incremented if it does not point to '\0'.
  78. */
  79. static u8 read_string(void *data)
  80. {
  81. const char **src = (const char **)data;
  82. u8 c;
  83. if (!src || !*src || !**src)
  84. return 0;
  85. c = **src;
  86. ++*src;
  87. return c;
  88. }
  89. /**
  90. * read_console() - read byte from console
  91. *
  92. * @data - not used, needed to match interface
  93. * Return: - byte read or 0 on error
  94. */
  95. static u8 read_console(void *data)
  96. {
  97. int ch;
  98. ch = getchar();
  99. if (ch < 0)
  100. ch = 0;
  101. return ch;
  102. }
  103. int console_read_unicode(s32 *code)
  104. {
  105. if (!tstc()) {
  106. /* No input available */
  107. return 1;
  108. }
  109. /* Read Unicode code */
  110. *code = get_code(read_console, NULL);
  111. return 0;
  112. }
  113. s32 utf8_get(const char **src)
  114. {
  115. return get_code(read_string, src);
  116. }
  117. int utf8_put(s32 code, char **dst)
  118. {
  119. if (!dst || !*dst)
  120. return -1;
  121. if ((code >= 0xD800 && code <= 0xDFFF) || code >= 0x110000)
  122. return -1;
  123. if (code <= 0x007F) {
  124. **dst = code;
  125. } else {
  126. if (code <= 0x07FF) {
  127. **dst = code >> 6 | 0xC0;
  128. } else {
  129. if (code < 0x10000) {
  130. **dst = code >> 12 | 0xE0;
  131. } else {
  132. **dst = code >> 18 | 0xF0;
  133. ++*dst;
  134. **dst = (code >> 12 & 0x3F) | 0x80;
  135. }
  136. ++*dst;
  137. **dst = (code >> 6 & 0x3F) | 0x80;
  138. }
  139. ++*dst;
  140. **dst = (code & 0x3F) | 0x80;
  141. }
  142. ++*dst;
  143. return 0;
  144. }
  145. size_t utf8_utf16_strnlen(const char *src, size_t count)
  146. {
  147. size_t len = 0;
  148. for (; *src && count; --count) {
  149. s32 code = utf8_get(&src);
  150. if (!code)
  151. break;
  152. if (code < 0) {
  153. /* Reserve space for a replacement character */
  154. len += 1;
  155. } else if (code < 0x10000) {
  156. len += 1;
  157. } else {
  158. len += 2;
  159. }
  160. }
  161. return len;
  162. }
  163. int utf8_utf16_strncpy(u16 **dst, const char *src, size_t count)
  164. {
  165. if (!src || !dst || !*dst)
  166. return -1;
  167. for (; count && *src; --count) {
  168. s32 code = utf8_get(&src);
  169. if (code < 0)
  170. code = '?';
  171. utf16_put(code, dst);
  172. }
  173. **dst = 0;
  174. return 0;
  175. }
  176. s32 utf16_get(const u16 **src)
  177. {
  178. s32 code, code2;
  179. if (!src || !*src)
  180. return -1;
  181. if (!**src)
  182. return 0;
  183. code = **src;
  184. ++*src;
  185. if (code >= 0xDC00 && code <= 0xDFFF)
  186. return -1;
  187. if (code >= 0xD800 && code <= 0xDBFF) {
  188. if (!**src)
  189. return -1;
  190. code &= 0x3ff;
  191. code <<= 10;
  192. code += 0x10000;
  193. code2 = **src;
  194. ++*src;
  195. if (code2 <= 0xDC00 || code2 >= 0xDFFF)
  196. return -1;
  197. code2 &= 0x3ff;
  198. code += code2;
  199. }
  200. return code;
  201. }
  202. int utf16_put(s32 code, u16 **dst)
  203. {
  204. if (!dst || !*dst)
  205. return -1;
  206. if ((code >= 0xD800 && code <= 0xDFFF) || code >= 0x110000)
  207. return -1;
  208. if (code < 0x10000) {
  209. **dst = code;
  210. } else {
  211. code -= 0x10000;
  212. **dst = code >> 10 | 0xD800;
  213. ++*dst;
  214. **dst = (code & 0x3ff) | 0xDC00;
  215. }
  216. ++*dst;
  217. return 0;
  218. }
  219. size_t utf16_strnlen(const u16 *src, size_t count)
  220. {
  221. size_t len = 0;
  222. for (; *src && count; --count) {
  223. s32 code = utf16_get(&src);
  224. if (!code)
  225. break;
  226. /*
  227. * In case of an illegal sequence still reserve space for a
  228. * replacement character.
  229. */
  230. ++len;
  231. }
  232. return len;
  233. }
  234. size_t utf16_utf8_strnlen(const u16 *src, size_t count)
  235. {
  236. size_t len = 0;
  237. for (; *src && count; --count) {
  238. s32 code = utf16_get(&src);
  239. if (!code)
  240. break;
  241. if (code < 0)
  242. /* Reserve space for a replacement character */
  243. len += 1;
  244. else if (code < 0x80)
  245. len += 1;
  246. else if (code < 0x800)
  247. len += 2;
  248. else if (code < 0x10000)
  249. len += 3;
  250. else
  251. len += 4;
  252. }
  253. return len;
  254. }
  255. int utf16_utf8_strncpy(char **dst, const u16 *src, size_t count)
  256. {
  257. if (!src || !dst || !*dst)
  258. return -1;
  259. for (; count && *src; --count) {
  260. s32 code = utf16_get(&src);
  261. if (code < 0)
  262. code = '?';
  263. utf8_put(code, dst);
  264. }
  265. **dst = 0;
  266. return 0;
  267. }
  268. s32 utf_to_lower(const s32 code)
  269. {
  270. struct capitalization_table *pos = capitalization_table;
  271. s32 ret = code;
  272. if (code <= 0x7f) {
  273. if (code >= 'A' && code <= 'Z')
  274. ret += 0x20;
  275. return ret;
  276. }
  277. for (; pos->upper; ++pos) {
  278. if (pos->upper == code) {
  279. ret = pos->lower;
  280. break;
  281. }
  282. }
  283. return ret;
  284. }
  285. s32 utf_to_upper(const s32 code)
  286. {
  287. struct capitalization_table *pos = capitalization_table;
  288. s32 ret = code;
  289. if (code <= 0x7f) {
  290. if (code >= 'a' && code <= 'z')
  291. ret -= 0x20;
  292. return ret;
  293. }
  294. for (; pos->lower; ++pos) {
  295. if (pos->lower == code) {
  296. ret = pos->upper;
  297. break;
  298. }
  299. }
  300. return ret;
  301. }
  302. /*
  303. * u16_strncmp() - compare two u16 string
  304. *
  305. * @s1: first string to compare
  306. * @s2: second string to compare
  307. * @n: maximum number of u16 to compare
  308. * Return: 0 if the first n u16 are the same in s1 and s2
  309. * < 0 if the first different u16 in s1 is less than the
  310. * corresponding u16 in s2
  311. * > 0 if the first different u16 in s1 is greater than the
  312. * corresponding u16 in s2
  313. */
  314. int u16_strncmp(const u16 *s1, const u16 *s2, size_t n)
  315. {
  316. int ret = 0;
  317. for (; n; --n, ++s1, ++s2) {
  318. ret = *s1 - *s2;
  319. if (ret || !*s1)
  320. break;
  321. }
  322. return ret;
  323. }
  324. size_t u16_strlen(const void *in)
  325. {
  326. const char *pos = in;
  327. size_t ret;
  328. for (; pos[0] || pos[1]; pos += 2)
  329. ;
  330. ret = pos - (char *)in;
  331. ret >>= 1;
  332. return ret;
  333. }
  334. size_t __efi_runtime u16_strnlen(const u16 *in, size_t count)
  335. {
  336. size_t i;
  337. for (i = 0; count-- && in[i]; i++);
  338. return i;
  339. }
  340. size_t u16_strsize(const void *in)
  341. {
  342. return (u16_strlen(in) + 1) * sizeof(u16);
  343. }
  344. u16 *u16_strcpy(u16 *dest, const u16 *src)
  345. {
  346. u16 *tmp = dest;
  347. for (;; dest++, src++) {
  348. *dest = *src;
  349. if (!*src)
  350. break;
  351. }
  352. return tmp;
  353. }
  354. u16 *u16_strdup(const void *src)
  355. {
  356. u16 *new;
  357. size_t len;
  358. if (!src)
  359. return NULL;
  360. len = (u16_strlen(src) + 1) * sizeof(u16);
  361. new = malloc(len);
  362. if (!new)
  363. return NULL;
  364. memcpy(new, src, len);
  365. return new;
  366. }
  367. /* Convert UTF-16 to UTF-8. */
  368. uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)
  369. {
  370. uint32_t code_high = 0;
  371. while (size--) {
  372. uint32_t code = *src++;
  373. if (code_high) {
  374. if (code >= 0xDC00 && code <= 0xDFFF) {
  375. /* Surrogate pair. */
  376. code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000;
  377. *dest++ = (code >> 18) | 0xF0;
  378. *dest++ = ((code >> 12) & 0x3F) | 0x80;
  379. *dest++ = ((code >> 6) & 0x3F) | 0x80;
  380. *dest++ = (code & 0x3F) | 0x80;
  381. } else {
  382. /* Error... */
  383. *dest++ = '?';
  384. /* *src may be valid. Don't eat it. */
  385. src--;
  386. }
  387. code_high = 0;
  388. } else {
  389. if (code <= 0x007F) {
  390. *dest++ = code;
  391. } else if (code <= 0x07FF) {
  392. *dest++ = (code >> 6) | 0xC0;
  393. *dest++ = (code & 0x3F) | 0x80;
  394. } else if (code >= 0xD800 && code <= 0xDBFF) {
  395. code_high = code;
  396. continue;
  397. } else if (code >= 0xDC00 && code <= 0xDFFF) {
  398. /* Error... */
  399. *dest++ = '?';
  400. } else if (code < 0x10000) {
  401. *dest++ = (code >> 12) | 0xE0;
  402. *dest++ = ((code >> 6) & 0x3F) | 0x80;
  403. *dest++ = (code & 0x3F) | 0x80;
  404. } else {
  405. *dest++ = (code >> 18) | 0xF0;
  406. *dest++ = ((code >> 12) & 0x3F) | 0x80;
  407. *dest++ = ((code >> 6) & 0x3F) | 0x80;
  408. *dest++ = (code & 0x3F) | 0x80;
  409. }
  410. }
  411. }
  412. return dest;
  413. }