/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss of reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#include <wchar.h>

/*
*	Conversion of a wide char to UTF-8 with RFC conformance checking
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*	'mb' points to the place where the result should be stored
*	'wc' contains the wide char
*	The function returns the length of the sequence if wc can be
*	converted, 0 if wc was 0 and negative if wc can not be converted
*	or is not within the allowed range specified by the RFC.
*/

int		blc_wctomb_rfc( char *mb, unsigned int wc )
{
	if ( wc >= 0x110000ul ) return( -1 );
	if ( wc >= 0xd800u && wc <= 0xe000u ) return( -1 );
	return( blc_wctomb_any( mb, wc ) );
}

/*
*	Conversion of a wide char to UTF-8 without RFC conformance checking
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*	'mb' points to the place where the result should be stored
*	'wc' contains the wide char
*	The function returns the length of the sequence if wc can be
*	converted, 0 if wc was 0 and negative if wc can not be converted.
*/

int		blc_wctomb_any( char *mb, unsigned int wc )
{
	if ( wc < 0x80 ) {

		if ( mb ) *mb = wc;
		return( 1 );
	}

	if ( wc < 0x800 ) {

		if ( mb ) {

			mb[ 0 ] = 0xc0 | ( wc >> 6 );
			mb[ 1 ] = 0x80 | ( wc & 63 );
		}

		return( 2 );
	}

	if ( wc < 0x10000ul ) {

		if ( mb ) {

			mb[ 0 ] = 0xe0 | ( wc >> 12 );
			mb[ 1 ] = 0x80 | ( ( wc >> 6 ) & 63 );
			mb[ 2 ] = 0x80 | ( wc & 63 );
		}

		return( 3 );
	}

	if ( wc < 0x200000ul ) {

		if ( mb ) {

			mb[ 0 ] = 0xf0 | ( wc >> 18 );
			mb[ 1 ] = 0x80 | ( ( wc >> 12 ) & 63 );
			mb[ 2 ] = 0x80 | ( ( wc >> 6 ) & 63 );
			mb[ 3 ] = 0x80 | ( wc & 63 );
		}

		return( 4 );
	}

	if ( wc < 0x4000000ul ) {

		if ( mb ) {

			mb[ 0 ] = 0xf8 | ( wc >> 24 );
			mb[ 1 ] = 0x80 | ( ( wc >> 18 ) & 63 );
			mb[ 2 ] = 0x80 | ( ( wc >> 12 ) & 63 );
			mb[ 3 ] = 0x80 | ( ( wc >> 6 ) & 63 );
			mb[ 4 ] = 0x80 | ( wc & 63 );
		}

		return( 5 );
	}

	if ( wc < 0x80000000ul ) {

		if ( mb ) {

			mb[ 0 ] = 0xfc | ( wc >> 30 );
			mb[ 1 ] = 0x80 | ( ( wc >> 24 ) & 63 );
			mb[ 2 ] = 0x80 | ( ( wc >> 18 ) & 63 );
			mb[ 3 ] = 0x80 | ( ( wc >> 12 ) & 63 );
			mb[ 4 ] = 0x80 | ( ( wc >> 6 ) & 63 );
			mb[ 5 ] = 0x80 | ( wc & 63 );
		}

		return( 6 );
	}

	return( -1 );
}

