in src/main/c/h3-java/src/jniapi.c [147:204]
H3Error CreateGeoPolygon(JNIEnv *env, jdoubleArray verts, jintArray holeSizes,
jdoubleArray holeVerts, GeoPolygon *polygon) {
// This is the number of doubles, so convert to number of verts
polygon->geoloop.numVerts = (**env).GetArrayLength(env, verts) / 2;
polygon->geoloop.verts = (**env).GetDoubleArrayElements(env, verts, 0);
if (polygon->geoloop.verts != NULL) {
polygon->numHoles = (**env).GetArrayLength(env, holeSizes);
if (polygon->numHoles > 0) {
polygon->holes = calloc(polygon->numHoles, sizeof(GeoPolygon));
if (polygon->holes == NULL) {
(**env).ReleaseDoubleArrayElements(
env, verts, polygon->geoloop.verts, JNI_ABORT);
ThrowOutOfMemoryError(env);
return E_MEMORY_ALLOC;
}
jint *holeSizesElements =
(**env).GetIntArrayElements(env, holeSizes, 0);
if (holeSizesElements == NULL) {
(**env).ReleaseDoubleArrayElements(
env, verts, polygon->geoloop.verts, JNI_ABORT);
free(polygon->holes);
ThrowOutOfMemoryError(env);
return E_MEMORY_ALLOC;
}
jdouble *holeVertsElements =
(**env).GetDoubleArrayElements(env, holeVerts, 0);
if (holeVertsElements == NULL) {
(**env).ReleaseDoubleArrayElements(
env, verts, polygon->geoloop.verts, JNI_ABORT);
free(polygon->holes);
(**env).ReleaseIntArrayElements(env, holeSizes,
holeSizesElements, JNI_ABORT);
ThrowOutOfMemoryError(env);
return E_MEMORY_ALLOC;
}
size_t offset = 0;
for (int i = 0; i < polygon->numHoles; i++) {
// This is the number of doubles, so convert to number of verts
polygon->holes[i].numVerts = holeSizesElements[i] / 2;
polygon->holes[i].verts = holeVertsElements + offset;
offset += holeSizesElements[i];
}
(**env).ReleaseIntArrayElements(env, holeSizes, holeSizesElements,
JNI_ABORT);
// holeVertsElements is not released here because it is still being
// pointed to by polygon->holes[*].verts. It will be released in
// DestroyGeoPolygon.
}
return E_SUCCESS;
} else {
ThrowOutOfMemoryError(env);
return E_MEMORY_ALLOC;
}
}