/*	$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 <string.h>
#include <sys/param.h>
#include <uchar.h>
#include <wchar.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 == nullptr || mbstate_is_initial(ps);
}

size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == nullptr) ? &__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 == nullptr) ? &__private_state : ps;
  size_t i, o, r;

  // The fast paths in the loops below are 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 loops.
  if (nmc > 0 && mbstate_bytes_so_far(state) > 0 && static_cast<uint8_t>((*src)[0]) < 0x80) {
    return mbstate_reset_and_return_illegal(EILSEQ, state);
  }

  // Measure only?
  if (dst == nullptr) {
    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') {
          return mbstate_reset_and_return(o, state);
        }
        r = 1;
      } else {
        r = mbrtowc(nullptr, *src + i, nmc - i, state);
        if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
          return mbstate_reset_and_return_illegal(EILSEQ, state);
        }
        if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
          return mbstate_reset_and_return_illegal(EILSEQ, state);
        }
        if (r == 0) {
          return mbstate_reset_and_return(o, state);
        }
      }
    }
    return mbstate_reset_and_return(o, state);
  }

  // Actually convert, updating `dst` and `src`.
  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 mbstate_reset_and_return(o, state);
      }
    } else {
      r = mbrtowc(dst + o, *src + i, nmc - i, state);
      if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
        *src += i;
        return mbstate_reset_and_return_illegal(EILSEQ, state);
      }
      if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
        *src += nmc;
        return mbstate_reset_and_return_illegal(EILSEQ, state);
      }
      if (r == 0) {
        *src = nullptr;
        return mbstate_reset_and_return(o, state);
      }
    }
  }
  *src += i;
  return mbstate_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);
}
__strong_alias(mbsrtowcs_l, mbsrtowcs);

size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps) {
  static mbstate_t __private_state;
  mbstate_t* state = (ps == nullptr) ? &__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 == nullptr) ? &__private_state : ps;

  if (!mbstate_is_initial(state)) {
    return mbstate_reset_and_return_illegal(EILSEQ, state);
  }

  char buf[MB_LEN_MAX];
  size_t i, o, r;
  if (dst == nullptr) {
    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 == BIONIC_MULTIBYTE_RESULT_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 = nullptr;
        return o;
      }
      r = 1;
    } else if (len - o >= sizeof(buf)) {
      // Enough space to translate in-place.
      r = wcrtomb(dst + o, wc, state);
      if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
        *src += i;
        return r;
      }
    } else {
      // May not be enough space; use temp buffer.
      r = wcrtomb(buf, wc, state);
      if (r == BIONIC_MULTIBYTE_RESULT_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);
}
__strong_alias(wcsrtombs_l, wcsrtombs);
