Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.  * UTF-8 utility functions
  3.  *
  4.  * (c) 2010 Steve Bennett <steveb@workware.net.au>
  5.  *
  6.  * See LICENCE for licence details.
  7.  */
  8.  
  9. #include <ctype.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include "utf8.h"
  14.  
  15. #ifdef USE_UTF8
  16. int utf8_fromunicode(char *p, unsigned short uc)
  17. {
  18.     if (uc <= 0x7f) {
  19.         *p = uc;
  20.         return 1;
  21.     }
  22.     else if (uc <= 0x7ff) {
  23.         *p++ = 0xc0 | ((uc & 0x7c0) >> 6);
  24.         *p = 0x80 | (uc & 0x3f);
  25.         return 2;
  26.     }
  27.     else {
  28.         *p++ = 0xe0 | ((uc & 0xf000) >> 12);
  29.         *p++ = 0x80 | ((uc & 0xfc0) >> 6);
  30.         *p = 0x80 | (uc & 0x3f);
  31.         return 3;
  32.     }
  33. }
  34.  
  35. int utf8_charlen(int c)
  36. {
  37.     if ((c & 0x80) == 0) {
  38.         return 1;
  39.     }
  40.     if ((c & 0xe0) == 0xc0) {
  41.         return 2;
  42.     }
  43.     if ((c & 0xf0) == 0xe0) {
  44.         return 3;
  45.     }
  46.     if ((c & 0xf8) == 0xf0) {
  47.         return 4;
  48.     }
  49.     /* Invalid sequence */
  50.     return -1;
  51. }
  52.  
  53. int utf8_strlen(const char *str, int bytelen)
  54. {
  55.     int charlen = 0;
  56.     if (bytelen < 0) {
  57.         bytelen = strlen(str);
  58.     }
  59.     while (bytelen) {
  60.         int c;
  61.         int l = utf8_tounicode(str, &c);
  62.         charlen++;
  63.         str += l;
  64.         bytelen -= l;
  65.     }
  66.     return charlen;
  67. }
  68.  
  69. int utf8_index(const char *str, int index)
  70. {
  71.     const char *s = str;
  72.     while (index--) {
  73.         int c;
  74.         s += utf8_tounicode(s, &c);
  75.     }
  76.     return s - str;
  77. }
  78.  
  79. int utf8_charequal(const char *s1, const char *s2)
  80. {
  81.     int c1, c2;
  82.  
  83.     utf8_tounicode(s1, &c1);
  84.     utf8_tounicode(s2, &c2);
  85.  
  86.     return c1 == c2;
  87. }
  88.  
  89. int utf8_tounicode(const char *str, int *uc)
  90. {
  91.     unsigned const char *s = (unsigned const char *)str;
  92.  
  93.     if (s[0] < 0xc0) {
  94.         *uc = s[0];
  95.         return 1;
  96.     }
  97.     if (s[0] < 0xe0) {
  98.         if ((s[1] & 0xc0) == 0x80) {
  99.             *uc = ((s[0] & ~0xc0) << 6) | (s[1] & ~0x80);
  100.             return 2;
  101.         }
  102.     }
  103.     else if (s[0] < 0xf0) {
  104.         if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80)) {
  105.             *uc = ((s[0] & ~0xe0) << 12) | ((s[1] & ~0x80) << 6) | (s[2] & ~0x80);
  106.             return 3;
  107.         }
  108.     }
  109.  
  110.     /* Invalid sequence, so just return the byte */
  111.     *uc = *s;
  112.     return 1;
  113. }
  114.  
  115. #endif
  116.