/*	$OpenBSD: citrus_utf8.c,v 1.6 2012/12/05 23:19:59 deraadt Exp $ */

/*-
 * Copyright (c) 2002-2004 Tim J. Robbins
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <errno.h>
#include <sys/param.h>
#include <string.h>
#include <wchar.h>
#include <uchar.h>

#include "private/bionic_mbstate.h"

//
// This file is basically OpenBSD's citrus_utf8.c but rewritten to not require a
// 12-byte mbstate_t so we're backwards-compatible with our LP32 ABI where
// mbstate_t was only 4 bytes.
//
// The state is the UTF-8 sequence. We only support <= 4-bytes sequences so LP32
// mbstate_t already has enough space (out of the 4 available bytes we only
// need 3 since we should never need to store the entire sequence in the
// intermediary state).
//
// The C standard leaves the conversion state undefined after a bad conversion.
// To avoid unexpected failures due to the possible use of the internal private
// state we always reset the conversion state when encountering illegal
// sequences.
//
// We also implement the POSIX interface directly rather than being accessed via
// function pointers.
//

int mbsinit(const mbstate_t* ps) {
  return (ps == NULL || (*(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0));
}

size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == NULL) ? &__private_state : ps;

  // Our wchar_t is UTF-32
  return mbrtoc32(reinterpret_cast<char32_t*>(pwc), s, n, state);
}

size_t mbsnrtowcs(wchar_t* dst, const char** src, size_t nmc, size_t len, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == NULL) ? &__private_state : ps;
  size_t i, o, r;

  if (dst == NULL) {
    /*
     * The fast path in the loop below is not safe if an ASCII
     * character appears as anything but the first byte of a
     * multibyte sequence. Check now to avoid doing it in the loop.
     */
    if ((nmc > 0) && (mbstate_bytes_so_far(state) > 0)
        && (static_cast<uint8_t>((*src)[0]) < 0x80)) {
      return reset_and_return_illegal(EILSEQ, state);
    }
    for (i = o = 0; i < nmc; i += r, o++) {
      if (static_cast<uint8_t>((*src)[i]) < 0x80) {
        // Fast path for plain ASCII characters.
        if ((*src)[i] == '\0') {
          *src = nullptr;
          return reset_and_return(o, state);
        }
        r = 1;
      } else {
        r = mbrtowc(NULL, *src + i, nmc - i, state);
        if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
          return reset_and_return_illegal(EILSEQ, state);
        }
        if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
          return reset_and_return_illegal(EILSEQ, state);
        }
        if (r == 0) {
          *src = nullptr;
          return reset_and_return(o, state);
        }
      }
    }
    return reset_and_return(o, state);
  }

  /*
   * The fast path in the loop below is not safe if an ASCII
   * character appears as anything but the first byte of a
   * multibyte sequence. Check now to avoid doing it in the loop.
   */
  if ((nmc > 0) && (mbstate_bytes_so_far(state) > 0)
      && (static_cast<uint8_t>((*src)[0]) < 0x80)) {
    return reset_and_return_illegal(EILSEQ, state);
  }
  for (i = o = 0; i < nmc && o < len; i += r, o++) {
    if (static_cast<uint8_t>((*src)[i]) < 0x80) {
      // Fast path for plain ASCII characters.
      dst[o] = (*src)[i];
      r = 1;
      if ((*src)[i] == '\0') {
        *src = nullptr;
        return reset_and_return(o, state);
      }
    } else {
      r = mbrtowc(dst + o, *src + i, nmc - i, state);
      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
        *src += i;
        return reset_and_return_illegal(EILSEQ, state);
      }
      if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
        *src += nmc;
        return reset_and_return(EILSEQ, state);
      }
      if (r == 0) {
        *src = NULL;
        return reset_and_return(o, state);
      }
    }
  }
  *src += i;
  return reset_and_return(o, state);
}

size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) {
  return mbsnrtowcs(dst, src, SIZE_MAX, len, ps);
}

size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == NULL) ? &__private_state : ps;

  // Our wchar_t is UTF-32
  return c32rtomb(s, static_cast<char32_t>(wc), state);
}

size_t wcsnrtombs(char* dst, const wchar_t** src, size_t nwc, size_t len, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == NULL) ? &__private_state : ps;

  if (!mbsinit(state)) {
    return reset_and_return_illegal(EILSEQ, state);
  }

  char buf[MB_LEN_MAX];
  size_t i, o, r;
  if (dst == NULL) {
    for (i = o = 0; i < nwc; i++, o += r) {
      wchar_t wc = (*src)[i];
      if (static_cast<uint32_t>(wc) < 0x80) {
        // Fast path for plain ASCII characters.
        if (wc == 0) {
          return o;
        }
        r = 1;
      } else {
        r = wcrtomb(buf, wc, state);
        if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
          return r;
        }
      }
    }
    return o;
  }

  for (i = o = 0; i < nwc && o < len; i++, o += r) {
    wchar_t wc = (*src)[i];
    if (static_cast<uint32_t>(wc) < 0x80) {
      // Fast path for plain ASCII characters.
      dst[o] = wc;
      if (wc == 0) {
        *src = NULL;
        return o;
      }
      r = 1;
    } else if (len - o >= sizeof(buf)) {
      // Enough space to translate in-place.
      r = wcrtomb(dst + o, wc, state);
      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
        *src += i;
        return r;
      }
    } else {
      // May not be enough space; use temp buffer.
      r = wcrtomb(buf, wc, state);
      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
        *src += i;
        return r;
      }
      if (r > len - o) {
        break;
      }
      memcpy(dst + o, buf, r);
    }
  }
  *src += i;
  return o;
}

size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps) {
  return wcsnrtombs(dst, src, SIZE_MAX, len, ps);
}

int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
  return wcscoll(ws1, ws2);
}

size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, locale_t) {
  return wcsxfrm(dest, src, n);
}

long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base,
                    locale_t) {
  return wcstoll(nptr, endptr, base);
}

unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr,
                              int base, locale_t) {
  return wcstoull(nptr, endptr, base);
}

long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t) {
  return wcstold(nptr, endptr);
}
