/*-----------------------------------------------------------------------*
 * MBYTE1.CAS
 *
 * single byte "multi-byte" locale only conversion functions
 *
 * function(s)
 *        mblen     - determines number of bytes in multibyte character
 *        mbtowc    - converts multibyte character to wide character
 *        wctomb    - converts wide character to multibyte character
 *        mbstowcs  - converts a multibyte string to a wide character string
 *        wcstombs  - converts a wide character string to a multibyte string
 *
 *-----------------------------------------------------------------------*/

/*
 *      C/C++ Run Time Library - Version 6.5
 *
 *      Copyright (c) 1987, 1994 by Borland International
 *      All Rights Reserved.
 *
 */


#pragma  inline
#include <asmrules.h>
#include <stdlib.h>

#if ( sizeof( wchar_t ) == 1 )
#error *** size of wchar_t is incorrect ***
#endif

/*
        single byte "multi-byte" locale code set

        ASSUMPTION: multi-byte char size is sizeof( char )
*/


int _CType _FARFUNC mblen( const char *s, size_t n )
{

        if ( s == NULL )
                return( 0 );

        if ( *s == 0 )
                return( 0 );

        if ( n == 0 )
                return( -1 );

        return( sizeof( char ) );
}

/*
        single byte "multi-byte" locale code set

        ASSUMPTION: each char is zero extended into wchar_t
*/

int _CType _FARFUNC mbtowc( wchar_t *pwc, const char *s, size_t n )

{
        /* return "no state-dependent encodings" */
        if ( s == NULL )
                return( 0 );

        if ( n == 0 )
                return( -1 );

        if ( pwc != NULL )
                /* zero extend */
                *pwc = (wchar_t) *s;

        if ( *s == 0 )
                return( 0 );

        return( sizeof( char ) );
}

/*
        single byte "multi-byte" locale code set

        ASSUMPTION: each wchar_t has zero in high byte
*/

int _CType _FARFUNC wctomb( char *s, wchar_t wc )

{
        /* return "no state-dependent encodings" */
        if ( s == NULL )
                return( 0 );

        /* is valid wide char value: must be zero extended */
        if ( ( wc & 0xff00 ) != 0 )
                return( -1 );

        /* take only lower byte value */
        *s = (char) wc;

        return( sizeof( char ) );

}

size_t _CType _FARFUNC mbstowcs( wchar_t _FAR *pwcs, const char _FAR *s, size_t n )
{

#if  defined(__LARGE__) || defined(__COMPACT__)

asm     push    ds

#endif

        /* load multi-byte string pointer */
asm     LDS_    si, [ DPTR_( s ) ]

        /* load wide char string pointer */
asm     LES_    di, [ DPTR_( pwcs ) ]

        /* load max length */
asm     mov     cx, [ n ]
asm     mov     dx, cx

asm             cld
asm             xor     ah, ah

mb_conversion_loop:

asm             lodsb

asm             stosw

                        /* end of string? but don't count zero string terminator */
asm             test    al, al
asm             jz      mb_conversion_exit

                        /* count bytes converted */
asm             dec     cx

                        /* max len of string? */
asm             test            cx, cx
asm             jnz     short mb_conversion_loop

mb_conversion_exit:

asm     mov     ax, dx
asm     sub     ax, cx

#if  defined(__LARGE__) || defined(__COMPACT__)
asm     pop     ds
#endif

                return( _AX );
}


size_t _CType _FARFUNC wcstombs(char _FAR *s, const wchar_t _FAR *pwcs, size_t n)
{

#if  defined(__LARGE__) || defined(__COMPACT__)

asm     push    ds

#endif

        /* load multi-byte string pointer */
asm     LDS_    si, [ DPTR_( pwcs ) ]

        /* load wide char string pointer */
asm     LES_    di, [ DPTR_( s ) ]

        /* load max length */
asm     mov     cx, [ n ]
asm     mov     dx, cx

asm             cld

wc_conversion_loop:

                        /* load wide char */
asm             lodsw

                        /* check ah is zero */
asm             test    ah, ah
asm             jnz     wc_invalid

                        /* store multi-byte char */
asm             stosb

                        /* end of string? but don't count zero string terminator */
asm             test    al, al
asm             jz      wc_conversion_exit

                        /* count bytes converted */
asm             dec     cx

                        /* max len? */
asm             test            cx, cx
asm             jnz     short wc_conversion_loop

wc_conversion_exit:

asm             mov     ax, dx
asm             sub     ax, cx

#if  defined(__LARGE__) || defined(__COMPACT__)
asm             pop     ds
#endif

                        return( _AX );

wc_invalid:

#if  defined(__LARGE__) || defined(__COMPACT__)
asm             pop     ds
#endif

asm             mov     ax, -1

                        return( _AX );
}

