1 /*
2 Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization
3 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)
22 extern "C" {
23 #endif
24
25 #ifndef EILSEQ
26 #define EILSEQ ENOENT
27 #endif
28
29 #define MaxMultibyteCodes 6
30
31 extern MagickPrivate MagickBooleanType
32 IsGlob(const char *);
33
34 typedef struct
35 {
36 int
37 code_mask,
38 code_value,
39 utf_mask,
40 utf_value;
41 } UTFInfo;
42
43 static 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
ConvertLatin1ToUTF8(const unsigned char * content)54 static inline unsigned char *ConvertLatin1ToUTF8(const unsigned char *content)
55 {
56 int
57 c;
58
59 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
71 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)
84 *q++=(unsigned char) c;
85 else
86 {
87 *q++=(unsigned char) (0xc0 | ((c >> 6) & 0x3f));
88 *q++=(unsigned char) (0x80 | (c & 0x3f));
89 }
90 }
91 *q='\0';
92 return(utf8);
93 }
94
GetNextUTFCode(const char * text,unsigned int * octets)95 static inline int GetNextUTFCode(const char *text,unsigned int *octets)
96 {
97 int
98 code;
99
100 register ssize_t
101 i;
102
103 register int
104 c,
105 unicode;
106
107 *octets=1;
108 if (text == (const char *) NULL)
109 {
110 errno=EINVAL;
111 return(-1);
112 }
113 code=(int) (*text++) & 0xff;
114 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;
123 return(-1);
124 }
125 *octets=(unsigned int) (i+1);
126 return(unicode);
127 }
128 c=(int) (*text++ ^ 0x80) & 0xff;
129 if ((c & 0xc0) != 0)
130 {
131 errno=EILSEQ;
132 return(-1);
133 }
134 unicode=(unicode << 6) | c;
135 }
136 errno=EILSEQ;
137 return(-1);
138 }
139
GetUTFCode(const char * text)140 static inline int GetUTFCode(const char *text)
141 {
142 unsigned int
143 octets;
144
145 return(GetNextUTFCode(text,&octets));
146 }
147
GetUTFOctets(const char * text)148 static inline unsigned int GetUTFOctets(const char *text)
149 {
150 unsigned int
151 octets;
152
153 (void) GetNextUTFCode(text,&octets);
154 return(octets);
155 }
156
IsUTFSpace(int code)157 static inline MagickBooleanType IsUTFSpace(int code)
158 {
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
IsUTFValid(int code)168 static inline MagickBooleanType IsUTFValid(int code)
169 {
170 int
171 mask;
172
173 mask=(int) 0x7fffffff;
174 if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
175 (code != 0xfffe) && (code != 0xffff))
176 return(MagickFalse);
177 return(MagickTrue);
178 }
179
IsUTFAscii(int code)180 static inline MagickBooleanType IsUTFAscii(int code)
181 {
182 int
183 mask;
184
185 mask=(int) 0x7f;
186 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
196