Beispiel #1
0
/*
 * Class:     hdf_hdf5lib_H5
 * Method:    H5Pget_elink_prefix
 * Signature: (J[Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL
Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix
    (JNIEnv *env, jclass clss, jlong lapl_id, jobjectArray prefix)
{
    ssize_t  prefix_size = -1;
    size_t   size = 0;
    char    *pre = NULL;
    jstring  str = NULL;

    UNUSED(clss);

    if (NULL == prefix)
        H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_elink_prefix: prefix is NULL");

    if ((prefix_size = H5Pget_elink_prefix((hid_t)lapl_id, (char *)NULL, size)) < 0)
        H5_LIBRARY_ERROR(ENVONLY);

    if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t) prefix_size + 1)))
        H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: memory allocation failed");

    if (H5Pget_elink_prefix((hid_t)lapl_id, (char *)pre, (size_t) prefix_size + 1) < 0)
        H5_LIBRARY_ERROR(ENVONLY);
    pre[prefix_size] = '\0';

    if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) {
        CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
        H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: out of memory - unable to construct string from UTF characters");
    }

    ENVPTR->SetObjectArrayElement(ENVONLY, prefix, 0, str);
    CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);

done:
    if (pre)
        HDfree(pre);

    return (jlong)prefix_size;
} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix */
/* "Windows to Unix" traversal function for external links
 *
 * Translates a filename stored in Unix format to Windows format by replacing
 * forward slashes with backslashes.
 * Makes no attempt to handle Windows drive names (e.g., "C:\"), spaces within
 * file names, quotes, etc.  These are left as an exercise for the user. :)
 * Note that this may not be necessary on your system; many Windows systems can
 * understand Unix paths.
 */
static hid_t elink_unix2win_trav(const char *link_name, hid_t cur_group,
    const void *udata, size_t udata_size, hid_t lapl_id)
{
    hid_t         fid;
    const char   *file_name;
    const char   *obj_name;
    char         *new_fname = NULL;     /* Buffer allocated to hold Unix file path */
    ssize_t       prefix_len;           /* External link prefix length */
    size_t        fname_len;
    size_t        start_pos;            /* Initial position in new_fname buffer */
    size_t        x;                    /* Counter variable */
    hid_t         ret_value = -1;

    printf("Converting Unix path to Windows path.\n");

    if(H5Lunpack_elink_val(udata, udata_size, NULL, &file_name, &obj_name) < 0)
        goto error;
    fname_len = strlen(file_name);

    /* See if the external link prefix property is set */
    if((prefix_len = H5Pget_elink_prefix(lapl_id, NULL, 0)) < 0)
        goto error;

    /* If so, prepend it to the filename.  We assume that the prefix
     * is in the correct format for the current file system.
     */
    if(prefix_len > 0)
    {
        /* Allocate a buffer to hold the filename plus prefix */
        new_fname = malloc(prefix_len + fname_len + 1);

        /* Copy the prefix into the buffer */
        if(H5Pget_elink_prefix(lapl_id, new_fname, (size_t)(prefix_len + 1)) < 0)
            goto error;

        start_pos = prefix_len;
    }
    else
    {
        /* Allocate a buffer to hold just the filename */
        new_fname = malloc(fname_len + 1);
        start_pos = 0;
    }

    /* We should now copy file_name into new_fname starting at position pos.
     * We'll convert '/' characters into '\' characters as we go.
     */
    for(x=0; file_name[x] != '\0'; x++)
    {
        if(file_name[x] == '/')
            new_fname[x + start_pos] = '\\';
        else
            new_fname[x + start_pos] = file_name[x];
    }
    new_fname[x + start_pos] = '\0';

    /* Now open the file and object within it */
    if((fid = H5Fopen(new_fname, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
        goto error;
    ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */
    if(H5Fclose(fid) < 0)
        goto error;

    /* Free file name if it's been allocated */
    if(new_fname)
        free(new_fname);

    return ret_value;

error:
    /* Free file name if it's been allocated */
    if(new_fname)
        free(new_fname);
    return -1;
}