utf8.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
  2. // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
  3. // Copyright (c) 2017 ZephRay <zephray@outlook.com>
  4. //
  5. // utf8to1252 - almost equivalent to iconv -f utf-8 -t windows-1252, but better
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include "esp_log.h"
  11. #define TAG "aa"
  12. #define UTF8_ACCEPT 0
  13. #define UTF8_REJECT 1
  14. static const uint8_t utf8d[] = {
  15. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  16. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  17. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  18. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  19. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  20. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  21. 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  22. 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  23. 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  24. 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  25. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  26. 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  27. 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  28. 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
  29. };
  30. static uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
  31. uint32_t type = utf8d[byte];
  32. *codep = (*state != UTF8_ACCEPT) ?
  33. (byte & 0x3fu) | (*codep << 6) :
  34. (0xff >> type) & (byte);
  35. *state = utf8d[256 + *state*16 + type];
  36. return *state;
  37. }
  38. static uint8_t UNICODEtoCP1252(uint16_t chr) {
  39. if (chr <= 0xff)
  40. return (chr&0xff);
  41. else {
  42. ESP_LOGI(TAG, "some multi-byte %hx", chr);
  43. switch(chr) {
  44. case 0x20ac: return 0x80; break;
  45. case 0x201a: return 0x82; break;
  46. case 0x0192: return 0x83; break;
  47. case 0x201e: return 0x84; break;
  48. case 0x2026: return 0x85; break;
  49. case 0x2020: return 0x86; break;
  50. case 0x2021: return 0x87; break;
  51. case 0x02c6: return 0x88; break;
  52. case 0x2030: return 0x89; break;
  53. case 0x0160: return 0x8a; break;
  54. case 0x2039: return 0x8b; break;
  55. case 0x0152: return 0x8c; break;
  56. case 0x017d: return 0x8e; break;
  57. case 0x2018: return 0x91; break;
  58. case 0x2019: return 0x92; break;
  59. case 0x201c: return 0x93; break;
  60. case 0x201d: return 0x94; break;
  61. case 0x2022: return 0x95; break;
  62. case 0x2013: return 0x96; break;
  63. case 0x2014: return 0x97; break;
  64. case 0x02dc: return 0x98; break;
  65. case 0x2122: return 0x99; break;
  66. case 0x0161: return 0x9a; break;
  67. case 0x203a: return 0x9b; break;
  68. case 0x0153: return 0x9c; break;
  69. case 0x017e: return 0x9e; break;
  70. case 0x0178: return 0x9f; break;
  71. default: return 0x00; break;
  72. }
  73. }
  74. }
  75. void utf8_decode(char *src) {
  76. uint32_t codep = 0, state = UTF8_ACCEPT;
  77. char *dst = src;
  78. while (src && *src) {
  79. if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep);
  80. }
  81. *dst = '\0';
  82. }