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 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 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 140 static inline int GetUTFCode(const char *text) 141 { 142 unsigned int 143 octets; 144 145 return(GetNextUTFCode(text,&octets)); 146 } 147 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 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 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 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