• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/gettext-0.17/gettext-tools/libgettextpo/unistr/
1/* Look at first character in UTF-8 string.
2   Copyright (C) 1999-2002, 2006-2007 Free Software Foundation, Inc.
3   Written by Bruno Haible <bruno@clisp.org>, 2001.
4
5   This program is free software: you can redistribute it and/or modify it
6   under the terms of the GNU General Public License as published
7   by the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18#include <config.h>
19
20/* Specification.  */
21#include "unistr.h"
22
23#if !HAVE_INLINE
24
25int
26u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n)
27{
28  uint8_t c = *s;
29
30  if (c < 0x80)
31    {
32      *puc = c;
33      return 1;
34    }
35  else if (c >= 0xc2)
36    {
37      if (c < 0xe0)
38	{
39	  if (n >= 2)
40	    {
41	      if ((s[1] ^ 0x80) < 0x40)
42		{
43		  *puc = ((unsigned int) (c & 0x1f) << 6)
44		         | (unsigned int) (s[1] ^ 0x80);
45		  return 2;
46		}
47	      /* invalid multibyte character */
48	    }
49	  else
50	    {
51	      /* incomplete multibyte character */
52	      *puc = 0xfffd;
53	      return n;
54	    }
55	}
56      else if (c < 0xf0)
57	{
58	  if (n >= 3)
59	    {
60	      if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
61		  && (c >= 0xe1 || s[1] >= 0xa0)
62		  && (c != 0xed || s[1] < 0xa0))
63		{
64		  *puc = ((unsigned int) (c & 0x0f) << 12)
65		         | ((unsigned int) (s[1] ^ 0x80) << 6)
66		         | (unsigned int) (s[2] ^ 0x80);
67		  return 3;
68		}
69	      /* invalid multibyte character */
70	    }
71	  else
72	    {
73	      /* incomplete multibyte character */
74	      *puc = 0xfffd;
75	      return n;
76	    }
77	}
78      else if (c < 0xf8)
79	{
80	  if (n >= 4)
81	    {
82	      if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
83		  && (s[3] ^ 0x80) < 0x40
84		  && (c >= 0xf1 || s[1] >= 0x90)
85#if 1
86		  && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
87#endif
88		 )
89		{
90		  *puc = ((unsigned int) (c & 0x07) << 18)
91		         | ((unsigned int) (s[1] ^ 0x80) << 12)
92		         | ((unsigned int) (s[2] ^ 0x80) << 6)
93		         | (unsigned int) (s[3] ^ 0x80);
94		  return 4;
95		}
96	      /* invalid multibyte character */
97	    }
98	  else
99	    {
100	      /* incomplete multibyte character */
101	      *puc = 0xfffd;
102	      return n;
103	    }
104	}
105#if 0
106      else if (c < 0xfc)
107	{
108	  if (n >= 5)
109	    {
110	      if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
111		  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
112		  && (c >= 0xf9 || s[1] >= 0x88))
113		{
114		  *puc = ((unsigned int) (c & 0x03) << 24)
115		         | ((unsigned int) (s[1] ^ 0x80) << 18)
116		         | ((unsigned int) (s[2] ^ 0x80) << 12)
117		         | ((unsigned int) (s[3] ^ 0x80) << 6)
118		         | (unsigned int) (s[4] ^ 0x80);
119		  return 5;
120		}
121	      /* invalid multibyte character */
122	    }
123	  else
124	    {
125	      /* incomplete multibyte character */
126	      *puc = 0xfffd;
127	      return n;
128	    }
129	}
130      else if (c < 0xfe)
131	{
132	  if (n >= 6)
133	    {
134	      if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
135		  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
136		  && (s[5] ^ 0x80) < 0x40
137		  && (c >= 0xfd || s[1] >= 0x84))
138		{
139		  *puc = ((unsigned int) (c & 0x01) << 30)
140		         | ((unsigned int) (s[1] ^ 0x80) << 24)
141		         | ((unsigned int) (s[2] ^ 0x80) << 18)
142		         | ((unsigned int) (s[3] ^ 0x80) << 12)
143		         | ((unsigned int) (s[4] ^ 0x80) << 6)
144		         | (unsigned int) (s[5] ^ 0x80);
145		  return 6;
146		}
147	      /* invalid multibyte character */
148	    }
149	  else
150	    {
151	      /* incomplete multibyte character */
152	      *puc = 0xfffd;
153	      return n;
154	    }
155	}
156#endif
157    }
158  /* invalid multibyte character */
159  *puc = 0xfffd;
160  return 1;
161}
162
163#endif
164