mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
654 lines
15 KiB
C
654 lines
15 KiB
C
/*
|
|
* @(#) $(JCGO)/native/jcgojnu.c --
|
|
* a part of the JCGO native layer library (native layer API implementation).
|
|
**
|
|
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
|
|
* Copyright (C) 2001-2013 Ivan Maidanski <ivmai@mail.ru>
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/*
|
|
* Used control macros: JCGO_DOWCSTOMBS, JCGO_HUGEARR, JCGO_NOJNI,
|
|
* JCGO_SYSWCHAR, JCGO_THREADS, JCGO_UTFWCTOMB, JCGO_WMAIN.
|
|
* Macros for tuning: JNUBIGEXPORT.
|
|
*/
|
|
|
|
/*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
**
|
|
* This software 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 (GPL) for more details.
|
|
**
|
|
* Linking this library statically or dynamically with other modules is
|
|
* making a combined work based on this library. Thus, the terms and
|
|
* conditions of the GNU General Public License cover the whole
|
|
* combination.
|
|
**
|
|
* As a special exception, the copyright holders of this library give you
|
|
* permission to link this library with independent modules to produce an
|
|
* executable, regardless of the license terms of these independent
|
|
* modules, and to copy and distribute the resulting executable under
|
|
* terms of your choice, provided that you also meet, for each linked
|
|
* independent module, the terms and conditions of the license of that
|
|
* module. An independent module is a module which is not derived from
|
|
* or based on this library. If you modify this library, you may extend
|
|
* this exception to your version of the library, but you are not
|
|
* obligated to do so. If you do not wish to do so, delete this
|
|
* exception statement from your version.
|
|
*/
|
|
|
|
#define JCGO_BUILDING_JNU
|
|
#ifdef JCGO_VER
|
|
#include "jcgojnu.h"
|
|
#else
|
|
#include "jcgojnu.h"
|
|
#ifdef JCGO_NOJNI
|
|
#ifndef JCGO_SEPARATED
|
|
#define JCGO_SEPARATED
|
|
#endif
|
|
#include "jcgortl.h"
|
|
jint *JNICALL jcgo_jnuStringLengthPtr( jstring str );
|
|
jchar *JNICALL jcgo_jnuStringChars( jstring str, int *pisbytes );
|
|
jstring JNICALL jcgo_jnuStringCreate( JNIEnv *pJniEnv, jint len );
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef JCGO_VER
|
|
|
|
#ifndef JCGO_UTFWCTOMB
|
|
|
|
/* #include <stdlib.h> */
|
|
/* const int MB_CUR_MAX; */
|
|
|
|
#ifdef JCGO_DOWCSTOMBS
|
|
/* #include <stdlib.h> */
|
|
/* size_t mbstowcs(wchar_t *, const char *, size_t); */
|
|
/* size_t wcstombs(char *, const wchar_t *, size_t); */
|
|
#else
|
|
/* #include <stdlib.h> */
|
|
/* int mbtowc(wchar_t *, const char *, size_t); */
|
|
/* int wctomb(char *, wchar_t); */
|
|
#endif
|
|
|
|
#ifndef _LIMITS_H
|
|
#include <limits.h>
|
|
#endif
|
|
|
|
#ifndef MB_LEN_MAX
|
|
#define MB_LEN_MAX 6
|
|
#endif
|
|
|
|
#endif /* !JCGO_UTFWCTOMB */
|
|
|
|
#ifndef JNUBIGEXPORT
|
|
#define JNUBIGEXPORT JNIEXPORT
|
|
#endif
|
|
|
|
#ifndef JCGO_JNUMSG_BADARG
|
|
#define JCGO_JNUMSG_BADARG "" /* in 'UTF-8' encoding */
|
|
#endif
|
|
|
|
#ifndef JCGO_NOJNI
|
|
#ifndef JCGO_ALLOCSIZE_T
|
|
#ifdef JCGO_HUGEARR
|
|
#define JCGO_ALLOCSIZE_T unsigned long
|
|
#else
|
|
#define JCGO_ALLOCSIZE_T unsigned
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef JCGO_HPTR_MOD
|
|
#ifdef JCGO_HUGEARR
|
|
#define JCGO_HPTR_MOD __huge
|
|
#else
|
|
#define JCGO_HPTR_MOD /* empty */
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef JCGO_JNUNEWSTRING_WBUFSIZE
|
|
#define JCGO_JNUNEWSTRING_WBUFSIZE 128
|
|
#endif
|
|
|
|
#ifdef JCGO_NOJNI
|
|
JNIEXPORT
|
|
#else
|
|
JNUBIGEXPORT
|
|
#endif
|
|
jbyte *JNICALL
|
|
jcgo_JnuGetByteArrayElemsRegion( JNIEnv *pJniEnv, jbyteArray arr, jint offset,
|
|
jint len )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
JCGO_UNUSED_VAR(len);
|
|
return (jbyte *)&JCGO_ARR_INTERNALACC(jbyte, (jbyteArr)arr, offset);
|
|
#else
|
|
jbyte *bytes = (*pJniEnv)->GetByteArrayElements(pJniEnv, arr, NULL);
|
|
if (bytes == NULL)
|
|
return NULL;
|
|
if ((offset | len) < 0 ||
|
|
(*pJniEnv)->GetArrayLength(pJniEnv, (jarray)arr) - offset < len)
|
|
{
|
|
(*pJniEnv)->FatalError(pJniEnv, JCGO_JNUMSG_BADARG);
|
|
return NULL;
|
|
}
|
|
return (jbyte *)((jbyte JCGO_HPTR_MOD *)bytes + (JCGO_ALLOCSIZE_T)offset);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
jcgo_JnuReleaseByteArrayElemsRegion( JNIEnv *pJniEnv, jbyteArray arr,
|
|
jbyte *bytes, jint offset )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
JCGO_UNUSED_VAR(arr);
|
|
JCGO_UNUSED_VAR(bytes);
|
|
JCGO_UNUSED_VAR(offset);
|
|
#else
|
|
(*pJniEnv)->ReleaseByteArrayElements(pJniEnv, arr,
|
|
(jbyte *)((jbyte JCGO_HPTR_MOD *)bytes - (JCGO_ALLOCSIZE_T)offset), 0);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
jcgo_JnuGetIntArrayElement( JNIEnv *pJniEnv, jintArray arr, jint index )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
return JCGO_ARR_INTERNALACC(jint, (jintArr)arr, index);
|
|
#else
|
|
jint value = 0;
|
|
(*pJniEnv)->GetIntArrayRegion(pJniEnv, arr, (jsize)index, 1, &value);
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
jcgo_JnuSetIntArrayElement( JNIEnv *pJniEnv, jintArray arr, jint index,
|
|
jint value )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
JCGO_ARR_INTERNALACC(jint, (jintArr)arr, index) = value;
|
|
#else
|
|
(*pJniEnv)->SetIntArrayRegion(pJniEnv, arr, (jsize)index, 1, &value);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
jcgo_JnuSetLongArrayElement( JNIEnv *pJniEnv, jlongArray arr, jint index,
|
|
jlong value )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
JCGO_ARR_INTERNALACC(jlong, (jlongArr)arr, index) = value;
|
|
#else
|
|
(*pJniEnv)->SetLongArrayRegion(pJniEnv, arr, (jsize)index, 1, &value);
|
|
#endif
|
|
}
|
|
|
|
JNUBIGEXPORT unsigned JNICALL
|
|
jcgo_JnuStringSizeOfPlatform( JNIEnv *pJniEnv, jstring str )
|
|
{
|
|
unsigned len = 0;
|
|
#ifdef JCGO_NOJNI
|
|
jint count = *jcgo_jnuStringLengthPtr(str);
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
#else
|
|
jint count = (jint)(*pJniEnv)->GetStringLength(pJniEnv, str);
|
|
#endif
|
|
if (count > 0)
|
|
{
|
|
#ifdef JCGO_UTFWCTOMB
|
|
len = count <= (jint)(((((unsigned)-1) >> 1) - 16) / 3) ?
|
|
(unsigned)count * 3 : (((unsigned)-1) >> 1) - (unsigned)16;
|
|
#else
|
|
len = (unsigned)count;
|
|
if (count > (jint)((((unsigned)-1) >> 1) - 16))
|
|
len = (((unsigned)-1) >> 1) - (unsigned)16;
|
|
#ifdef MB_CUR_MAX
|
|
count = (jint)MB_CUR_MAX;
|
|
if (count != 1)
|
|
#endif
|
|
{
|
|
#ifdef MB_CUR_MAX
|
|
if ((unsigned)count < (unsigned)MB_LEN_MAX &&
|
|
*(volatile jint *)&count != 0)
|
|
len = ((((unsigned)-1) >> 1) - (unsigned)16) / (unsigned)count >= len ?
|
|
(unsigned)count * len : (((unsigned)-1) >> 1) - (unsigned)16;
|
|
else
|
|
#endif
|
|
{
|
|
len = len <= ((((unsigned)-1) >> 1) - (unsigned)16) /
|
|
(unsigned)MB_LEN_MAX ? len * (unsigned)MB_LEN_MAX :
|
|
(((unsigned)-1) >> 1) - (unsigned)16;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
return len + 1;
|
|
}
|
|
|
|
JNUBIGEXPORT int JNICALL
|
|
jcgo_JnuStringToPlatformChars( JNIEnv *pJniEnv, jstring str, char *cbuf,
|
|
unsigned size )
|
|
{
|
|
int cnt;
|
|
int i;
|
|
unsigned pos;
|
|
unsigned len;
|
|
int noerr = -1;
|
|
jint count;
|
|
CONST jchar JCGO_HPTR_MOD *chars;
|
|
#ifdef JCGO_NOJNI
|
|
int isbytes;
|
|
#endif
|
|
#ifdef JCGO_UTFWCTOMB
|
|
jchar wch;
|
|
#else
|
|
int res;
|
|
#ifdef JCGO_DOWCSTOMBS
|
|
wchar_t wbuf[2];
|
|
#else
|
|
int j;
|
|
char mbbuf[MB_LEN_MAX];
|
|
#endif
|
|
#endif
|
|
if (cbuf != NULL && size)
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
chars = jcgo_jnuStringChars(str, &isbytes);
|
|
count = *jcgo_jnuStringLengthPtr(str);
|
|
#else
|
|
chars = (*pJniEnv)->GetStringChars(pJniEnv, str, NULL);
|
|
if (chars == NULL)
|
|
return noerr;
|
|
count = (jint)(*pJniEnv)->GetStringLength(pJniEnv, str);
|
|
#endif
|
|
len = (((unsigned)-1) >> 1) - (unsigned)16;
|
|
pos = 0;
|
|
noerr = 1;
|
|
if (size <= len)
|
|
len = size - 1;
|
|
cnt = (int)len;
|
|
if ((jint)cnt > count)
|
|
cnt = (int)count;
|
|
#ifndef JCGO_UTFWCTOMB
|
|
#ifdef JCGO_DOWCSTOMBS
|
|
wbuf[1] = (wchar_t)0;
|
|
#else
|
|
*(volatile char *)&mbbuf[0] = (char)wctomb(NULL, (wchar_t)0);
|
|
#endif
|
|
#endif
|
|
for (i = 0; i < cnt; i++)
|
|
{
|
|
#ifdef JCGO_UTFWCTOMB
|
|
#ifdef JCGO_NOJNI
|
|
wch = isbytes ? (unsigned char)(*((volatile jbyte JCGO_HPTR_MOD *)chars +
|
|
(unsigned)i)) : *(chars + (unsigned)i);
|
|
#else
|
|
wch = *(chars + (unsigned)i);
|
|
#endif
|
|
if (wch < 0x80 && wch)
|
|
{
|
|
if (pos >= len)
|
|
break;
|
|
cbuf[pos] = (char)wch;
|
|
}
|
|
else
|
|
{
|
|
if (wch < 0x800)
|
|
{
|
|
if (pos + 1 >= len)
|
|
break;
|
|
cbuf[pos] = (char)((wch >> 6) | 0xc0);
|
|
}
|
|
else
|
|
{
|
|
if (pos + 2 >= len)
|
|
break;
|
|
cbuf[pos] = (char)((wch >> 12) | 0xe0);
|
|
cbuf[pos + 1] = (char)(((wch >> 6) & 0x3f) | 0x80);
|
|
pos++;
|
|
}
|
|
cbuf[++pos] = (char)((wch & 0x3f) | 0x80);
|
|
}
|
|
pos++;
|
|
#else
|
|
#ifdef JCGO_DOWCSTOMBS
|
|
#ifdef JCGO_NOJNI
|
|
wbuf[0] = (wchar_t)(isbytes ?
|
|
(unsigned char)(*((volatile jbyte JCGO_HPTR_MOD *)chars +
|
|
(unsigned)i)) : *(chars + (unsigned)i));
|
|
#else
|
|
wbuf[0] = (wchar_t)(*(chars + (unsigned)i));
|
|
#endif
|
|
res = (int)wcstombs(&cbuf[pos], wbuf, len - pos);
|
|
#else
|
|
#ifdef JCGO_NOJNI
|
|
res = wctomb(len - pos < sizeof(mbbuf) ? mbbuf : &cbuf[pos],
|
|
(wchar_t)(isbytes ?
|
|
(unsigned char)(*((volatile jbyte JCGO_HPTR_MOD *)chars +
|
|
(unsigned)i)) : *(chars + (unsigned)i)));
|
|
#else
|
|
res = wctomb(len - pos < sizeof(mbbuf) ? mbbuf : &cbuf[pos],
|
|
(wchar_t)(*(chars + (unsigned)i)));
|
|
#endif
|
|
#endif
|
|
if (res > 0)
|
|
{
|
|
#ifndef JCGO_DOWCSTOMBS
|
|
if (len - pos < sizeof(mbbuf))
|
|
{
|
|
if (pos + (unsigned)res > len)
|
|
break;
|
|
for (j = 0; j < res; j++)
|
|
cbuf[pos + j] = mbbuf[j];
|
|
}
|
|
#endif
|
|
pos = (unsigned)res + pos;
|
|
}
|
|
else
|
|
{
|
|
if (pos >= len)
|
|
break;
|
|
if (res < 0)
|
|
{
|
|
noerr = 0;
|
|
cbuf[pos++] = '?';
|
|
}
|
|
else cbuf[pos++] = '\0';
|
|
}
|
|
#endif
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
(*pJniEnv)->ReleaseStringChars(pJniEnv, str, (CONST jchar *)chars);
|
|
#endif
|
|
if ((jint)i < count)
|
|
{
|
|
noerr = 0;
|
|
if (pos < len)
|
|
cbuf[pos++] = '?';
|
|
else
|
|
{
|
|
if (len)
|
|
cbuf[len - 1] = '?';
|
|
}
|
|
}
|
|
cbuf[pos] = '\0';
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
else (*pJniEnv)->FatalError(pJniEnv, JCGO_JNUMSG_BADARG);
|
|
#endif
|
|
return noerr;
|
|
}
|
|
|
|
JNUBIGEXPORT jstring JNICALL
|
|
jcgo_JnuNewStringPlatform( JNIEnv *pJniEnv, CONST char *cstr )
|
|
{
|
|
#ifdef JCGO_UTFWCTOMB
|
|
jchar wch;
|
|
char ch;
|
|
unsigned pos;
|
|
#else
|
|
#ifndef JCGO_DOWCSTOMBS
|
|
wchar_t wch;
|
|
int res;
|
|
unsigned pos;
|
|
#endif
|
|
#endif
|
|
unsigned len = 0;
|
|
int i = (int)(((unsigned)-1) >> 1) - 16;
|
|
jstring str = NULL;
|
|
jchar *chars;
|
|
#ifndef JCGO_NOJNI
|
|
jcharArray arr;
|
|
jchar buf[JCGO_JNUNEWSTRING_WBUFSIZE];
|
|
#endif
|
|
if (cstr != NULL)
|
|
{
|
|
while (*(cstr + len))
|
|
len++;
|
|
if (len >= (unsigned)i)
|
|
len = (unsigned)i;
|
|
#ifdef JCGO_NOJNI
|
|
str = jcgo_jnuStringCreate(pJniEnv, (jint)len);
|
|
chars = NULL;
|
|
if (str != NULL)
|
|
chars = jcgo_jnuStringChars(str, &i);
|
|
#else
|
|
arr = NULL;
|
|
chars = buf;
|
|
if (len > sizeof(buf) / sizeof(jchar))
|
|
{
|
|
arr = (*pJniEnv)->NewCharArray(pJniEnv, (jsize)len);
|
|
chars = NULL;
|
|
if (arr != NULL)
|
|
chars = (*pJniEnv)->GetCharArrayElements(pJniEnv, arr, NULL);
|
|
}
|
|
#endif
|
|
if (chars != NULL)
|
|
{
|
|
i = 0;
|
|
#ifdef JCGO_UTFWCTOMB
|
|
for (pos = 0; pos < len; pos++)
|
|
{
|
|
wch = (unsigned char)cstr[pos];
|
|
if (wch >= 0x80 && (wch > 0xef ||
|
|
((ch = cstr[++pos]) & 0xc0) != 0x80 || (wch < 0xe0 ?
|
|
(wch = (jchar)(((wch & 0x1f) << 6) | (ch & 0x3f))) < 0x80 && wch :
|
|
(wch = (jchar)((wch << 12) | ((jchar)(ch & 0x3f) << 6) |
|
|
(cstr[++pos] & 0x3f))) < 0x800 || (cstr[pos] & 0xc0) != 0x80)))
|
|
{
|
|
*chars = (jchar)0x3f; /*'?'*/
|
|
if (i <= 0)
|
|
i = 1;
|
|
break;
|
|
}
|
|
*(chars + (i++)) = wch;
|
|
}
|
|
#else
|
|
#ifdef JCGO_DOWCSTOMBS
|
|
if (len && (i = (int)mbstowcs(chars, cstr, len)) < 0)
|
|
{
|
|
*chars = (jchar)0x3f; /*'?'*/
|
|
for (i = 1; i < (int)len; i++)
|
|
if (!(*(chars + i)))
|
|
break;
|
|
}
|
|
#else
|
|
*(volatile wchar_t *)&wch = (wchar_t)mbtowc(&wch, NULL, 0);
|
|
for (pos = 0; pos < len; pos = (unsigned)res + pos)
|
|
{
|
|
if ((res = mbtowc(&wch, cstr + pos, len - pos + 1)) <= 0)
|
|
{
|
|
if (!res)
|
|
break;
|
|
if ((res = mbtowc(&wch, cstr + pos, 1)) <= 0)
|
|
{
|
|
if (!res)
|
|
break;
|
|
*chars = (jchar)0x3f; /*'?'*/
|
|
if (i <= 0)
|
|
i = 1;
|
|
break;
|
|
}
|
|
}
|
|
*(chars + (i++)) = (jchar)wch;
|
|
}
|
|
#endif
|
|
#endif
|
|
#ifdef JCGO_NOJNI
|
|
*jcgo_jnuStringLengthPtr(str) = i;
|
|
#else
|
|
str = (*pJniEnv)->NewString(pJniEnv, chars, (jsize)i);
|
|
if (arr != NULL)
|
|
(*pJniEnv)->ReleaseCharArrayElements(pJniEnv, arr, chars, 0);
|
|
#endif
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
if (arr != NULL)
|
|
(*pJniEnv)->DeleteLocalRef(pJniEnv, (jobject)arr);
|
|
#endif
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
else (*pJniEnv)->FatalError(pJniEnv, JCGO_JNUMSG_BADARG);
|
|
#endif
|
|
return str;
|
|
}
|
|
|
|
#ifdef JCGO_SYSWCHAR
|
|
|
|
JNIEXPORT unsigned JNICALL
|
|
jcgo_JnuStringSizeOfWide( JNIEnv *pJniEnv, jstring str )
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
jint count = *jcgo_jnuStringLengthPtr(str);
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
#else
|
|
jint count = (jint)(*pJniEnv)->GetStringLength(pJniEnv, str);
|
|
#endif
|
|
return count > 0 ? (count < (jint)(((((unsigned)-1) >> 1) - 16) /
|
|
sizeof(wchar_t)) ? ((unsigned)count + 1) * sizeof(wchar_t) :
|
|
(((unsigned)-1) >> 1) + sizeof(wchar_t) - 16) : sizeof(wchar_t);
|
|
}
|
|
|
|
JNUBIGEXPORT int JNICALL
|
|
jcgo_JnuStringToWideChars( JNIEnv *pJniEnv, jstring str, wchar_t *wbuf,
|
|
unsigned size )
|
|
{
|
|
int cnt;
|
|
int i;
|
|
int noerr = -1;
|
|
jint count;
|
|
CONST jchar JCGO_HPTR_MOD *chars;
|
|
#ifdef JCGO_NOJNI
|
|
int isbytes;
|
|
#endif
|
|
if (wbuf != NULL && size >= sizeof(wchar_t))
|
|
{
|
|
#ifdef JCGO_NOJNI
|
|
JCGO_UNUSED_VAR(pJniEnv);
|
|
chars = jcgo_jnuStringChars(str, &isbytes);
|
|
count = *jcgo_jnuStringLengthPtr(str);
|
|
#else
|
|
chars = (*pJniEnv)->GetStringChars(pJniEnv, str, NULL);
|
|
if (chars == NULL)
|
|
return noerr;
|
|
count = (jint)(*pJniEnv)->GetStringLength(pJniEnv, str);
|
|
#endif
|
|
cnt = (int)(((unsigned)-1) >> 1) - 16;
|
|
if (size <= (unsigned)cnt)
|
|
cnt = (int)size;
|
|
cnt = (int)((unsigned)cnt / sizeof(wchar_t)) - 1;
|
|
noerr = 1;
|
|
if ((jint)cnt < count)
|
|
{
|
|
noerr = 0;
|
|
if (cnt)
|
|
wbuf[cnt - 1] = (wchar_t)0x3f; /*'?'*/
|
|
}
|
|
else cnt = (int)count;
|
|
#ifdef JCGO_NOJNI
|
|
if (isbytes)
|
|
{
|
|
for (i = 0; i < cnt; i++)
|
|
wbuf[i] = (wchar_t)((unsigned char)(
|
|
*((volatile jbyte JCGO_HPTR_MOD *)chars + i)));
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < cnt; i++)
|
|
wbuf[i] = (wchar_t)(*(chars + i));
|
|
}
|
|
#else
|
|
for (i = 0; i < cnt; i++)
|
|
wbuf[i] = (wchar_t)(*(chars + i));
|
|
(*pJniEnv)->ReleaseStringChars(pJniEnv, str, (CONST jchar *)chars);
|
|
#endif
|
|
wbuf[cnt] = (wchar_t)0;
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
else (*pJniEnv)->FatalError(pJniEnv, JCGO_JNUMSG_BADARG);
|
|
#endif
|
|
return noerr;
|
|
}
|
|
|
|
#else /* JCGO_SYSWCHAR */
|
|
|
|
#ifndef JCGO_WMAIN
|
|
#define JCGO_EXCLUDE_NEWSTRINGWIDE
|
|
#endif
|
|
|
|
#endif /* ! JCGO_SYSWCHAR */
|
|
|
|
#ifndef JCGO_EXCLUDE_NEWSTRINGWIDE
|
|
|
|
JNUBIGEXPORT jstring JNICALL
|
|
jcgo_JnuNewStringWide( JNIEnv *pJniEnv, CONST wchar_t *wstr )
|
|
{
|
|
unsigned len = 0;
|
|
int i = (int)(((((unsigned)-1) >> 1) - 16) / sizeof(wchar_t));
|
|
jstring str = NULL;
|
|
jchar *chars;
|
|
#ifndef JCGO_NOJNI
|
|
jcharArray arr;
|
|
jchar buf[JCGO_JNUNEWSTRING_WBUFSIZE];
|
|
#endif
|
|
if (wstr != NULL)
|
|
{
|
|
while (*(wstr + len))
|
|
len++;
|
|
if (len >= (unsigned)i)
|
|
len = (unsigned)i;
|
|
#ifdef JCGO_NOJNI
|
|
str = jcgo_jnuStringCreate(pJniEnv, (jint)len);
|
|
chars = NULL;
|
|
if (str != NULL)
|
|
chars = jcgo_jnuStringChars(str, &i);
|
|
#else
|
|
arr = NULL;
|
|
chars = buf;
|
|
if (len > sizeof(buf) / sizeof(jchar))
|
|
{
|
|
arr = (*pJniEnv)->NewCharArray(pJniEnv, (jsize)len);
|
|
chars = NULL;
|
|
if (arr != NULL)
|
|
chars = (*pJniEnv)->GetCharArrayElements(pJniEnv, arr, NULL);
|
|
}
|
|
#endif
|
|
if (chars != NULL)
|
|
{
|
|
for (i = 0; i < (int)len; i++)
|
|
*(chars + i) = (jchar)(*(wstr + i));
|
|
#ifdef JCGO_NOJNI
|
|
*jcgo_jnuStringLengthPtr(str) = (int)len;
|
|
#else
|
|
str = (*pJniEnv)->NewString(pJniEnv, chars, (jsize)len);
|
|
if (arr != NULL)
|
|
(*pJniEnv)->ReleaseCharArrayElements(pJniEnv, arr, chars, 0);
|
|
#endif
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
if (arr != NULL)
|
|
(*pJniEnv)->DeleteLocalRef(pJniEnv, (jobject)arr);
|
|
#endif
|
|
}
|
|
#ifndef JCGO_NOJNI
|
|
else (*pJniEnv)->FatalError(pJniEnv, JCGO_JNUMSG_BADARG);
|
|
#endif
|
|
return str;
|
|
}
|
|
|
|
#endif /* ! JCGO_EXCLUDE_NEWSTRINGWIDE */
|
|
|
|
#endif
|