00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef MAGICKCORE_TOKEN_PRIVATE_H
00019 #define MAGICKCORE_TOKEN_PRIVATE_H
00020
00021 #if defined(__cplusplus) || defined(c_plusplus)
00022 extern "C" {
00023 #endif
00024
00025 #ifndef EILSEQ
00026 #define EILSEQ ENOENT
00027 #endif
00028
00029 #define MaxMultibyteCodes 6
00030
00031 typedef struct
00032 {
00033 int
00034 code_mask,
00035 code_value,
00036 utf_mask,
00037 utf_value;
00038 } UTFInfo;
00039
00040 static UTFInfo
00041 utf_info[MaxMultibyteCodes] =
00042 {
00043 { 0x80, 0x00, 0x000007f, 0x0000000 },
00044 { 0xE0, 0xC0, 0x00007ff, 0x0000080 },
00045 { 0xF0, 0xE0, 0x000ffff, 0x0000800 },
00046 { 0xF8, 0xF0, 0x01fffff, 0x0010000 },
00047 { 0xFC, 0xF8, 0x03fffff, 0x0200000 },
00048 { 0xFE, 0xFC, 0x7ffffff, 0x4000000 },
00049 };
00050
00051 static inline unsigned char *ConvertLatin1ToUTF8(
00052 const unsigned char *magick_restrict content)
00053 {
00054 register const unsigned char
00055 *magick_restrict p;
00056
00057 register unsigned char
00058 *magick_restrict q;
00059
00060 size_t
00061 length;
00062
00063 unsigned char
00064 *utf8;
00065
00066 unsigned int
00067 c;
00068
00069 length=0;
00070 for (p=content; *p != '\0'; p++)
00071 length+=(*p & 0x80) != 0 ? 2 : 1;
00072 utf8=(unsigned char *) NULL;
00073 if (~length >= 1)
00074 utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
00075 if (utf8 == (unsigned char *) NULL)
00076 return((unsigned char *) NULL);
00077 q=utf8;
00078 for (p=content; *p != '\0'; p++)
00079 {
00080 c=(*p);
00081 if ((c & 0x80) == 0)
00082 *q++=c;
00083 else
00084 {
00085 *q++=0xc0 | ((c >> 6) & 0x3f);
00086 *q++=0x80 | (c & 0x3f);
00087 }
00088 }
00089 *q='\0';
00090 return(utf8);
00091 }
00092
00093 static inline int GetNextUTFCode(const char *magick_restrict text,
00094 unsigned int *magick_restrict octets)
00095 {
00096 int
00097 code;
00098
00099 register ssize_t
00100 i;
00101
00102 register int
00103 c,
00104 unicode;
00105
00106 *octets=1;
00107 if (text == (const char *) NULL)
00108 {
00109 errno=EINVAL;
00110 return(-1);
00111 }
00112 code=(int) (*text++) & 0xff;
00113 unicode=code;
00114 for (i=0; i < MaxMultibyteCodes; i++)
00115 {
00116 if ((code & utf_info[i].code_mask) == utf_info[i].code_value)
00117 {
00118 unicode&=utf_info[i].utf_mask;
00119 if (unicode < utf_info[i].utf_value)
00120 break;
00121 *octets=(unsigned int) (i+1);
00122 return(unicode);
00123 }
00124 c=(int) (*text++ ^ 0x80) & 0xff;
00125 if ((c & 0xc0) != 0)
00126 break;
00127 if (unicode > 0x10FFFF)
00128 break;
00129 unicode=(unicode << 6) | c;
00130 }
00131 errno=EILSEQ;
00132 return(-1);
00133 }
00134
00135 static inline int GetUTFCode(const char *magick_restrict text)
00136 {
00137 unsigned int
00138 octets;
00139
00140 return(GetNextUTFCode(text,&octets));
00141 }
00142
00143 static inline unsigned int GetUTFOctets(const char *magick_restrict text)
00144 {
00145 unsigned int
00146 octets;
00147
00148 (void) GetNextUTFCode(text,&octets);
00149 return(octets);
00150 }
00151
00152 static inline MagickBooleanType IsUTFSpace(int code)
00153 {
00154 if (((code >= 0x0009) && (code <= 0x000d)) || (code == 0x0020) ||
00155 (code == 0x0085) || (code == 0x00a0) || (code == 0x1680) ||
00156 (code == 0x180e) || ((code >= 0x2000) && (code <= 0x200a)) ||
00157 (code == 0x2028) || (code == 0x2029) || (code == 0x202f) ||
00158 (code == 0x205f) || (code == 0x3000))
00159 return(MagickTrue);
00160 return(MagickFalse);
00161 }
00162
00163 static inline MagickBooleanType IsUTFValid(int code)
00164 {
00165 int
00166 mask;
00167
00168 mask=(int) 0x7fffffff;
00169 if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
00170 (code != 0xfffe) && (code != 0xffff))
00171 return(MagickFalse);
00172 return(MagickTrue);
00173 }
00174
00175 static inline MagickBooleanType IsUTFAscii(int code)
00176 {
00177 int
00178 mask;
00179
00180 mask=(int) 0x7f;
00181 if ((code & ~mask) != 0)
00182 return(MagickFalse);
00183 return(MagickTrue);
00184 }
00185
00186 #if defined(__cplusplus) || defined(c_plusplus)
00187 }
00188 #endif
00189
00190 #endif