forked from KolibriOS/kolibrios
ea1a60faa3
git-svn-id: svn://kolibrios.org@9837 a494cfbc-eb01-0410-851d-a64ba20cac60
116 lines
2.1 KiB
C
116 lines
2.1 KiB
C
/**
|
|
* UTF-8 utility functions
|
|
*
|
|
* (c) 2010 Steve Bennett <steveb@workware.net.au>
|
|
*
|
|
* See LICENCE for licence details.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "utf8.h"
|
|
|
|
#ifdef USE_UTF8
|
|
int utf8_fromunicode(char *p, unsigned short uc)
|
|
{
|
|
if (uc <= 0x7f) {
|
|
*p = uc;
|
|
return 1;
|
|
}
|
|
else if (uc <= 0x7ff) {
|
|
*p++ = 0xc0 | ((uc & 0x7c0) >> 6);
|
|
*p = 0x80 | (uc & 0x3f);
|
|
return 2;
|
|
}
|
|
else {
|
|
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
|
|
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
|
|
*p = 0x80 | (uc & 0x3f);
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
int utf8_charlen(int c)
|
|
{
|
|
if ((c & 0x80) == 0) {
|
|
return 1;
|
|
}
|
|
if ((c & 0xe0) == 0xc0) {
|
|
return 2;
|
|
}
|
|
if ((c & 0xf0) == 0xe0) {
|
|
return 3;
|
|
}
|
|
if ((c & 0xf8) == 0xf0) {
|
|
return 4;
|
|
}
|
|
/* Invalid sequence */
|
|
return -1;
|
|
}
|
|
|
|
int utf8_strlen(const char *str, int bytelen)
|
|
{
|
|
int charlen = 0;
|
|
if (bytelen < 0) {
|
|
bytelen = strlen(str);
|
|
}
|
|
while (bytelen) {
|
|
int c;
|
|
int l = utf8_tounicode(str, &c);
|
|
charlen++;
|
|
str += l;
|
|
bytelen -= l;
|
|
}
|
|
return charlen;
|
|
}
|
|
|
|
int utf8_index(const char *str, int index)
|
|
{
|
|
const char *s = str;
|
|
while (index--) {
|
|
int c;
|
|
s += utf8_tounicode(s, &c);
|
|
}
|
|
return s - str;
|
|
}
|
|
|
|
int utf8_charequal(const char *s1, const char *s2)
|
|
{
|
|
int c1, c2;
|
|
|
|
utf8_tounicode(s1, &c1);
|
|
utf8_tounicode(s2, &c2);
|
|
|
|
return c1 == c2;
|
|
}
|
|
|
|
int utf8_tounicode(const char *str, int *uc)
|
|
{
|
|
unsigned const char *s = (unsigned const char *)str;
|
|
|
|
if (s[0] < 0xc0) {
|
|
*uc = s[0];
|
|
return 1;
|
|
}
|
|
if (s[0] < 0xe0) {
|
|
if ((s[1] & 0xc0) == 0x80) {
|
|
*uc = ((s[0] & ~0xc0) << 6) | (s[1] & ~0x80);
|
|
return 2;
|
|
}
|
|
}
|
|
else if (s[0] < 0xf0) {
|
|
if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80)) {
|
|
*uc = ((s[0] & ~0xe0) << 12) | ((s[1] & ~0x80) << 6) | (s[2] & ~0x80);
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/* Invalid sequence, so just return the byte */
|
|
*uc = *s;
|
|
return 1;
|
|
}
|
|
|
|
#endif
|