⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbctype.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:

/***
*setSBCS() - Set MB code page to SBCS.
*
*Purpose:
*           Set MB code page to SBCS.
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/

static void setSBCS (pthreadmbcinfo ptmbci)
{
    int i;

    /* set for single-byte code page */
    for (i = 0; i < NUM_CHARS; i++)
        ptmbci->mbctype[i] = 0;

    /* code page has changed, set global flag */
    ptmbci->mbcodepage = 0;

    /* clear flag to indicate single-byte code */
    ptmbci->ismbcodepage = 0;

    ptmbci->mblcid = 0;

    for (i = 0; i < NUM_ULINFO; i++)
        ptmbci->mbulinfo[i] = 0;

    for ( i = 0 ; i < 257 ; i++ )
        ptmbci->mbctype[i] = __initialmbcinfo.mbctype[i];

    for ( i = 0 ; i < 256 ; i++ )
        ptmbci->mbcasemap[i] = __initialmbcinfo.mbcasemap[i];
}

/***
*setSBUpLow() - Set single byte upper/lower mappings
*
*Purpose:
*           Set single byte mapping for tolower/toupper.
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/

static void setSBUpLow (pthreadmbcinfo ptmbci)
{
    BYTE *  pbPair;
    UINT    ich;
    CPINFO  cpinfo;
    UCHAR   sbVector[256];
    UCHAR   upVector[256];
    UCHAR   lowVector[256];
    USHORT  wVector[256];

    //    test if codepage exists
    if (GetCPInfo(ptmbci->mbcodepage, &cpinfo) != 0)
    {
        //  if so, create vector 0-255
        for (ich = 0; ich < 256; ich++)
            sbVector[ich] = (UCHAR) ich;

        //  set byte 0 and any leading byte value to non-alpha char ' '
        sbVector[0] = (UCHAR)' ';
        for (pbPair = &cpinfo.LeadByte[0]; *pbPair; pbPair += 2)
            for (ich = *pbPair; ich <= *(pbPair + 1); ich++)
                sbVector[ich] = (UCHAR)' ';

        //  get char type for character vector

        __crtGetStringTypeA(NULL, CT_CTYPE1, (LPCSTR)sbVector, 256, wVector,
                            ptmbci->mbcodepage, ptmbci->mblcid, FALSE);

        //  get lower case mappings for character vector

        __crtLCMapStringA(NULL, ptmbci->mblcid, LCMAP_LOWERCASE, (LPCSTR)sbVector, 256,
                                    (LPSTR)lowVector, 256, ptmbci->mbcodepage, FALSE);

        //  get upper case mappings for character vector

        __crtLCMapStringA(NULL, ptmbci->mblcid, LCMAP_UPPERCASE, (LPCSTR)sbVector, 256,
                                    (LPSTR)upVector, 256, ptmbci->mbcodepage, FALSE);

        //  set _SBUP, _SBLOW in ptmbci->mbctype if type is upper. lower
        //  set mapping array with lower or upper mapping value

        for (ich = 0; ich < 256; ich++)
            if (wVector[ich] & _UPPER)
            {
                ptmbci->mbctype[ich + 1] |= _SBUP;
                ptmbci->mbcasemap[ich] = lowVector[ich];
            }
            else if (wVector[ich] & _LOWER)
            {
                ptmbci->mbctype[ich + 1] |= _SBLOW;
                ptmbci->mbcasemap[ich] = upVector[ich];
            }
            else
                ptmbci->mbcasemap[ich] = 0;
    }
    else
    {
        //  if no codepage, set 'A'-'Z' as upper, 'a'-'z' as lower

        for (ich = 0; ich < 256; ich++)
            if (ich >= (UINT)'A' && ich <= (UINT)'Z')
            {
                ptmbci->mbctype[ich + 1] |= _SBUP;
                ptmbci->mbcasemap[ich] = ich + ('a' - 'A');
            }
            else if (ich >= (UINT)'a' && ich <= (UINT)'z')
            {
                ptmbci->mbctype[ich + 1] |= _SBLOW;
                ptmbci->mbcasemap[ich] = ich - ('a' - 'A');
            }
            else
                ptmbci->mbcasemap[ich] = 0;
    }
}

/***
*__updatetmbcinfo() - refresh the thread's mbc info
*
*Purpose:
*       Update the current thread's reference to the multibyte character
*       information to match the current global mbc info. Decrement the
*       reference on the old mbc information struct and if this count is now
*       zero (so that no threads are using it), free it.
*
*Entry:
*
*Exit:
*       _getptd()->ptmbcinfo == __ptmbcinfo
*
*Exceptions:
*
*******************************************************************************/

extern "C" pthreadmbcinfo __cdecl __updatetmbcinfo(void)
{
        pthreadmbcinfo ptmbci;

        _ptiddata ptd = _getptd();
        if (!(ptd->_ownlocale & __globallocalestatus)|| !ptd->ptlocinfo) {
        _mlock(_MB_CP_LOCK);

        __try
        {

            if ( (ptmbci = ptd->ptmbcinfo) != __ptmbcinfo )
            {
                /*
                 * Decrement the reference count in the old mbc info structure
                 * and free it, if necessary
                 */
                    if ( (ptmbci != NULL) && (InterlockedDecrement((volatile LONG *)&(ptmbci->refcount)) == 0) && ptmbci != &__initialmbcinfo )
                {
                    /*
                     * Free it
                     */
                    _free_crt(ptmbci);
                }

                /*
                 * Point to the current mbc info structure and increment its
                 * reference count.
                 */
                ptmbci = ptd->ptmbcinfo = __ptmbcinfo;
                    InterlockedIncrement((volatile LONG *)&(ptmbci->refcount));
            }
        }
        __finally
        {
            _munlock(_MB_CP_LOCK);
        }
        } else {
            ptmbci = ptd->ptmbcinfo;
        }

        if(!ptmbci)
        {
            _amsg_exit(_RT_LOCALE);
        }

        return ptmbci;
}

/***
*_setmbcp() - Set MBC data based on code page
*
*Purpose:
*       Init MBC character type tables based on code page number. If
*       given code page is supported, load that code page info into
*       mbctype table. If not, query OS to find the information,
*       otherwise set up table with single byte info.
*
*       Multithread Notes: First, allocate an mbc information struct. Set the
*       mbc info in the static vars and arrays as does the single-thread
*       version. Then, copy this info into the new allocated struct and set
*       the current mbc info pointer (__ptmbcinfo) to point to it.
*
*Entry:
*       codepage - code page to initialize MBC table
*           _MB_CP_OEM = use system OEM code page
*           _MB_CP_ANSI = use system ANSI code page
*           _MB_CP_SBCS = set to single byte 'code page'
*
*Exit:
*        0 = Success
*       -1 = Error, code page not changed.
*
*Exceptions:
*
*******************************************************************************/

extern "C" int __cdecl _setmbcp (int codepage)
{
    int retcode = -1;           /* initialize to failure */
    pthreadmbcinfo ptmbci;
    int i;

    _ptiddata ptd = _getptd();

    __updatetmbcinfo();
    ptmbci = ptd->ptmbcinfo;

    codepage = getSystemCP(codepage);

    if ( codepage != ptmbci->mbcodepage )
    {
        /*
         * Always allocate space so that we don't have to take lock
         * for any update.
         */
        ptmbci = (pthreadmbcinfo)_malloc_crt( sizeof(threadmbcinfo) );

        if (ptmbci != NULL)
        {
            *ptmbci = *(ptd->ptmbcinfo);
            /*
             * Note that refcount for this structure is just one so
             * update the refcount.
             */

                        /*
             * Note that the refcount is set to zero because we don't count this
             * refcount as we won't be calling InterlockedDecrement for this when
             * the variable goes out of scope.
             */
            ptmbci->refcount = 0;

            /*
             * Install the codepage and copy the info into the struct
             */
            if ( (retcode = _setmbcp_nolock(codepage, ptmbci)) == 0)
            {
                if (InterlockedDecrement((volatile LONG *)&ptd->ptmbcinfo->refcount) == 0 && ptd->ptmbcinfo != &__initialmbcinfo)
                    _free_crt(ptd->ptmbcinfo);
                /*
                 * Assign and increment the refcount of this structure.
                 */
                ptd->ptmbcinfo = ptmbci;
                InterlockedIncrement((volatile LONG *)&(ptd->ptmbcinfo->refcount));
                if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT) &&
                        !(__globallocalestatus & _GLOBAL_LOCALE_BIT)) {

                    _mlock(_MB_CP_LOCK);
                    __try
                    {
                        /*
                         * Fill in the mbc info struct
                         */
                        __mbcodepage = ptmbci->mbcodepage;
                        __ismbcodepage = ptmbci->ismbcodepage;
                        __mblcid = ptmbci->mblcid;
                        for ( i = 0 ; i < 5 ; i++ )
                            __mbulinfo[i] = ptmbci->mbulinfo[i];
                        for ( i = 0 ; i < 257 ; i++ )
                            _mbctype[i] = ptmbci->mbctype[i];
                        for ( i = 0 ; i < 256 ; i++ )
                            _mbcasemap[i] = ptmbci->mbcasemap[i];

                        if (InterlockedDecrement((volatile LONG *)&__ptmbcinfo->refcount) == 0 && __ptmbcinfo != &__initialmbcinfo)
                            _free_crt(__ptmbcinfo);
                        /*
                         * Update __ptmbcinfo
                         */
                        __ptmbcinfo = ptmbci;
                        InterlockedIncrement((volatile LONG *)&ptmbci->refcount);
                    }
                    __finally
                    {
                        _munlock(_MB_CP_LOCK);
                    }
                }
            }
            else if (retcode == -1)
            {
                /*
                 * Free up the newly malloc-ed struct (note: a free of
                 * NULL is legal)
                 */
                if (ptmbci != &__initialmbcinfo)
                    _free_crt(ptmbci);
                errno = EINVAL;
                /* note that if malloc fails, it sets errno to ENOMEM already */
            }
        }

    }
    else
        /*
         * Not a new codepage after all. Nothing to do but return
         * success.
         */
        retcode = 0;

#pragma warning(disable:4390)
    if ( (retcode == -1) && (__ptmbcinfo == NULL) )
        /*
         * Fatal error!
         */
        ;

    return retcode;
}

extern "C" int __cdecl _setmbcp_nolock(int codepage, pthreadmbcinfo ptmbci)
{
        unsigned int icp;
        unsigned int irg;
        unsigned int ich;
        unsigned char *rgptr;
        CPINFO cpinfo;

        codepage = getSystemCP(codepage);

        /* user wants 'single-byte' MB code page */
        if (codepage == _MB_CP_SBCS)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -