FsUtf.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * Copyright (c) 2011-2022 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "FsUtf.h"
  26. namespace FsUtf {
  27. //----------------------------------------------------------------------------
  28. char* cpToMb(uint32_t cp, char* str, char* end) {
  29. size_t n = end - str;
  30. if (cp < 0X80) {
  31. if (n < 1) goto fail;
  32. *(str++) = static_cast<uint8_t>(cp);
  33. } else if (cp < 0X800) {
  34. if (n < 2) goto fail;
  35. *(str++) = static_cast<uint8_t>((cp >> 6) | 0XC0);
  36. *(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
  37. } else if (cp < 0X10000) {
  38. if (n < 3) goto fail;
  39. *(str++) = static_cast<uint8_t>((cp >> 12) | 0XE0);
  40. *(str++) = static_cast<uint8_t>(((cp >> 6) & 0X3F) | 0X80);
  41. *(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
  42. } else {
  43. if (n < 4) goto fail;
  44. *(str++) = static_cast<uint8_t>((cp >> 18) | 0XF0);
  45. *(str++) = static_cast<uint8_t>(((cp >> 12) & 0X3F)| 0X80);
  46. *(str++) = static_cast<uint8_t>(((cp >> 6) & 0X3F) | 0X80);
  47. *(str++) = static_cast<uint8_t>((cp & 0X3F) | 0X80);
  48. }
  49. return str;
  50. fail:
  51. return nullptr;
  52. }
  53. //----------------------------------------------------------------------------
  54. // to do? improve error check
  55. const char* mbToCp(const char* str, const char* end, uint32_t* rtn) {
  56. size_t n;
  57. uint32_t cp;
  58. if (str >= end) {
  59. return nullptr;
  60. }
  61. uint8_t ch = str[0];
  62. if ((ch & 0X80) == 0) {
  63. *rtn = ch;
  64. return str + 1;
  65. }
  66. if ((ch & 0XE0) == 0XC0) {
  67. cp = ch & 0X1F;
  68. n = 2;
  69. } else if ((ch & 0XF0) == 0XE0) {
  70. cp = ch & 0X0F;
  71. n = 3;
  72. } else if ((ch & 0XF8) == 0XF0) {
  73. cp = ch & 0X07;
  74. n = 4;
  75. } else {
  76. return nullptr;
  77. }
  78. if ((str + n) > end) {
  79. return nullptr;
  80. }
  81. for (size_t i = 1; i < n; i++) {
  82. ch = str[i];
  83. if ((ch & 0XC0) != 0X80) {
  84. return nullptr;
  85. }
  86. cp <<= 6;
  87. cp |= ch & 0X3F;
  88. }
  89. // Don't allow over long as ASCII.
  90. if (cp < 0X80 || !isValidCp(cp)) {
  91. return nullptr;
  92. }
  93. *rtn = cp;
  94. return str + n;
  95. }
  96. //----------------------------------------------------------------------------
  97. const char* mbToU16(const char* str,
  98. const char* end, uint16_t* hs, uint16_t* ls) {
  99. uint32_t cp;
  100. const char* ptr = mbToCp(str, end, &cp);
  101. if (!ptr) {
  102. return nullptr;
  103. }
  104. if (cp <= 0XFFFF) {
  105. *hs = cp;
  106. *ls = 0;
  107. } else {
  108. *hs = highSurrogate(cp);
  109. *ls = lowSurrogate(cp);
  110. }
  111. return ptr;
  112. }
  113. } // namespace FsUtf