Files
hdf5/test/json_vol_connector.c
2019-04-01 15:17:53 -07:00

259 lines
10 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Purpose: A virtual object layer (VOL) connector that uses JSON to
* store HDF5 data and metadata.
*
* The JSON representation is taken from hdf5-json, though
* that code can't be directly used because it's in Python.
* (https://github.com/HDFGroup/hdf5-json)
*/
#include "hdf5.h"
#include "H5PLextern.h"
#include "json_vol_connector.h"
/* XXX: Note that we're going to have to guard most of the JSON VOL
* connector content with #ifdefs in the final product...
*/
/* The Jansson JSON parser */
#include <jansson.h>
/* libuuid for generating UUIDs */
#include <uuid/uuid.h>
#define SUCCEED 0
#define FAIL (-1)
/* Callbacks */
/* File */
static void *jvc_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
static void *jvc_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
static herr_t jvc_file_close(void *file, hid_t dxpl_id, void **req);
/* The VOL class struct */
static const H5VL_class_t json_vol_g = {
JSON_VOL_CONNECTOR_VERSION, /* version */
JSON_VOL_CONNECTOR_VALUE, /* value */
JSON_VOL_CONNECTOR_NAME, /* name */
0, /* capability flags */
NULL, /* initialize */
NULL, /* terminate */
{ /* info_cls */
(size_t)0, /* info size */
NULL, /* info copy */
NULL, /* info compare */
NULL, /* info free */
NULL, /* info to str */
NULL /* str to info */
},
{ /* wrap_cls */
NULL, /* get_object */
NULL, /* get_wrap_ctx */
NULL, /* wrap_object */
NULL /* free_wrap_ctx */
},
{ /* attribute_cls */
NULL, /* create */
NULL, /* open */
NULL, /* read */
NULL, /* write */
NULL, /* get */
NULL, /* specific */
NULL, /* optional */
NULL /* close */
},
{ /* dataset_cls */
NULL, /* create */
NULL, /* open */
NULL, /* read */
NULL, /* write */
NULL, /* get */
NULL, /* specific */
NULL, /* optional */
NULL /* close */
},
{ /* datatype_cls */
NULL, /* commit */
NULL, /* open */
NULL, /* get_size */
NULL, /* specific */
NULL, /* optional */
NULL /* close */
},
{ /* file_cls */
jvc_file_create, /* create */
jvc_file_open, /* open */
NULL, /* get */
NULL, /* specific */
NULL, /* optional */
jvc_file_close /* close */
},
{ /* group_cls */
NULL, /* create */
NULL, /* open */
NULL, /* get */
NULL, /* specific */
NULL, /* optional */
NULL /* close */
},
{ /* link_cls */
NULL, /* create */
NULL, /* copy */
NULL, /* move */
NULL, /* get */
NULL, /* specific */
NULL /* optional */
},
{ /* object_cls */
NULL, /* open */
NULL, /* copy */
NULL, /* get */
NULL, /* specific */
NULL /* optional */
},
{ /* request_cls */
NULL, /* wait */
NULL, /* notify */
NULL, /* cancel */
NULL, /* specific */
NULL, /* optional */
NULL /* free */
},
NULL /* optional */
};
/* These two functions are necessary to load this plugin using
* the HDF5 library.
*/
H5PL_type_t H5PLget_plugin_type(void) {return H5PL_TYPE_VOL;}
const void *H5PLget_plugin_info(void) {return &json_vol_g;}
/******************/
/* IMPLEMENTATION */
/******************/
typedef struct json_vol_file_t {
FILE *fp; /* File pointer to JSON file */
json_t *root; /* Root of the JSON tree */
json_t *groups; /* JSON array of groups */
} json_vol_file_t;
#if 0
/* Helper functions */
static herr_t
jvc_helper_create_group(json_vol_file_t *jfile, char *group_name)
{
return SUCCEED;
} /* end jvc_helper_create_group() */
#endif
/* File callback implementation */
static void *
jvc_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req)
{
json_vol_file_t *jfile = NULL;
/* Set up */
if(NULL == (jfile = (json_vol_file_t *)calloc((size_t)1, sizeof(json_vol_file_t))))
goto error;
/* Create the file */
if(NULL == (jfile->fp = fopen(name, "w")))
goto error;
/* Create the JSON root */
jfile->root = json_object();
/* Add the groups array */
jfile->groups = json_array();
json_object_set_new(jfile->root, "groups", jfile->groups);
return (void *)jfile;
error:
if(jfile->fp)
fclose(jfile->fp);
if(jfile)
free(jfile);
return NULL;
} /* end jvc_file_create() */
static void *
jvc_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req)
{
json_vol_file_t *jfile = NULL;
char *json_in = NULL;
long int file_size;
json_error_t jerror;
/* Set up */
if(NULL == (jfile = (json_vol_file_t *)calloc((size_t)1, sizeof(json_vol_file_t))))
goto error;
/* Open the file and get the size */
if(NULL == (jfile->fp = fopen(name, "r")))
goto error;
fseek(jfile->fp, 0, SEEK_END);
file_size = ftell(jfile->fp);
fseek(jfile->fp, 0, SEEK_SET);
/* Create the JSON root */
if(NULL == (json_in = (char *)malloc((size_t)(file_size + 1) * sizeof(char))))
goto error;
fread(json_in, (size_t)file_size, 1, jfile->fp);
jfile->root = json_loads(json_in, 0, &jerror);
/* Will still need to parse out the groups array */
free(json_in);
return (void *)jfile;
error:
if(json_in)
free(json_in);
if(jfile->fp)
fclose(jfile->fp);
if(jfile)
free(jfile);
return NULL;
} /* end jvc_file_open() */
static herr_t
jvc_file_close(void *file, hid_t dxpl_id, void **req)
{
json_vol_file_t *jfile = (json_vol_file_t *)file;
/* Dump the JSON string to the file */
fprintf(jfile->fp, "%s", json_dumps(jfile->root, 0));
/* Close the file */
if(EOF == fclose(jfile->fp))
goto error;
/* Decrement the reference count on the JSON root, closing it */
json_decref(jfile->root);
/* Tear down */
free(jfile);
return SUCCEED;
error:
return FAIL;
} /* end jvc_file_close() */