jdk/src/windows/npt/utf_md.c
author ohair
Tue, 25 May 2010 15:58:33 -0700
changeset 5506 202f599c92aa
parent 2 90ce3da70b43
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy, weijun

/*
 * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "utf.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

/*
 * Initialize all utf processing.
 */
struct UtfInst * JNICALL
utfInitialize(char *options)
{
    struct UtfInst *ui;
    LANGID langID;
    LCID localeID;
    TCHAR strCodePage[7];       // ANSI code page id

    ui = (struct UtfInst*)calloc(sizeof(struct UtfInst), 1);

    /*
     * Get the code page for this locale
     */
    langID = LANGIDFROMLCID(GetUserDefaultLCID());
    localeID = MAKELCID(langID, SORT_DEFAULT);
    if (GetLocaleInfo(localeID, LOCALE_IDEFAULTANSICODEPAGE,
                      strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 ) {
        ui->platformCodePage = atoi(strCodePage);
    } else {
        ui->platformCodePage = GetACP();
    }
    return ui;
}

/*
 * Terminate all utf processing
 */
void JNICALL
utfTerminate(struct UtfInst *ui, char *options)
{
    (void)free(ui);
}

/*
 * Get wide string  (assumes len>0)
 */
static WCHAR*
getWideString(UINT codePage, char* str, int len, int *pwlen)
{
    int wlen;
    WCHAR* wstr;

    /* Convert the string to WIDE string */
    wlen = MultiByteToWideChar(codePage, 0, str, len, NULL, 0);
    *pwlen = wlen;
    if (wlen <= 0) {
        UTF_ERROR(("Can't get WIDE string length"));
        return NULL;
    }
    wstr = (WCHAR*)malloc(wlen * sizeof(WCHAR));
    if (wstr == NULL) {
        UTF_ERROR(("Can't malloc() any space"));
        return NULL;
    }
    if (MultiByteToWideChar(codePage, 0, str, len, wstr, wlen) == 0) {
        UTF_ERROR(("Can't get WIDE string"));
        return NULL;
    }
    return wstr;
}

/*
 * Convert UTF-8 to a platform string
 */
int JNICALL
utf8ToPlatform(struct UtfInst *ui, jbyte *utf8, int len, char* output, int outputMaxLen)
{
    int wlen;
    int plen;
    WCHAR* wstr;

    /* Negative length is an error */
    if ( len < 0 ) {
        return -1;
    }

    /* Zero length is ok, but we don't need to do much */
    if ( len == 0 ) {
        output[0] = 0;
        return 0;
    }

    /* Get WIDE string version (assumes len>0) */
    wstr = getWideString(CP_UTF8, (char*)utf8, len, &wlen);
    if ( wstr == NULL ) {
        return -1;
    }

    /* Convert WIDE string to MultiByte string */
    plen = WideCharToMultiByte(ui->platformCodePage, 0, wstr, wlen,
                               output, outputMaxLen, NULL, NULL);
    free(wstr);
    if (plen <= 0) {
        UTF_ERROR(("Can't convert WIDE string to multi-byte"));
        return -1;
    }
    output[plen] = '\0';
    return plen;
}

/*
 * Convert Platform Encoding to UTF-8.
 */
int JNICALL
utf8FromPlatform(struct UtfInst *ui, char *str, int len, jbyte *output, int outputMaxLen)
{
    int wlen;
    int plen;
    WCHAR* wstr;

    /* Negative length is an error */
    if ( len < 0 ) {
        return -1;
    }

    /* Zero length is ok, but we don't need to do much */
    if ( len == 0 ) {
        output[0] = 0;
        return 0;
    }

    /* Get WIDE string version (assumes len>0) */
    wstr = getWideString(ui->platformCodePage, str, len, &wlen);
    if ( wstr == NULL ) {
        return -1;
    }

    /* Convert WIDE string to UTF-8 string */
    plen = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen,
                               (char*)output, outputMaxLen, NULL, NULL);
    free(wstr);
    if (plen <= 0) {
        UTF_ERROR(("Can't convert WIDE string to multi-byte"));
        return -1;
    }
    output[plen] = '\0';
    return plen;
}