Exemplo n.º 1
0
size_t
wcsftime_l(wchar_t *wcs, size_t maxsize,
    const wchar_t *format, const struct tm *timeptr, locale_t loc)
{
	char *dst, *dstp, *sformat;
	size_t n, sflen;
	int sverrno;

	sformat = dst = NULL;

	/*
	 * Convert the supplied format string to a multibyte representation
	 * for strftime(), which only handles single-byte characters.
	 */
	sflen = wcstombs_l(NULL, format, 0, loc);
	if (sflen == (size_t)-1)
		goto error;
	if ((sformat = malloc(sflen + 1)) == NULL)
		goto error;
	wcstombs_l(sformat, format, sflen + 1, loc);

	/*
	 * Allocate memory for longest multibyte sequence that will fit
	 * into the caller's buffer and call strftime() to fill it.
	 * Then, copy and convert the result back into wide characters in
	 * the caller's buffer.
	 */
	if (SIZE_T_MAX / MB_CUR_MAX_L(loc) <= maxsize) {
		/* maxsize is preposterously large - avoid int. overflow. */
		errno = EINVAL;
		goto error;
	}
	dst = malloc(maxsize * MB_CUR_MAX_L(loc));
	if (dst == NULL)
		goto error;
	if (strftime_l(dst, maxsize, sformat, timeptr, loc) == 0)
		goto error;
	dstp = dst;
	n = mbstowcs_l(wcs, dstp, maxsize, loc);
	if (n == (size_t)-2 || n == (size_t)-1)
		goto error;

	free(sformat);
	free(dst);
	return n;

error:
	sverrno = errno;
	free(sformat);
	free(dst);
	errno = sverrno;
	return 0;
}
Exemplo n.º 2
0
/*
 * wchar2char --- convert wide characters to multibyte format
 *
 * This has the same API as the standard wcstombs_l() function; in particular,
 * tolen is the maximum number of bytes to store at *to, and *from must be
 * zero-terminated.  The output will be zero-terminated iff there is room.
 */
size_t
wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
{
	size_t		result;

	if (tolen == 0)
		return 0;

#ifdef WIN32

	/*
	 * On Windows, the "Unicode" locales assume UTF16 not UTF8 encoding, and
	 * for some reason mbstowcs and wcstombs won't do this for us, so we use
	 * MultiByteToWideChar().
	 */
	if (GetDatabaseEncoding() == PG_UTF8)
	{
		result = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, tolen,
									 NULL, NULL);
		/* A zero return is failure */
		if (result <= 0)
			result = -1;
		else
		{
			Assert(result <= tolen);
			/* Microsoft counts the zero terminator in the result */
			result--;
		}
	}
	else
#endif   /* WIN32 */
	if (locale == (pg_locale_t) 0)
	{
		/* Use wcstombs directly for the default locale */
		result = wcstombs(to, from, tolen);
	}
	else
	{
#ifdef HAVE_LOCALE_T
#ifdef HAVE_WCSTOMBS_L
		/* Use wcstombs_l for nondefault locales */
		result = wcstombs_l(to, from, tolen, locale);
#else							/* !HAVE_WCSTOMBS_L */
		/* We have to temporarily set the locale as current ... ugh */
		locale_t	save_locale = uselocale(locale);

		result = wcstombs(to, from, tolen);

		uselocale(save_locale);
#endif   /* HAVE_WCSTOMBS_L */
#else							/* !HAVE_LOCALE_T */
		/* Can't have locale != 0 without HAVE_LOCALE_T */
		elog(ERROR, "wcstombs_l is not available");
		result = 0;				/* keep compiler quiet */
#endif   /* HAVE_LOCALE_T */
	}

	return result;
}
Exemplo n.º 3
0
int UTF8::FromUnicode(const wchar_t *wstr, int wlen, char *str, int *len)
{
#if defined(WIN32) || defined(_WINDOWS_)
	wlen = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, str, wlen * 4, NULL, NULL);
#else
	if (!m_UTF8_locale) m_UTF8_locale = _create_locale(LC_ALL, "en_US.UTF-8");
	wlen = wcstombs_l(str, wstr, wlen, m_UTF8_locale);
#endif

	if (len != NULL) *len = wlen;
	return (errno = 0);
}