Home | History | Annotate | Download | only in MagickCore
      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