Skip to content

Commit

Permalink
Merge pull request #10652 from rouault/java_NewStringUTF
Browse files Browse the repository at this point in the history
Java: UTF-8 related fixes
  • Loading branch information
rouault authored Sep 5, 2024
2 parents a8be1ce + 17b7081 commit f832d0e
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 40 deletions.
114 changes: 87 additions & 27 deletions swig/include/java/typemaps_java.i
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,45 @@
%include "arrays_java.i";
%include "typemaps.i"


%fragment("SafeNewStringUTF8","header")
%{
static jstring
SafeNewStringUTF8(JNIEnv *jenv, const char* pszInput)
{
jstring ret = 0;
if (pszInput)
{
if( !CPLIsUTF8(pszInput, -1) )
{
CPLError(CE_Warning, CPLE_AppDefined,
"A non-UTF8 string has been detected. Forcing it to ASCII");
char* pszTmp = CPLUTF8ForceToASCII(pszInput, '_');
#ifdef __cplusplus
ret = jenv->NewStringUTF(pszTmp);
#else
ret = (*jenv)->NewStringUTF(jenv, pszTmp);
#endif
CPLFree(pszTmp);
}
else
{
#ifdef __cplusplus
ret = jenv->NewStringUTF(pszInput);
#else
ret = (*jenv)->NewStringUTF(jenv, pszInput);
#endif
}
}
return ret;
}
%}

// Overrides typemap defined in /usr/share/swig4.0/java.swg
%typemap(out, fragment="SafeNewStringUTF8", noblock=1) char * {
$result = SafeNewStringUTF8(jenv, (const char *)$1);
}

%apply (int) {VSI_RETVAL};

%typemap(javabody) SWIGTYPE %{
Expand Down Expand Up @@ -250,7 +289,7 @@
$2 = &pGCPs;
}

%typemap(argout) (int *nGCPs, GDAL_GCP const **pGCPs )
%typemap(argout, fragment="SafeNewStringUTF8") (int *nGCPs, GDAL_GCP const **pGCPs )
{
/* %typemap(argout) (int *nGCPs, GDAL_GCP const **pGCPs ) */
const jclass GCPClass = jenv->FindClass("org/gdal/gdal/GCP");
Expand All @@ -261,8 +300,8 @@

int i;
for (i=0; i<*$1; i++ ) {
jstring stringInfo = jenv->NewStringUTF((*$2)[i].pszInfo);
jstring stringId = jenv->NewStringUTF((*$2)[i].pszId);
jstring stringInfo = SafeNewStringUTF8(jenv, (*$2)[i].pszInfo);
jstring stringId = SafeNewStringUTF8(jenv, (*$2)[i].pszId);
jobject GCPobj = jenv->NewObject(GCPClass, GCPcon,
(*$2)[i].dfGCPX,
(*$2)[i].dfGCPY,
Expand Down Expand Up @@ -441,12 +480,12 @@
* Typemaps for (retStringAndCPLFree*)
***************************************************/

%typemap(out) (retStringAndCPLFree*)
%typemap(out, fragment="SafeNewStringUTF8") (retStringAndCPLFree*)
{
/* %typemap(out) (retStringAndCPLFree*) */
if(result)
{
$result = jenv->NewStringUTF((const char *)result);
$result = SafeNewStringUTF8(jenv, (const char *)result);
CPLFree(result);
}
}
Expand All @@ -459,6 +498,29 @@
return $jnicall;
}

/***************************************************
* Typemaps for (StringAsByteArray*)
***************************************************/

%typemap(out) (StringAsByteArray*)
{
/* %typemap(out) (StringAsByteArray*) */
if(result)
{
const size_t nLen = strlen((const char*)result);
jbyteArray byteArray = jenv->NewByteArray(nLen);
jenv->SetByteArrayRegion(byteArray, (jsize)0, (jsize)nLen, (jbyte*)result);
$result = byteArray;
}
}

%typemap(jni) (StringAsByteArray*) "jbyteArray"
%typemap(jtype) (StringAsByteArray*) "byte[]"
%typemap(jstype) (StringAsByteArray*) "byte[]"
%typemap(javain) (StringAsByteArray*) "$javainput"
%typemap(javaout) (StringAsByteArray*) {
return $jnicall;
}

/***************************************************
* Typemaps for (char **ignorechange)
Expand Down Expand Up @@ -1035,7 +1097,7 @@
}
}

%fragment("GetCSLStringAsHashTable","header")
%fragment("GetCSLStringAsHashTable","header", fragment="SafeNewStringUTF8")
%{
/* Convert a char array to a Hashtable */
static jobject
Expand All @@ -1054,8 +1116,8 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
keyptr = CPLStrdup(*stringarray);
keyptr[pszSep - *stringarray] = '\0';
valptr = pszSep + 1;
jstring name = jenv->NewStringUTF(keyptr);
jstring value = jenv->NewStringUTF(valptr);
jstring name = SafeNewStringUTF8(jenv, keyptr);
jstring value = SafeNewStringUTF8(jenv, valptr);
jenv->CallObjectMethod(jHashtable, put, name, value);
jenv->DeleteLocalRef(name);
jenv->DeleteLocalRef(value);
Expand Down Expand Up @@ -1151,7 +1213,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
CSLDestroy( $1 );
}

%typemap(out) char **options
%typemap(out, fragment="SafeNewStringUTF8") char **options
{
/* %typemap(out) char **options */
char **stringarray = $1;
Expand All @@ -1162,8 +1224,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$result = jenv->NewObject(vector, constructor);
if ( stringarray != NULL ) {
while(*stringarray != NULL) {
/*printf("working on string %s\n", *stringarray);*/
jstring value = (jstring)jenv->NewStringUTF(*stringarray);
jstring value = SafeNewStringUTF8(jenv, *stringarray);
jenv->CallBooleanMethod($result, add, value);
jenv->DeleteLocalRef(value);
stringarray++;
Expand All @@ -1183,7 +1244,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
* Typemaps for retAsStringArrayNoFree
***************************************************/

%typemap(out) char **retAsStringArrayNoFree
%typemap(out,fragment="SafeNewStringUTF8") char **retAsStringArrayNoFree
{
/* %typemap(out) char **retAsStringArrayNoFree */
char **stringarray = result;
Expand All @@ -1196,7 +1257,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*stringarray++);
temp_string = SafeNewStringUTF8(jenv, *stringarray++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand All @@ -1214,7 +1275,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
* Typemaps for retAsStringArrayNoFree
***************************************************/

%typemap(out) char **retAsStringArrayAndFree
%typemap(out, fragment="SafeNewStringUTF8") char **retAsStringArrayAndFree
{
/* %typemap(out) char **retAsStringArrayAndFree */
char **stringarray = result;
Expand All @@ -1227,7 +1288,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*stringarray++);
temp_string = SafeNewStringUTF8(jenv, *stringarray++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -1261,10 +1322,10 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$1 = &ret;
}

%typemap(argout) char **OUTPUT
%typemap(argout, fragment="SafeNewStringUTF8") char **OUTPUT
{
/* %typemap(argout) char **OUTPUT */
jstring temp_string = jenv->NewStringUTF(ret$argnum);
jstring temp_string = SafeNewStringUTF8(jenv, ret$argnum);
jenv->SetObjectArrayElement($input, 0, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand All @@ -1285,7 +1346,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* Almost same as %typemap(out) char **options */
/* but we CSLDestroy the char** pointer at the end */

%typemap(out) char **CSL
%typemap(out, fragment="SafeNewStringUTF8") char **CSL
{
/* %typemap(out) char **CSL */
char **stringarray = $1;
Expand All @@ -1296,8 +1357,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$result = jenv->NewObject(vector, constructor);
if ( stringarray != NULL ) {
while(*stringarray != NULL) {
/*printf("working on string %s\n", *stringarray);*/
jstring value = (jstring)jenv->NewStringUTF(*stringarray);
jstring value = SafeNewStringUTF8(jenv, *stringarray);
jenv->CallBooleanMethod($result, add, value);
jenv->DeleteLocalRef(value);
stringarray++;
Expand All @@ -1324,13 +1384,13 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$1 = &argout;
}

%typemap(argout) (char **argout)
%typemap(argout, fragment="SafeNewStringUTF8") (char **argout)
{
/* %typemap(argout) (char **argout) */
jstring temp_string;

if($input != NULL && (int)jenv->GetArrayLength($input) >= 1) {
temp_string = jenv->NewStringUTF(argout$argnum);
temp_string = SafeNewStringUTF8(jenv, argout$argnum);
jenv->SetObjectArrayElement($input, 0, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -1497,7 +1557,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {

/* This allows a C function to return a char ** as a Java String array */

%typemap(out) char ** {
%typemap(out, fragment="SafeNewStringUTF8") char ** {
/* %typemap(out) char ** */
int i;
int len=0;
Expand All @@ -1509,7 +1569,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*result++);
temp_string = SafeNewStringUTF8(jenv, *result++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -2509,7 +2569,7 @@ DEFINE_BOOLEAN_FUNC_ARRAY_IN(double, jdouble, GetDoubleArrayElements, ReleaseDou
CPLFree( $1 );
}

%typemap(out) OGRCodedValue*
%typemap(out, fragment="SafeNewStringUTF8") OGRCodedValue*
{
/* %typemap(out) OGRCodedValue* */
/* Convert a OGRCodedValue* to a HashMap */
Expand All @@ -2525,10 +2585,10 @@ DEFINE_BOOLEAN_FUNC_ARRAY_IN(double, jdouble, GetDoubleArrayElements, ReleaseDou
$result = jenv->NewObject(hashMapClass, constructor);
for( int i = 0; ($1)[i].pszCode != NULL; i++ )
{
jstring name = jenv->NewStringUTF(($1)[i].pszCode);
jstring name = SafeNewStringUTF8(jenv, ($1)[i].pszCode);
if( ($1)[i].pszValue )
{
jstring value = jenv->NewStringUTF(($1)[i].pszValue);
jstring value = SafeNewStringUTF8(jenv, ($1)[i].pszValue);
jenv->CallObjectMethod($result, put, name, value);
jenv->DeleteLocalRef(value);
}
Expand Down
Loading

0 comments on commit f832d0e

Please sign in to comment.