token-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2020 ImageMagick Studio LLC, a non-profit organization
00003   dedicated to making software imaging solutions freely available.
00004 
00005   You may not use this file except in compliance with the License.  You may
00006   obtain a copy of the License at
00007 
00008     https://imagemagick.org/script/license.php
00009 
00010   Unless required by applicable law or agreed to in writing, software
00011   distributed under the License is distributed on an "AS IS" BASIS,
00012   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013   See the License for the specific language governing permissions and
00014   limitations under the License.
00015 
00016   MagickCore private token methods.
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 extern MagickPrivate MagickBooleanType
00032   IsGlob(const char *) magick_attribute((__pure__));
00033 
00034 typedef struct
00035 {
00036   int
00037     code_mask,
00038     code_value,
00039     utf_mask,
00040     utf_value;
00041 } UTFInfo;
00042 
00043 static UTFInfo
00044   utf_info[MaxMultibyteCodes] =
00045   {
00046     { 0x80, 0x00, 0x000007f, 0x0000000 },  /* 1 byte sequence */
00047     { 0xE0, 0xC0, 0x00007ff, 0x0000080 },  /* 2 byte sequence */
00048     { 0xF0, 0xE0, 0x000ffff, 0x0000800 },  /* 3 byte sequence */
00049     { 0xF8, 0xF0, 0x01fffff, 0x0010000 },  /* 4 byte sequence */
00050     { 0xFC, 0xF8, 0x03fffff, 0x0200000 },  /* 5 byte sequence */
00051     { 0xFE, 0xFC, 0x7ffffff, 0x4000000 },  /* 6 byte sequence */
00052   };
00053 
00054 static inline unsigned char *ConvertLatin1ToUTF8(
00055   const unsigned char *magick_restrict content)
00056 {
00057   int
00058     c;
00059 
00060   register const unsigned char
00061     *magick_restrict p;
00062 
00063   register unsigned char
00064     *magick_restrict q;
00065 
00066   size_t
00067     length;
00068 
00069   unsigned char
00070     *utf8;
00071 
00072   length=0;
00073   for (p=content; *p != '\0'; p++)
00074     length+=(*p & 0x80) != 0 ? 2 : 1;
00075   utf8=(unsigned char *) NULL;
00076   if (~length >= 1)
00077     utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
00078   if (utf8 == (unsigned char *) NULL)
00079     return((unsigned char *) NULL);
00080   q=utf8;
00081   for (p=content; *p != '\0'; p++)
00082   {
00083     c=(*p);
00084     if ((c & 0x80) == 0)
00085       *q++=(unsigned char) c;
00086     else
00087       {
00088         *q++=(unsigned char) (0xc0 | ((c >> 6) & 0x3f));
00089         *q++=(unsigned char) (0x80 | (c & 0x3f));
00090       }
00091   }
00092   *q='\0';
00093   return(utf8);
00094 }
00095 
00096 static inline int GetNextUTFCode(const char *magick_restrict text,
00097   unsigned int *magick_restrict octets)
00098 {
00099   int
00100     code;
00101 
00102   register ssize_t
00103     i;
00104 
00105   register int
00106     c,
00107     unicode;
00108 
00109   *octets=1;
00110   if (text == (const char *) NULL)
00111     {
00112       errno=EINVAL;
00113       return(-1);
00114     }
00115   code=(int) (*text++) & 0xff;
00116   unicode=code;
00117   for (i=0; i < MaxMultibyteCodes; i++)
00118   {
00119     if ((code & utf_info[i].code_mask) == utf_info[i].code_value)
00120       {
00121         unicode&=utf_info[i].utf_mask;
00122         if (unicode < utf_info[i].utf_value)
00123           break;
00124         *octets=(unsigned int) (i+1);
00125         return(unicode);
00126       }
00127     c=(int) (*text++ ^ 0x80) & 0xff;
00128     if ((c & 0xc0) != 0)
00129       break;
00130     if (unicode > 0x10FFFF)
00131       break;
00132     unicode=(unicode << 6) | c;
00133   }
00134   errno=EILSEQ;
00135   return(-1);
00136 }
00137 
00138 static inline int GetUTFCode(const char *magick_restrict text)
00139 {
00140   unsigned int
00141     octets;
00142 
00143   return(GetNextUTFCode(text,&octets));
00144 }
00145 
00146 static inline unsigned int GetUTFOctets(const char *magick_restrict text)
00147 {
00148   unsigned int
00149     octets;
00150 
00151   (void) GetNextUTFCode(text,&octets);
00152   return(octets);
00153 }
00154 
00155 static inline MagickBooleanType IsUTFSpace(int code)
00156 {
00157   if (((code >= 0x0009) && (code <= 0x000d)) || (code == 0x0020) ||
00158       (code == 0x0085) || (code == 0x00a0) || (code == 0x1680) ||
00159       (code == 0x180e) || ((code >= 0x2000) && (code <= 0x200a)) ||
00160       (code == 0x2028) || (code == 0x2029) || (code == 0x202f) ||
00161       (code == 0x205f) || (code == 0x3000))
00162     return(MagickTrue);
00163   return(MagickFalse);
00164 }
00165 
00166 static inline MagickBooleanType IsUTFValid(int code)
00167 {
00168   int
00169     mask;
00170 
00171   mask=(int) 0x7fffffff;
00172   if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
00173       (code != 0xfffe) && (code != 0xffff))
00174     return(MagickFalse);
00175   return(MagickTrue);
00176 }
00177 
00178 static inline MagickBooleanType IsUTFAscii(int code)
00179 {
00180   int
00181     mask;
00182 
00183   mask=(int) 0x7f;
00184   if ((code & ~mask) != 0)
00185     return(MagickFalse);
00186   return(MagickTrue);
00187 }
00188 
00189 #if defined(__cplusplus) || defined(c_plusplus)
00190 }
00191 #endif
00192 
00193 #endif

Generated on 18 Feb 2020 for MagickCore by  doxygen 1.6.1