95a76286d4aff4d18a119811821826d18821ae89
[platform/upstream/fribidi.git] / charset / fribidi-char-sets-utf8.c
1 /* FriBidi
2  * fribidi-char-sets-utf8.c - UTF-8 character set conversion routines
3  *
4  * $Id: fribidi-char-sets-utf8.c,v 1.3 2005-07-30 09:06:28 behdad Exp $
5  * $Author: behdad $
6  * $Date: 2005-07-30 09:06:28 $
7  * $Revision: 1.3 $
8  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-utf8.c,v $
9  *
10  * Authors:
11  *   Behdad Esfahbod, 2001, 2002, 2004
12  *   Dov Grobgeld, 1999, 2000
13  *
14  * Copyright (C) 2004 Sharif FarsiWeb, Inc
15  * Copyright (C) 2001,2002 Behdad Esfahbod
16  * Copyright (C) 1999,2000 Dov Grobgeld
17  * 
18  * This library is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU Lesser General Public
20  * License as published by the Free Software Foundation; either
21  * version 2.1 of the License, or (at your option) any later version.
22  * 
23  * This library is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26  * Lesser General Public License for more details.
27  * 
28  * You should have received a copy of the GNU Lesser General Public License
29  * along with this library, in a file named COPYING; if not, write to the
30  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
31  * Boston, MA 02110-1301, USA
32  * 
33  * For licensing issues, contact <license@farsiweb.info>.
34  */
35
36 #include <common.h>
37
38 #include <fribidi-char-sets-utf8.h>
39
40 #include <fribidi-unicode.h>
41
42 FriBidiStrIndex
43 fribidi_utf8_to_unicode (
44   /* input */
45   const char *ss,
46   FriBidiStrIndex len,
47   /* output */
48   FriBidiChar *us
49 )
50 {
51   FriBidiStrIndex length;
52   const unsigned char *s = (unsigned const char *) ss;
53   const unsigned char *t = s;
54
55   length = 0;
56   while ((FriBidiStrIndex) (s - t) < len)
57     {
58       register unsigned char ch = *s;
59       if (ch <= 0x7f)           /* one byte */
60         {
61           *us++ = *s++;
62         }
63       else if (ch <= 0xdf)      /* 2 byte */
64         {
65           *us++ = ((*s & 0x1f) << 6) + (*(s + 1) & 0x3f);
66           s += 2;
67         }
68       else                      /* 3 byte */
69         {
70           *us++ =
71             ((int) (*s & 0x0f) << 12) +
72             ((*(s + 1) & 0x3f) << 6) + (*(s + 2) & 0x3f);
73           s += 3;
74         }
75       length++;
76     }
77   return (length);
78 }
79
80 FriBidiStrIndex
81 fribidi_unicode_to_utf8 (
82   /* input */
83   const FriBidiChar *us,
84   FriBidiStrIndex len,
85   /* output */
86   char *ss
87 )
88 {
89   FriBidiStrIndex i;
90   unsigned char *s = (unsigned char *) ss;
91   unsigned char *t = s;
92
93   for (i = 0; i < len; i++)
94     {
95       FriBidiChar mychar = us[i];
96       if (mychar <= 0x7F)
97         {                       /* 7 sig bits */
98           *t++ = mychar;
99         }
100       else if (mychar <= 0x7FF)
101         {                       /* 11 sig bits */
102           *t++ = 0xC0 | (unsigned char) (mychar >> 6);  /* upper 5 bits */
103           *t++ = 0x80 | (unsigned char) (mychar & 0x3F);        /* lower 6 bits */
104         }
105       else if (mychar <= 0xFFFF)
106         {                       /* 16 sig bits */
107           *t++ = 0xE0 | (unsigned char) (mychar >> 12); /* upper 4 bits */
108           *t++ = 0x80 | (unsigned char) ((mychar >> 6) & 0x3F); /* next 6 bits */
109           *t++ = 0x80 | (unsigned char) (mychar & 0x3F);        /* lowest 6 bits */
110         }
111       else if (mychar < FRIBIDI_UNICODE_CHARS)
112         {                       /* 21 sig bits */
113           *t++ = 0xF0 | (unsigned char) ((mychar >> 18) & 0x07);        /* upper 3 bits */
114           *t++ = 0x80 | (unsigned char) ((mychar >> 12) & 0x3F);        /* next 6 bits */
115           *t++ = 0x80 | (unsigned char) ((mychar >> 6) & 0x3F); /* next 6 bits */
116           *t++ = 0x80 | (unsigned char) (mychar & 0x3F);        /* lowest 6 bits */
117         }
118     }
119   *t = 0;
120
121   return (t - s);
122 }
123
124 /* Editor directions:
125  * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent
126  */