Ignore:
Timestamp:
Apr 3, 2001, 4:10:48 PM (24 years ago)
Author:
sandervl
Message:

codepage updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/codepage.cpp

    r5424 r5451  
    1 /* $Id: codepage.cpp,v 1.9 2001-04-01 12:33:10 sandervl Exp $
    2 **
    3 ** Module   :CODEPAGE.CPP
    4 ** Abstract :
    5 **
    6 ** Copyright (C) Vit Timchishin
    7 **
    8 ** Log: Wed  22/12/1999 Created
    9 **
    10 */
    11 
    12 #include <odin.h>
    13 #include <odinwrap.h>
    14 #include <os2win.h>
    15 #include "oslibdos.h"
    16 //#include "profile.h"
     1/*
     2 * Code page functions
     3 *
     4 * Based on Wine code (memory\codepage.c)
     5 *
     6 * Copyright 2000 Alexandre Julliard
     7 *
     8 * Project Odin Software License can be found in LICENSE.TXT
     9 *
     10 */
     11
     12#include <assert.h>
     13#include <stdio.h>
     14#include <stdlib.h>
     15#include <string.h>
     16
     17#include "winbase.h"
     18#include "winerror.h"
     19#include "winnls.h"
     20#include "wine/unicode.h"
     21#include "debugtools.h"
     22
     23#ifdef __WIN32OS2__
    1724#include <options.h>
    1825#include "codepage.h"
     
    2027#define DBG_LOCALLOG    DBG_codepage
    2128#include "dbglocal.h"
    22 
    23 static UconvObject DisplayUconv = NULL;
    24 static UconvObject WindowsUconv = NULL;
    25 
    26 static ULONG windowCodePage = -1;
    27 static ULONG displayCodePage = -1;
    28 
     29#endif
     30
     31DEFAULT_DEBUG_CHANNEL(string);
     32
     33/* current code pages */
     34static const union cptable *ansi_cptable;
     35static const union cptable *oem_cptable;
     36static const union cptable *mac_cptable;
     37
     38/* retrieve a code page table from the locale info */
     39static const union cptable *get_locale_cp( LCID lcid, LCTYPE type )
     40{
     41    const union cptable *table = NULL;
     42    char buf[32];
     43
     44    if (GetLocaleInfoA( lcid, type, buf, sizeof(buf) )) table = cp_get_table( atoi(buf) );
     45    return table;
     46}
     47
     48/* setup default codepage info before we can get at the locale stuff */
     49static void init_codepages(void)
     50{
     51    ansi_cptable = cp_get_table( 1252 );
     52    oem_cptable  = cp_get_table( 437 );
     53    mac_cptable  = cp_get_table( 10000 );
     54    assert( ansi_cptable );
     55    assert( oem_cptable );
     56    assert( mac_cptable );
     57}
     58
     59/* find the table for a given codepage, handling CP_ACP etc. pseudo-codepages */
     60static const union cptable *get_codepage_table( unsigned int codepage )
     61{
     62    const union cptable *ret = NULL;
     63
     64    if (!ansi_cptable) init_codepages();
     65
     66    switch(codepage)
     67    {
     68    case CP_ACP:        return ansi_cptable;
     69    case CP_OEMCP:      return oem_cptable;
     70    case CP_MACCP:      return mac_cptable;
     71    case CP_THREAD_ACP: return get_locale_cp( GetThreadLocale(), LOCALE_IDEFAULTANSICODEPAGE );
     72    case CP_UTF7:
     73    case CP_UTF8:
     74        break;
     75    default:
     76        if (codepage == ansi_cptable->info.codepage) return ansi_cptable;
     77        if (codepage == oem_cptable->info.codepage) return oem_cptable;
     78        if (codepage == mac_cptable->info.codepage) return mac_cptable;
     79        ret = cp_get_table( codepage );
     80        break;
     81    }
     82    return ret;
     83}
     84
     85/* initialize default code pages from locale info */
     86/* FIXME: should be done in init_codepages, but it can't right now */
     87/* since it needs KERNEL32 to be loaded for the locale info. */
     88void CODEPAGE_Init(void)
     89{
     90    const union cptable *table;
     91    LCID lcid = GetUserDefaultLCID();
     92
     93    if (!ansi_cptable) init_codepages();  /* just in case */
     94   
     95    if ((table = get_locale_cp( lcid, LOCALE_IDEFAULTANSICODEPAGE ))) ansi_cptable = table;
     96    if ((table = get_locale_cp( lcid, LOCALE_IDEFAULTMACCODEPAGE ))) mac_cptable = table;
     97    if ((table = get_locale_cp( lcid, LOCALE_IDEFAULTCODEPAGE ))) oem_cptable = table;
     98
     99    TRACE( "ansi=%03d oem=%03d mac=%03d\n", ansi_cptable->info.codepage,
     100           oem_cptable->info.codepage, mac_cptable->info.codepage );
     101}
     102
     103#ifdef __WIN32OS2__
    29104ULONG GetDisplayCodepage()
    30105{
    31     if(displayCodePage == -1) {
    32         //default codepage is 1252 (same as default Windows codepage)
    33         displayCodePage = PROFILE_GetOdinIniInt(CODEPAGE_SECTION, "DISPLAY", 1252);
    34 //      displayCodePage = PROFILE_GetOdinIniInt(CODEPAGE_SECTION, "DISPLAY", 0);
    35     }
    36     return displayCodePage;
     106    if (!ansi_cptable) CODEPAGE_Init();
     107
     108    return oem_cptable->info.codepage;
    37109}
    38110
    39111ULONG GetWindowsCodepage()
    40112{
    41     if(windowCodePage == -1) {
    42         //default codepage is 1252 (same as default Windows codepage)
    43         windowCodePage = PROFILE_GetOdinIniInt(CODEPAGE_SECTION, "WINDOWS", 1252);
    44 //      windowCodePage = PROFILE_GetOdinIniInt(CODEPAGE_SECTION, "WINDOWS", 0);
    45     }
    46     return windowCodePage;
    47 }
    48 
    49 UINT WIN32API GetACP()
    50 {
    51     UINT codepage = GetDisplayCodepage();
    52     dprintf(("GetACP -> %d", codepage));
    53 
    54     return(codepage);
     113    if (!ansi_cptable) CODEPAGE_Init();
     114
     115    return oem_cptable->info.codepage;
    55116}
    56117
     
    71132}
    72133
     134static UconvObject DisplayUconv = NULL;
     135static UconvObject WindowsUconv = NULL;
     136
    73137UconvObject GetDisplayUconvObject()
    74138{
     
    87151}
    88152
     153#endif
     154
     155/******************************************************************************
     156 *              GetACP   (KERNEL32)
     157 *
     158 * RETURNS
     159 *    Current ANSI code-page identifier, default if no current defined
     160 */
     161UINT WINAPI GetACP(void)
     162{
     163    if (!ansi_cptable) init_codepages();
     164#ifdef __WIN32OS2__
     165    dprintf(("GetACP %d", ansi_cptable->info.codepage));
     166#endif
     167    return ansi_cptable->info.codepage;
     168}
     169
     170
     171/***********************************************************************
     172 *              GetOEMCP   (KERNEL32)
     173 */
     174UINT WINAPI GetOEMCP(void)
     175{
     176    if (!oem_cptable) init_codepages();
     177#ifdef __WIN32OS2__
     178    dprintf(("GetOEMCP %d", oem_cptable->info.codepage));
     179#endif
     180    return oem_cptable->info.codepage;
     181}
     182
     183
     184/***********************************************************************
     185 *           IsValidCodePage   (KERNEL32)
     186 */
     187BOOL WINAPI IsValidCodePage( UINT codepage )
     188{
     189#ifdef __WIN32OS2__
     190    dprintf(("IsValidCodePage %d", codepage));
     191#endif
     192    return cp_get_table( codepage ) != NULL;
     193}
     194
     195
     196/***********************************************************************
     197 *           IsDBCSLeadByteEx   (KERNEL32)
     198 */
     199BOOL WINAPI IsDBCSLeadByteEx( UINT codepage, BYTE testchar )
     200{
     201#ifdef __WIN32OS2__
     202    dprintf2(("IsDBCSLeadByteEx %d %x", codepage, testchar));
     203#endif
     204
     205    const union cptable *table = get_codepage_table( codepage );
     206    return table && is_dbcs_leadbyte( table, testchar );
     207}
     208
     209
     210/***********************************************************************
     211 *           IsDBCSLeadByte   (KERNEL32)
     212 */
     213BOOL WINAPI IsDBCSLeadByte( BYTE testchar )
     214{
     215    if (!ansi_cptable) init_codepages();
     216    return is_dbcs_leadbyte( ansi_cptable, testchar );
     217}
     218
     219
     220/***********************************************************************
     221 *           GetCPInfo   (KERNEL32)
     222 */
     223BOOL WINAPI GetCPInfo( UINT codepage, LPCPINFO cpinfo )
     224{
     225    const union cptable *table = get_codepage_table( codepage );
     226
     227#ifdef __WIN32OS2__
     228    dprintf(("GetCPInfo %d %x", codepage, cpinfo));
     229#endif
     230
     231    if (!table)
     232    {
     233        SetLastError( ERROR_INVALID_PARAMETER );
     234        return FALSE;
     235    }
     236    if (table->info.def_char & 0xff00)
     237    {
     238        cpinfo->DefaultChar[0] = table->info.def_char & 0xff00;
     239        cpinfo->DefaultChar[1] = table->info.def_char & 0x00ff;
     240    }
     241    else
     242    {
     243        cpinfo->DefaultChar[0] = table->info.def_char & 0xff;
     244        cpinfo->DefaultChar[1] = 0;
     245    }
     246    if ((cpinfo->MaxCharSize = table->info.char_size) == 2)
     247        memcpy( cpinfo->LeadByte, table->dbcs.lead_bytes, sizeof(cpinfo->LeadByte) );
     248    else
     249        cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
     250
     251    return TRUE;
     252}
     253
     254
     255/***********************************************************************
     256 *              EnumSystemCodePagesA   (KERNEL32)
     257 */
     258BOOL WINAPI EnumSystemCodePagesA( CODEPAGE_ENUMPROCA lpfnCodePageEnum, DWORD flags )
     259{
     260    const union cptable *table;
     261    char buffer[10];
     262    int index = 0;
     263
     264#ifdef __WIN32OS2__
     265    dprintf(("EnumSystemCodePagesA %x %x", lpfnCodePageEnum, flags));
     266#endif
     267
     268    for (;;)
     269    {
     270        if (!(table = cp_enum_table( index++ ))) break;
     271        sprintf( buffer, "%d", table->info.codepage );
     272        if (!lpfnCodePageEnum( buffer )) break;
     273    }
     274    return TRUE;
     275}
     276
     277
     278/***********************************************************************
     279 *              EnumSystemCodePagesW   (KERNEL32)
     280 */
     281BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum, DWORD flags )
     282{
     283    const union cptable *table;
     284    WCHAR buffer[10], *p;
     285    int page, index = 0;
     286
     287#ifdef __WIN32OS2__
     288    dprintf(("EnumSystemCodePagesW %x %x", lpfnCodePageEnum, flags));
     289#endif
     290
     291    for (;;)
     292    {
     293        if (!(table = cp_enum_table( index++ ))) break;
     294        p = buffer + sizeof(buffer)/sizeof(WCHAR);
     295        *--p = 0;
     296        page = table->info.codepage;
     297        do
     298        {
     299            *--p = '0' + (page % 10);
     300            page /= 10;
     301        } while( page );
     302        if (!lpfnCodePageEnum( p )) break;
     303    }
     304    return TRUE;
     305}
     306
     307
     308/***********************************************************************
     309 *              MultiByteToWideChar   (KERNEL32)
     310 *
     311 * PARAMS
     312 *   page [in]    Codepage character set to convert from
     313 *   flags [in]   Character mapping flags
     314 *   src [in]     Source string buffer
     315 *   srclen [in]  Length of source string buffer
     316 *   dst [in]     Destination buffer
     317 *   dstlen [in]  Length of destination buffer
     318 *
     319 * NOTES
     320 *   The returned length includes the null terminator character.
     321 *
     322 * RETURNS
     323 *   Success: If dstlen > 0, number of characters written to destination
     324 *            buffer.  If dstlen == 0, number of characters needed to do
     325 *            conversion.
     326 *   Failure: 0. Occurs if not enough space is available.
     327 *
     328 * ERRORS
     329 *   ERROR_INSUFFICIENT_BUFFER
     330 *   ERROR_INVALID_PARAMETER
     331 *   ERROR_NO_UNICODE_TRANSLATION
     332 *
     333 */
     334INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
     335                                LPWSTR dst, INT dstlen )
     336{
     337    const union cptable *table;
     338    int ret;
     339
     340#ifdef __WIN32OS2__
     341    dprintf2(("MultiByteToWideChar %d %x %x %d %x %d", page, flags, src, srclen, dst, dstlen));
     342#endif
     343
     344    if (!src || (!dst && dstlen))
     345    {
     346        SetLastError( ERROR_INVALID_PARAMETER );
     347        return 0;
     348    }
     349
     350    if (srclen == -1) srclen = strlen(src) + 1;
     351
     352    if (flags & MB_USEGLYPHCHARS) FIXME("MB_USEGLYPHCHARS not supported\n");
     353
     354    switch(page)
     355    {
     356    case CP_UTF7:
     357        FIXME("UTF not supported\n");
     358        SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
     359        return 0;
     360    case CP_UTF8:
     361        ret = utf8_mbstowcs( flags, src, srclen, dst, dstlen );
     362        break;
     363    default:
     364        if (!(table = get_codepage_table( page )))
     365        {
     366            SetLastError( ERROR_INVALID_PARAMETER );
     367            return 0;
     368        }
     369        ret = cp_mbstowcs( table, flags, src, srclen, dst, dstlen );
     370        break;
     371    }
     372
     373    if (ret < 0)
     374    {
     375        switch(ret)
     376        {
     377        case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
     378        case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
     379        }
     380        ret = 0;
     381    }
     382    return ret;
     383}
     384
     385
     386/***********************************************************************
     387 *              WideCharToMultiByte   (KERNEL32)
     388 *
     389 * PARAMS
     390 *   page [in]    Codepage character set to convert to
     391 *   flags [in]   Character mapping flags
     392 *   src [in]     Source string buffer
     393 *   srclen [in]  Length of source string buffer
     394 *   dst [in]     Destination buffer
     395 *   dstlen [in]  Length of destination buffer
     396 *   defchar [in] Default character to use for conversion if no exact
     397 *                  conversion can be made
     398 *   used [out]   Set if default character was used in the conversion
     399 *
     400 * NOTES
     401 *   The returned length includes the null terminator character.
     402 *
     403 * RETURNS
     404 *   Success: If dstlen > 0, number of characters written to destination
     405 *            buffer.  If dstlen == 0, number of characters needed to do
     406 *            conversion.
     407 *   Failure: 0. Occurs if not enough space is available.
     408 *
     409 * ERRORS
     410 *   ERROR_INSUFFICIENT_BUFFER
     411 *   ERROR_INVALID_PARAMETER
     412 */
     413INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
     414                                LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
     415{
     416    const union cptable *table;
     417    int ret, used_tmp;
     418
     419#ifdef __WIN32OS2__
     420    dprintf2(("WideCharToMultiByte %d %x %x %d %x %d", page, flags, src, srclen, dst, dstlen));
     421#endif
     422
     423    if (!src || (!dst && dstlen))
     424    {
     425        SetLastError( ERROR_INVALID_PARAMETER );
     426        return 0;
     427    }
     428
     429    if (srclen == -1) srclen = strlenW(src) + 1;
     430
     431    switch(page)
     432    {
     433    case CP_UTF7:
     434        FIXME("UTF-7 not supported\n");
     435        SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
     436        return 0;
     437    case CP_UTF8:
     438        ret = utf8_wcstombs( src, srclen, dst, dstlen );
     439        break;
     440    default:
     441        if (!(table = get_codepage_table( page )))
     442        {
     443            SetLastError( ERROR_INVALID_PARAMETER );
     444            return 0;
     445        }
     446        ret = cp_wcstombs( table, flags, src, srclen, dst, dstlen,
     447                           defchar, used ? &used_tmp : NULL );
     448        if (used) *used = used_tmp;
     449        break;
     450    }
     451
     452    if (ret == -1)
     453    {
     454        SetLastError( ERROR_INSUFFICIENT_BUFFER );
     455        ret = 0;
     456    }
     457    return ret;
     458}
     459
     460
     461/******************************************************************************
     462 *              GetStringTypeW   (KERNEL32)
     463 *
     464 */
     465BOOL WINAPI GetStringTypeW( DWORD type, LPCWSTR src, INT count, LPWORD chartype )
     466{
     467#ifdef __WIN32OS2__
     468    dprintf(("GetStringTypeW %x %x %d %x", type, src, count, chartype));
     469#endif
     470
     471    if (count == -1) count = strlenW(src) + 1;
     472    switch(type)
     473    {
     474    case CT_CTYPE1:
     475        while (count--) *chartype++ = get_char_typeW( *src++ ) & 0xfff;
     476        break;
     477    case CT_CTYPE2:
     478        while (count--) *chartype++ = get_char_typeW( *src++ ) >> 12;
     479        break;
     480    case CT_CTYPE3:
     481        FIXME("CT_CTYPE3 not supported.\n");
     482    default:
     483        SetLastError( ERROR_INVALID_PARAMETER );
     484        return FALSE;
     485    }
     486    return TRUE;
     487}
     488
     489
     490/******************************************************************************
     491 *              GetStringTypeExW   (KERNEL32)
     492 */
     493BOOL WINAPI GetStringTypeExW( LCID locale, DWORD type, LPCWSTR src, INT count, LPWORD chartype )
     494{
     495    /* locale is ignored for Unicode */
     496    return GetStringTypeW( type, src, count, chartype );
     497}
Note: See TracChangeset for help on using the changeset viewer.