/*
  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization
  dedicated to making software imaging solutions freely available.

  You may not use this file except in compliance with the License.
  obtain a copy of the License at

    http://www.imagemagick.org/script/license.php

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

  MagickCore private token methods.
*/
#ifndef MAGICKCORE_TOKEN_PRIVATE_H
#define MAGICKCORE_TOKEN_PRIVATE_H

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

#ifndef EILSEQ
  #define EILSEQ  ENOENT
#endif

#define MaxMultibyteCodes  6

extern MagickPrivate MagickBooleanType
  IsGlob(const char *);

typedef struct
{
  int
    code_mask,
    code_value,
    utf_mask,
    utf_value;
} UTFInfo;

static UTFInfo
  utf_info[MaxMultibyteCodes] =
  {
    { 0x80, 0x00, 0x000007f, 0x0000000 },  /* 1 byte sequence */
    { 0xE0, 0xC0, 0x00007ff, 0x0000080 },  /* 2 byte sequence */
    { 0xF0, 0xE0, 0x000ffff, 0x0000800 },  /* 3 byte sequence */
    { 0xF8, 0xF0, 0x01fffff, 0x0010000 },  /* 4 byte sequence */
    { 0xFC, 0xF8, 0x03fffff, 0x0200000 },  /* 5 byte sequence */
    { 0xFE, 0xFC, 0x7ffffff, 0x4000000 },  /* 6 byte sequence */
  };

static inline unsigned char *ConvertLatin1ToUTF8(const unsigned char *content)
{
  int
    c;

  register const unsigned char
    *p;

  register unsigned char
    *q;

  size_t
    length;

  unsigned char
    *utf8;

  length=0;
  for (p=content; *p != '\0'; p++)
    length+=(*p & 0x80) != 0 ? 2 : 1;
  utf8=(unsigned char *) NULL;
  if (~length >= 1)
    utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
  if (utf8 == (unsigned char *) NULL)
    return((unsigned char *) NULL);
  q=utf8;
  for (p=content; *p != '\0'; p++)
  {
    c=(*p);
    if ((c & 0x80) == 0)
      *q++=(unsigned char) c;
    else
      {
        *q++=(unsigned char) (0xc0 | ((c >> 6) & 0x3f));
        *q++=(unsigned char) (0x80 | (c & 0x3f));
      }
  }
  *q='\0';
  return(utf8);
}

static inline int GetNextUTFCode(const char *text,unsigned int *octets)
{
  int
    code;

  register ssize_t
    i;

  register int
    c,
    unicode;

  *octets=1;
  if (text == (const char *) NULL)
    {
      errno=EINVAL;
      return(-1);
    }
  code=(int) (*text++) & 0xff;
  unicode=code;
  for (i=0; i < MaxMultibyteCodes; i++)
  {
    if ((code & utf_info[i].code_mask) == utf_info[i].code_value)
      {
        unicode&=utf_info[i].utf_mask;
        if (unicode < utf_info[i].utf_value)
          {
            errno=EILSEQ;
            return(-1);
          }
        *octets=(unsigned int) (i+1);
        return(unicode);
      }
    c=(int) (*text++ ^ 0x80) & 0xff;
    if ((c & 0xc0) != 0)
      {
        errno=EILSEQ;
        return(-1);
      }
    unicode=(unicode << 6) | c;
  }
  errno=EILSEQ;
  return(-1);
}

static inline int GetUTFCode(const char *text)
{
  unsigned int
    octets;

  return(GetNextUTFCode(text,&octets));
}

static inline unsigned int GetUTFOctets(const char *text)
{
  unsigned int
    octets;

  (void) GetNextUTFCode(text,&octets);
  return(octets);
}

static inline MagickBooleanType IsUTFSpace(int code)
{
  if (((code >= 0x0009) && (code <= 0x000d)) || (code == 0x0020) ||
      (code == 0x0085) || (code == 0x00a0) || (code == 0x1680) ||
      (code == 0x180e) || ((code >= 0x2000) && (code <= 0x200a)) ||
      (code == 0x2028) || (code == 0x2029) || (code == 0x202f) ||
      (code == 0x205f) || (code == 0x3000))
    return(MagickTrue);
  return(MagickFalse);
}

static inline MagickBooleanType IsUTFValid(int code)
{
  int
    mask;

  mask=(int) 0x7fffffff;
  if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
      (code != 0xfffe) && (code != 0xffff))
    return(MagickFalse);
  return(MagickTrue);
}

static inline MagickBooleanType IsUTFAscii(int code)
{
  int
    mask;

  mask=(int) 0x7f;
  if ((code & ~mask) != 0)
    return(MagickFalse);
  return(MagickTrue);
}

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#endif
