/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cm_utf8.h"

#include <string.h>

/*
  RFC 3629
  07-bit: 0xxxxxxx
  11-bit: 110xxxxx 10xxxxxx
  16-bit: 1110xxxx 10xxxxxx 10xxxxxx
  21-bit: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

  Pre-RFC Compatibility
  26-bit: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  31-bit: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/

/* Number of leading ones before a zero in the byte.  */
unsigned char const cm_utf8_ones[256] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8
};

/* Mask away control bits from bytes with n leading ones.  */
static unsigned char const cm_utf8_mask[7] = { 0xEF, 0x3F, 0x1F, 0x0F,
                                               0x07, 0x03, 0x01 };

/* Minimum allowed value when first byte has n leading ones.  */
static unsigned int const cm_utf8_min[7] = {
  0, 0, 1u << 7, 1u << 11, 1u << 16, 1u << 21, 1u << 26 /*, 1u<<31 */
};

const char* cm_utf8_decode_character(const char* first, const char* last,
                                     unsigned int* pc)
{
  /* Count leading ones in the first byte.  */
  unsigned char c = (unsigned char)*first++;
  unsigned char const ones = cm_utf8_ones[c];
  switch (ones) {
    case 0:
      *pc = c;
      return first; /* One-byte character.  */
    case 1:
    case 7:
    case 8:
      return 0; /* Invalid leading byte.  */
    default:
      break;
  }

  /* Extract bits from this multi-byte character.  */
  {
    unsigned int uc = c & cm_utf8_mask[ones];
    int left;
    for (left = ones - 1; left && first != last; --left) {
      c = (unsigned char)*first++;
      if (cm_utf8_ones[c] != 1) {
        return 0;
      }
      uc = (uc << 6) | (c & cm_utf8_mask[1]);
    }

    if (left > 0 || uc < cm_utf8_min[ones]) {
      return 0;
    }

    /* UTF-16 surrogate halves. */
    if (0xD800 <= uc && uc <= 0xDFFF) {
      return 0;
    }

    /* Invalid codepoints. */
    if (0x10FFFF < uc) {
      return 0;
    }

    *pc = uc;
    return first;
  }
}

int cm_utf8_is_valid(const char* s)
{
  if (!s) {
    return 0;
  }

  const char* last = s + strlen(s);
  const char* pos = s;
  unsigned int pc;

  while (pos != last && (pos = cm_utf8_decode_character(pos, last, &pc))) {
    /* Nothing to do. */
  }

  return pos == last;
}
