ucs2_string.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include <linux/ucs2_string.h>
  2. #include <linux/module.h>
  3. /* Return the number of unicode characters in data */
  4. unsigned long
  5. ucs2_strnlen(const ucs2_char_t *s, size_t maxlength)
  6. {
  7. unsigned long length = 0;
  8. while (*s++ != 0 && length < maxlength)
  9. length++;
  10. return length;
  11. }
  12. EXPORT_SYMBOL(ucs2_strnlen);
  13. unsigned long
  14. ucs2_strlen(const ucs2_char_t *s)
  15. {
  16. return ucs2_strnlen(s, ~0UL);
  17. }
  18. EXPORT_SYMBOL(ucs2_strlen);
  19. /*
  20. * Return the number of bytes is the length of this string
  21. * Note: this is NOT the same as the number of unicode characters
  22. */
  23. unsigned long
  24. ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength)
  25. {
  26. return ucs2_strnlen(data, maxlength/sizeof(ucs2_char_t)) * sizeof(ucs2_char_t);
  27. }
  28. EXPORT_SYMBOL(ucs2_strsize);
  29. int
  30. ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len)
  31. {
  32. while (1) {
  33. if (len == 0)
  34. return 0;
  35. if (*a < *b)
  36. return -1;
  37. if (*a > *b)
  38. return 1;
  39. if (*a == 0) /* implies *b == 0 */
  40. return 0;
  41. a++;
  42. b++;
  43. len--;
  44. }
  45. }
  46. EXPORT_SYMBOL(ucs2_strncmp);
  47. unsigned long
  48. ucs2_utf8size(const ucs2_char_t *src)
  49. {
  50. unsigned long i;
  51. unsigned long j = 0;
  52. for (i = 0; src[i]; i++) {
  53. u16 c = src[i];
  54. if (c >= 0x800)
  55. j += 3;
  56. else if (c >= 0x80)
  57. j += 2;
  58. else
  59. j += 1;
  60. }
  61. return j;
  62. }
  63. EXPORT_SYMBOL(ucs2_utf8size);
  64. /*
  65. * copy at most maxlength bytes of whole utf8 characters to dest from the
  66. * ucs2 string src.
  67. *
  68. * The return value is the number of characters copied, not including the
  69. * final NUL character.
  70. */
  71. unsigned long
  72. ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
  73. {
  74. unsigned int i;
  75. unsigned long j = 0;
  76. unsigned long limit = ucs2_strnlen(src, maxlength);
  77. for (i = 0; maxlength && i < limit; i++) {
  78. u16 c = src[i];
  79. if (c >= 0x800) {
  80. if (maxlength < 3)
  81. break;
  82. maxlength -= 3;
  83. dest[j++] = 0xe0 | (c & 0xf000) >> 12;
  84. dest[j++] = 0x80 | (c & 0x0fc0) >> 6;
  85. dest[j++] = 0x80 | (c & 0x003f);
  86. } else if (c >= 0x80) {
  87. if (maxlength < 2)
  88. break;
  89. maxlength -= 2;
  90. dest[j++] = 0xc0 | (c & 0x7c0) >> 6;
  91. dest[j++] = 0x80 | (c & 0x03f);
  92. } else {
  93. maxlength -= 1;
  94. dest[j++] = c & 0x7f;
  95. }
  96. }
  97. if (maxlength)
  98. dest[j] = '\0';
  99. return j;
  100. }
  101. EXPORT_SYMBOL(ucs2_as_utf8);