diff --git a/swig/include/java/typemaps_java.i b/swig/include/java/typemaps_java.i index 682995cd12fd..551cc42b1f4e 100644 --- a/swig/include/java/typemaps_java.i +++ b/swig/include/java/typemaps_java.i @@ -498,6 +498,29 @@ SafeNewStringUTF8(JNIEnv *jenv, const char* pszInput) 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) diff --git a/swig/include/ogr.i b/swig/include/ogr.i index a176f12feed7..10c2b9d256df 100644 --- a/swig/include/ogr.i +++ b/swig/include/ogr.i @@ -52,6 +52,12 @@ typedef char retStringAndCPLFree; %} #endif +#ifdef SWIGJAVA +%inline %{ +typedef const char StringAsByteArray; +%} +#endif + #ifdef SWIGCSHARP %include swig_csharp_extensions.i #endif @@ -930,6 +936,12 @@ public: return OGR_DS_GetName(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_DS_GetName(self); + } +#endif + OGRErr DeleteLayer(int index){ return OGR_DS_DeleteLayer(self, index); } @@ -1324,6 +1336,12 @@ public: return OGR_L_GetName(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_L_GetName(self); + } +#endif + /* Added in OGR 1.8.0 */ OGRwkbGeometryType GetGeomType() { return (OGRwkbGeometryType) OGR_L_GetGeomType(self); @@ -1333,10 +1351,22 @@ public: return OGR_L_GetGeometryColumn(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetGeometryColumnAsByteArray() { + return OGR_L_GetGeometryColumn(self); + } +#endif + const char * GetFIDColumn() { return OGR_L_GetFIDColumn(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetFIDColumnAsByteArray() { + return OGR_L_GetFIDColumn(self); + } +#endif + %newobject GetFeature; OGRFeatureShadow *GetFeature(GIntBig fid) { return (OGRFeatureShadow*) OGR_L_GetFeature(self, fid); @@ -1985,17 +2015,40 @@ public: /* ---- GetFieldAsString --------------------- */ const char* GetFieldAsString(int id) { - return (const char *) OGR_F_GetFieldAsString(self, id); + return OGR_F_GetFieldAsString(self, id); } const char* GetFieldAsString(const char* field_name) { int i = OGR_F_GetFieldIndex(self, field_name); if (i == -1) - CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name); + { + CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name); + return NULL; + } else - return (const char *) OGR_F_GetFieldAsString(self, i); - return NULL; + { + return OGR_F_GetFieldAsString(self, i); + } + } + +#ifdef SWIGJAVA + StringAsByteArray* GetFieldAsStringAsByteArray(int id) { + return OGR_F_GetFieldAsString(self, id); + } + + StringAsByteArray* GetFieldAsStringAsByteArray(const char* field_name) { + int i = OGR_F_GetFieldIndex(self, field_name); + if (i == -1) + { + CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name); + return NULL; + } + else + { + return OGR_F_GetFieldAsString(self, i); + } } +#endif /* ------------------------------------------- */ @@ -2474,6 +2527,12 @@ public: return (const char*) OGR_F_GetStyleString(self); } +#ifdef SWIGJAVA + StringAsByteArray *GetStyleStringAsByteArray() { + return OGR_F_GetStyleString(self); + } +#endif + void SetStyleString(const char* the_string) { OGR_F_SetStyleString(self, the_string); } @@ -2510,6 +2569,12 @@ public: return OGR_F_GetNativeData(self); } +#ifdef SWIGJAVA + StringAsByteArray *GetNativeDataAsByteArray() { + return OGR_F_GetNativeData(self); + } +#endif + const char* GetNativeMediaType () { return OGR_F_GetNativeMediaType(self); } @@ -2640,6 +2705,12 @@ public: return OGR_FD_GetName(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_FD_GetName(self); + } +#endif + int GetFieldCount(){ return OGR_FD_GetFieldCount(self); } @@ -2796,11 +2867,17 @@ public: } const char * GetName() { - return (const char *) OGR_Fld_GetNameRef(self); + return OGR_Fld_GetNameRef(self); + } + +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_Fld_GetNameRef(self); } +#endif const char * GetNameRef() { - return (const char *) OGR_Fld_GetNameRef(self); + return OGR_Fld_GetNameRef(self); } void SetName( const char* name) { @@ -2811,6 +2888,12 @@ public: return OGR_Fld_GetAlternativeNameRef(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetAlternativeNameAsByteArray() { + return OGR_Fld_GetAlternativeNameRef(self); + } +#endif + const char * GetAlternativeNameRef() { return OGR_Fld_GetAlternativeNameRef(self); } @@ -2915,6 +2998,12 @@ public: return OGR_Fld_GetDefault( self ); } +#ifdef SWIGJAVA + StringAsByteArray* GetDefaultAsByteArray() { + return OGR_Fld_GetDefault(self); + } +#endif + void SetDefault(const char* pszValue ) { OGR_Fld_SetDefault( self, pszValue ); } @@ -2927,6 +3016,12 @@ public: return OGR_Fld_GetDomainName(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetDomainNameAsByteArray() { + return OGR_Fld_GetDomainName(self); + } +#endif + void SetDomainName(const char* name ) { OGR_Fld_SetDomainName( self, name ); } @@ -2935,6 +3030,12 @@ public: return OGR_Fld_GetComment(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetCommentAsByteArray() { + return OGR_Fld_GetComment(self); + } +#endif + void SetComment(const char* comment ) { OGR_Fld_SetComment( self, comment ); } @@ -2970,11 +3071,17 @@ public: } const char * GetName() { - return (const char *) OGR_GFld_GetNameRef(self); + return OGR_GFld_GetNameRef(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_GFld_GetNameRef(self); + } +#endif + const char * GetNameRef() { - return (const char *) OGR_GFld_GetNameRef(self); + return OGR_GFld_GetNameRef(self); } void SetName( const char* name) { @@ -4054,10 +4161,22 @@ public: return OGR_FldDomain_GetName(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetNameAsByteArray() { + return OGR_FldDomain_GetName(self); + } +#endif + const char * GetDescription() { return OGR_FldDomain_GetDescription(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetDescriptionAsByteArray() { + return OGR_FldDomain_GetDescription(self); + } +#endif + OGRFieldType GetFieldType() { return OGR_FldDomain_GetFieldType(self); } @@ -4180,6 +4299,12 @@ public: return OGR_GlobFldDomain_GetGlob(self); } +#ifdef SWIGJAVA + StringAsByteArray* GetGlobAsByteArray() { + return OGR_GlobFldDomain_GetGlob(self); + } +#endif + } /* %extend */ }; /* class OGRFieldDomainShadow */ diff --git a/swig/java/CMakeLists.txt b/swig/java/CMakeLists.txt index 6198ab9b12f3..5a3530206773 100644 --- a/swig/java/CMakeLists.txt +++ b/swig/java/CMakeLists.txt @@ -191,6 +191,7 @@ if (Java_Runtime_FOUND AND BUILD_TESTING) file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/tmp_test) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tmp_test) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_data/byte.tif DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tmp_test) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_data/iso_8859_1.csv DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tmp_test) if (WIN32) set(CLASSPATH_SEPARATOR "\\;") @@ -229,9 +230,8 @@ if (Java_Runtime_FOUND AND BUILD_TESTING) add_test(NAME java_OSRTest COMMAND ${JAVA_RUN} OSRTest) add_test(NAME java_test_ogrfielddomains COMMAND ${JAVA_RUN} test_ogrfielddomains) - foreach ( - test_name IN - ITEMS java_GDALOverviews + set(JAVA_TEST_LIST + java_GDALOverviews java_gdalinfo java_ogr2ogr_1 java_ogrinfo_1 @@ -247,7 +247,14 @@ if (Java_Runtime_FOUND AND BUILD_TESTING) java_testgetpoints java_ogrtindex java_OSRTest - java_test_ogrfielddomains) + java_test_ogrfielddomains + ) + if (OGR_ENABLE_DRIVER_CSV) + add_test(NAME java_OGRTest COMMAND ${JAVA_RUN} OGRTest) + list(APPEND JAVA_TEST_LIST java_OGRTest) + endif() + + foreach (test_name IN LISTS JAVA_TEST_LIST) set_property(TEST ${test_name} PROPERTY ENVIRONMENT "${TEST_ENV}") endforeach () diff --git a/swig/java/apps/OGRTest.java b/swig/java/apps/OGRTest.java new file mode 100644 index 000000000000..71148bbeccb1 --- /dev/null +++ b/swig/java/apps/OGRTest.java @@ -0,0 +1,47 @@ +/****************************************************************************** + * Name: OGRTest.java + * Project: OGR Java Interface + * Purpose: Test OGR module + * Author: Even Rouault, + * + ****************************************************************************** + * Copyright (c) 2024, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + *****************************************************************************/ + +import java.util.Arrays; +import org.gdal.ogr.*; + +public class OGRTest +{ + public static void main(String[] args) throws Exception + { + ogr.RegisterAll(); + DataSource poDS = ogr.Open("tmp_test/iso_8859_1.csv", false); + Layer lyr = poDS.GetLayer(0); + FieldDefn fld_defn = lyr.GetLayerDefn().GetFieldDefn(1); + String got = fld_defn.GetName(); + if (!got.equals("field_")) + throw new Exception("Got '" + got + "'"); + byte[] byteArray = fld_defn.GetNameAsByteArray(); + if(!Arrays.equals(byteArray, new byte[]{'f', 'i', 'e', 'l', 'd', '_', 0xE9 - 256, 'x'})) + throw new Exception("GetNameAsByteArray() returned unexpected content of size " + byteArray.length); + } +} diff --git a/swig/java/javadoc.java b/swig/java/javadoc.java index 22a144897093..552bc63da733 100644 --- a/swig/java/javadoc.java +++ b/swig/java/javadoc.java @@ -6859,9 +6859,22 @@ public class Layer:public FeatureDefn GetLayerDefn() * definition initialization. * * @return the layer name + * @see #GetNameAsByteArray() */ public class Layer:public String GetName() +/** + * Return the layer name (when it is not UTF-8 encoded). + *

+ * This returns the same content as GetLayerDefn().GetName(), but for a + * few drivers, calling GetName() directly can avoid lengthy layer + * definition initialization. + * + * @return the layer name + * @since 3.10 +*/ +public class Layer:public byte GetNameAsByteArray() + /** * Return the layer geometry type. *

@@ -7756,6 +7769,7 @@ public class Feature:public int[] GetFieldAsIntegerList(int ifield) * @param ifield the field to fetch, from 0 to GetFieldCount()-1. * * @return the field value. + * @see #GetFieldAsStringAsByteArray(int) */ public class Feature:public String GetFieldAsString(int ifield) @@ -7769,9 +7783,38 @@ public class Feature:public String GetFieldAsString(int ifield) * @param name the name of the field to fetch. * * @return the field value. + * @see #GetFieldAsStringAsByteArray(String) */ public class Feature:public String GetFieldAsString(String name) +/** + * Fetch field value as a string (when it is not UTF-8 encoded). + *

+ * OFTReal and OFTInteger fields will be translated to string using + * sprintf(), but not necessarily using the established formatting rules. + * Other field types, or errors will result in a return value of zero. + * + * @param ifield the field to fetch, from 0 to GetFieldCount()-1. + * + * @return the field value. + * @since 3.10 + */ +public class Feature:public byte[] GetFieldAsStringAsByteArray(int ifield) + +/** + * Fetch field value as a string (when it is not UTF-8 encoded). + *

+ * OFTReal and OFTInteger fields will be translated to string using + * sprintf(), but not necessarily using the established formatting rules. + * Other field types, or errors will result in a return value of zero. + * + * @param name the name of the field to fetch. + * + * @return the field value. + * @since 3.10 + */ +public class Feature:public byte[] GetFieldAsStringAsByteArray(String name) + /** * Fetch field value as a list of strings. *

@@ -7861,9 +7904,23 @@ public class Feature:public Geometry GetGeometryRef() * * @return a reference to a representation in string format, or null if * there isn't one. + * + * @see #GetStyleStringAsByteArray() */ public class Feature:public String GetStyleString() +/** + * Fetch style string for this feature (when it is not UTF-8 encoded). + *

+ * Set the OGR Feature Style Specification for details on the format of + * this string, and ogr_featurestyle.h for services available to parse it. + * + * @return a reference to a representation in string format, or null if + * there isn't one. + * @since 3.10 + */ +public class Feature:public byte[] GetStyleStringAsByteArray() + /** * Test if a field has ever been assigned a value or not. * @@ -9416,6 +9473,15 @@ public class FeatureDefn:public int GetFieldCount() */ public class FeatureDefn:public String GetName() +/** + * Get name of this FeatureDefn (when it is not UTF-8 encoded). + * + * @return the name + * @since 3.10 +*/ +public class FeatureDefn:public byte GetNameAsByteArray() + +/** /** * Fetch field definition. * @@ -9569,12 +9635,20 @@ public class FieldDefn:public String GetFieldTypeName(int type) public class FieldDefn:public int GetJustify() /** - * Fetch name of this field. + * Get the name of this field. * * @return the name of the field */ public class FieldDefn:public String GetName() +/** + * Get the name of this field (when it is not UTF-8 encoded). + * + * @return the name of the field + * @since 3.10 +*/ +public class FieldDefn:public byte GetNameAsByteArray() + /** * Fetch name of this field. * diff --git a/swig/java/test_data/iso_8859_1.csv b/swig/java/test_data/iso_8859_1.csv new file mode 100644 index 000000000000..f4ef83814f21 --- /dev/null +++ b/swig/java/test_data/iso_8859_1.csv @@ -0,0 +1,2 @@ +id,field_éx +1,xéx