blob: d221924965c369b8ad5b491ca98f66181f22c18c [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
cristy7e41fe82010-12-04 23:12:08 +00002 Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization
cristy3ed852e2009-09-05 21:47:34 +00003 dedicated to making software imaging solutions freely available.
4
5 You may not use this file except in compliance with the License.
6 obtain a copy of the License at
7
8 http://www.imagemagick.org/script/license.php
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 MagickCore private token methods.
17*/
18#ifndef _MAGICKCORE_TOKEN_PRIVATE_H
19#define _MAGICKCORE_TOKEN_PRIVATE_H
20
21#if defined(__cplusplus) || defined(c_plusplus)
22extern "C" {
23#endif
24
25#ifndef EILSEQ
26 #define EILSEQ ENOENT
27#endif
28
29#define MaxMultibyteCodes 6
30
cristy7832dc22011-09-05 01:21:53 +000031extern MagickPrivate MagickBooleanType
32 IsGlob(const char *);
33
cristy3ed852e2009-09-05 21:47:34 +000034typedef struct
35{
cristy5ed838e2010-05-31 00:05:35 +000036 int
cristy3ed852e2009-09-05 21:47:34 +000037 code_mask,
38 code_value,
39 utf_mask,
40 utf_value;
41} UTFInfo;
42
43static UTFInfo
44 utf_info[MaxMultibyteCodes] =
45 {
46 { 0x80, 0x00, 0x000007f, 0x0000000 }, /* 1 byte sequence */
47 { 0xE0, 0xC0, 0x00007ff, 0x0000080 }, /* 2 byte sequence */
48 { 0xF0, 0xE0, 0x000ffff, 0x0000800 }, /* 3 byte sequence */
49 { 0xF8, 0xF0, 0x01fffff, 0x0010000 }, /* 4 byte sequence */
50 { 0xFC, 0xF8, 0x03fffff, 0x0200000 }, /* 5 byte sequence */
51 { 0xFE, 0xFC, 0x7ffffff, 0x4000000 }, /* 6 byte sequence */
52 };
53
cristy2857ffc2010-03-27 23:44:00 +000054static inline unsigned char *ConvertLatin1ToUTF8(const unsigned char *content)
55{
cristyccd8a482011-09-19 17:02:13 +000056 int
57 c;
58
cristy2857ffc2010-03-27 23:44:00 +000059 register const unsigned char
60 *p;
61
62 register unsigned char
63 *q;
64
65 size_t
66 length;
67
68 unsigned char
69 *utf8;
70
cristy2857ffc2010-03-27 23:44:00 +000071 length=0;
72 for (p=content; *p != '\0'; p++)
73 length+=(*p & 0x80) != 0 ? 2 : 1;
74 utf8=(unsigned char *) NULL;
75 if (~length >= 1)
76 utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
77 if (utf8 == (unsigned char *) NULL)
78 return((unsigned char *) NULL);
79 q=utf8;
80 for (p=content; *p != '\0'; p++)
81 {
82 c=(*p);
83 if ((c & 0x80) == 0)
cristyccd8a482011-09-19 17:02:13 +000084 *q++=(unsigned char) c;
cristy2857ffc2010-03-27 23:44:00 +000085 else
86 {
cristyccd8a482011-09-19 17:02:13 +000087 *q++=(unsigned char) (0xc0 | ((c >> 6) & 0x3f));
88 *q++=(unsigned char) (0x80 | (c & 0x3f));
cristy2857ffc2010-03-27 23:44:00 +000089 }
90 }
91 *q='\0';
92 return(utf8);
93}
94
cristy5ed838e2010-05-31 00:05:35 +000095static inline int GetNextUTFCode(const char *text,unsigned int *octets)
cristy3ed852e2009-09-05 21:47:34 +000096{
cristy5ed838e2010-05-31 00:05:35 +000097 int
cristy68b59162010-02-13 02:17:52 +000098 code;
99
cristybb503372010-05-27 20:51:26 +0000100 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000101 i;
102
cristy5ed838e2010-05-31 00:05:35 +0000103 register int
cristy3ed852e2009-09-05 21:47:34 +0000104 c,
105 unicode;
106
cristy386ad9b2010-03-19 23:46:32 +0000107 *octets=1;
cristy3ed852e2009-09-05 21:47:34 +0000108 if (text == (const char *) NULL)
109 {
110 errno=EINVAL;
cristybd512462010-02-13 02:13:14 +0000111 return(-1);
cristy3ed852e2009-09-05 21:47:34 +0000112 }
cristy5ed838e2010-05-31 00:05:35 +0000113 code=(int) (*text++) & 0xff;
cristy3ed852e2009-09-05 21:47:34 +0000114 unicode=code;
115 for (i=0; i < MaxMultibyteCodes; i++)
116 {
117 if ((code & utf_info[i].code_mask) == utf_info[i].code_value)
118 {
119 unicode&=utf_info[i].utf_mask;
120 if (unicode < utf_info[i].utf_value)
121 {
122 errno=EILSEQ;
cristybd512462010-02-13 02:13:14 +0000123 return(-1);
cristy3ed852e2009-09-05 21:47:34 +0000124 }
cristy5ed838e2010-05-31 00:05:35 +0000125 *octets=(unsigned int) (i+1);
cristy3ed852e2009-09-05 21:47:34 +0000126 return(unicode);
127 }
cristy5ed838e2010-05-31 00:05:35 +0000128 c=(int) (*text++ ^ 0x80) & 0xff;
cristy3ed852e2009-09-05 21:47:34 +0000129 if ((c & 0xc0) != 0)
130 {
131 errno=EILSEQ;
cristybd512462010-02-13 02:13:14 +0000132 return(-1);
cristy3ed852e2009-09-05 21:47:34 +0000133 }
134 unicode=(unicode << 6) | c;
135 }
136 errno=EILSEQ;
cristybd512462010-02-13 02:13:14 +0000137 return(-1);
cristy3ed852e2009-09-05 21:47:34 +0000138}
139
cristy5ed838e2010-05-31 00:05:35 +0000140static inline int GetUTFCode(const char *text)
cristy3ed852e2009-09-05 21:47:34 +0000141{
cristy5ed838e2010-05-31 00:05:35 +0000142 unsigned int
cristy3ed852e2009-09-05 21:47:34 +0000143 octets;
144
145 return(GetNextUTFCode(text,&octets));
146}
147
cristy5ed838e2010-05-31 00:05:35 +0000148static inline unsigned int GetUTFOctets(const char *text)
cristy3ed852e2009-09-05 21:47:34 +0000149{
cristy5ed838e2010-05-31 00:05:35 +0000150 unsigned int
cristy3ed852e2009-09-05 21:47:34 +0000151 octets;
152
153 (void) GetNextUTFCode(text,&octets);
154 return(octets);
155}
156
cristy5ed838e2010-05-31 00:05:35 +0000157static inline MagickBooleanType IsUTFSpace(int code)
cristy3ed852e2009-09-05 21:47:34 +0000158{
159 if (((code >= 0x0009) && (code <= 0x000d)) || (code == 0x0020) ||
160 (code == 0x0085) || (code == 0x00a0) || (code == 0x1680) ||
161 (code == 0x180e) || ((code >= 0x2000) && (code <= 0x200a)) ||
162 (code == 0x2028) || (code == 0x2029) || (code == 0x202f) ||
163 (code == 0x205f) || (code == 0x3000))
164 return(MagickTrue);
165 return(MagickFalse);
166}
167
cristy5ed838e2010-05-31 00:05:35 +0000168static inline MagickBooleanType IsUTFValid(int code)
cristy3ed852e2009-09-05 21:47:34 +0000169{
cristy5ed838e2010-05-31 00:05:35 +0000170 int
cristy3ed852e2009-09-05 21:47:34 +0000171 mask;
172
cristy5ed838e2010-05-31 00:05:35 +0000173 mask=(int) 0x7fffffff;
cristy3ed852e2009-09-05 21:47:34 +0000174 if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
175 (code != 0xfffe) && (code != 0xffff))
176 return(MagickFalse);
177 return(MagickTrue);
178}
179
cristy5ed838e2010-05-31 00:05:35 +0000180static inline MagickBooleanType IsUTFAscii(int code)
cristy3ed852e2009-09-05 21:47:34 +0000181{
cristy5ed838e2010-05-31 00:05:35 +0000182 int
cristy3ed852e2009-09-05 21:47:34 +0000183 mask;
184
cristy5ed838e2010-05-31 00:05:35 +0000185 mask=(int) 0x7f;
cristy3ed852e2009-09-05 21:47:34 +0000186 if ((code & ~mask) != 0)
187 return(MagickFalse);
188 return(MagickTrue);
189}
190
191#if defined(__cplusplus) || defined(c_plusplus)
192}
193#endif
194
195#endif