charset.c 8.1 KB

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