H3Error CreateGeoPolygon()

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;
    }
}