[cig-commits] r12839 - in cs/cigma/trunk/src: . h5io h5io/t
luis at geodynamics.org
luis at geodynamics.org
Wed Sep 10 12:50:40 PDT 2008
Author: luis
Date: 2008-09-10 12:50:40 -0700 (Wed, 10 Sep 2008)
New Revision: 12839
Added:
cs/cigma/trunk/src/h5io/
cs/cigma/trunk/src/h5io/Makefile
cs/cigma/trunk/src/h5io/Makefile.dep
cs/cigma/trunk/src/h5io/h5array.c
cs/cigma/trunk/src/h5io/h5attr.c
cs/cigma/trunk/src/h5io/h5dset.c
cs/cigma/trunk/src/h5io/h5file.c
cs/cigma/trunk/src/h5io/h5group.c
cs/cigma/trunk/src/h5io/h5io.h
cs/cigma/trunk/src/h5io/split.c
cs/cigma/trunk/src/h5io/split.h
cs/cigma/trunk/src/h5io/t/
cs/cigma/trunk/src/h5io/t/Makefile
cs/cigma/trunk/src/h5io/t/test_h5dset.c
cs/cigma/trunk/src/h5io/t/test_h5file.c
cs/cigma/trunk/src/h5io/t/test_h5group.c
Log:
Source files for h5io library
Added: cs/cigma/trunk/src/h5io/Makefile
===================================================================
--- cs/cigma/trunk/src/h5io/Makefile (rev 0)
+++ cs/cigma/trunk/src/h5io/Makefile 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,37 @@
+include ../variables
+
+LIB = ../lib/libh5io.a
+
+CFLAGS = $(OPTIM) $(FLAGS)
+
+SRC = \
+ h5array.c \
+ h5attr.c \
+ h5dset.c \
+ h5file.c \
+ h5group.c \
+ split.c \
+
+OBJ = $(SRC:.c=.o)
+
+.SUFFIXES: .o .c
+
+$(LIB): $(OBJ)
+ $(AR) $(LIB) $(OBJ)
+ $(RANLIB) $(LIB)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+tests:
+ cd t && make tests
+
+clean:
+ rm -f *.o
+ cd t && make clean
+
+-include Makefile.dep
+depend:
+ $(CC) -MM $(SRC) > Makefile.dep
+
+.PHONY: clean depend
Added: cs/cigma/trunk/src/h5io/Makefile.dep
===================================================================
--- cs/cigma/trunk/src/h5io/Makefile.dep (rev 0)
+++ cs/cigma/trunk/src/h5io/Makefile.dep 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,6 @@
+h5array.o: h5array.c h5io.h
+h5attr.o: h5attr.c h5io.h
+h5dset.o: h5dset.c h5io.h
+h5file.o: h5file.c h5io.h
+h5group.o: h5group.c h5io.h split.h
+split.o: split.c split.h
Added: cs/cigma/trunk/src/h5io/h5array.c
===================================================================
--- cs/cigma/trunk/src/h5io/h5array.c (rev 0)
+++ cs/cigma/trunk/src/h5io/h5array.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,428 @@
+#include <stdlib.h>
+#include "hdf5.h"
+#include "h5io.h"
+
+
+int h5io_array_init(h5array_t *array, hid_t type_id, int rank, int *shape, void *data)
+{
+ int i;
+
+ /* initialize dataspace */
+ array->rank = rank;
+ array->shape = (hsize_t *)malloc(rank * sizeof(hsize_t));
+ if (shape != NULL)
+ {
+ for (i = 0; i < rank; i++)
+ array->shape[i] = shape[i];
+ }
+ else
+ {
+ for (i = 0; i < rank; i++)
+ array->shape[i] = 0;
+ }
+
+ /* initialize datatype */
+ array->type_id = type_id;
+
+ /* initialize data */
+ array->data = data;
+
+ return 0;
+}
+
+int h5io_array_free_dims(h5array_t *array)
+{
+ free(array->shape);
+ return 0;
+}
+
+int h5io_array_free_data(h5array_t *array)
+{
+ if (array->data != NULL)
+ {
+ free(array->data);
+ }
+ return 0;
+}
+
+int h5io_array_free(h5array_t *array)
+{
+ h5io_array_free_dims(array);
+ h5io_array_free_data(array);
+ return 0;
+}
+
+
+
+int h5io_array_npoints(h5array_t *array)
+{
+ int i;
+ int npoints = 1;
+ for (i = 0; i < array->rank; i++)
+ {
+ npoints *= (int) array->shape[i];
+ }
+ return npoints;
+}
+
+int h5io_array_dim(h5array_t *array, int i)
+{
+ if ((0 <= i) && (i < array->rank))
+ {
+ return (int)(array->shape[i]);
+ }
+ return 0;
+}
+
+void h5io_array_dims(h5array_t *array, int *rank, int **shape)
+{
+ int i;
+
+ *rank = array->rank;
+ *shape = (int *)malloc((array->rank) * sizeof(int));
+
+ for (i = 0; i < array->rank; i++)
+ {
+ (*shape)[i] = (int) array->shape[i];
+ }
+}
+
+void h5io_array_dims1(h5array_t *array, int *n)
+{
+ *n = array->shape[0];
+}
+
+void h5io_array_dims2(h5array_t *array, int *m, int *n)
+{
+ *m = array->shape[0];
+ *n = array->shape[1];
+}
+void h5io_array_dims3(h5array_t *array, int *l, int *m, int *n)
+{
+ *l = array->shape[0];
+ *m = array->shape[1];
+ *n = array->shape[2];
+}
+
+
+
+hid_t h5io_array_open(h5array_t *array, hid_t loc_id, const char *name)
+{
+ hid_t dataset_id;
+ hid_t dataspace_id;
+ herr_t status;
+
+ dataset_id = H5Dopen(loc_id, name);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ dataspace_id = H5Dget_space(dataset_id);
+ if (dataspace_id < 0)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ array->rank = H5Sget_simple_extent_ndims(dataspace_id);
+
+ status = H5Sget_simple_extent_dims(dataspace_id, array->shape, NULL);
+
+ status = H5Sclose(dataspace_id);
+
+ return dataset_id;
+}
+
+
+hid_t h5io_array_create(h5array_t *array, hid_t loc_id, const char *name, const char *title)
+{
+ hid_t dataspace_id;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataspace_id = H5Screate_simple(array->rank, array->shape, NULL);
+ if (dataspace_id < 0)
+ {
+ return -1;
+ }
+
+ dataset_id = H5Dcreate(loc_id, name, array->type_id, dataspace_id, H5P_DEFAULT);
+ if (dataset_id < 0)
+ {
+ H5Sclose(dataspace_id);
+ return -2;
+ }
+
+ status = h5io_attr_set_str(dataset_id, "TITLE", title);
+ status = h5io_attr_set_str(dataset_id, "CLASS", "ARRAY");
+ status = h5io_attr_set_str(dataset_id, "FLAVOR", "numpy");
+ status = h5io_attr_set_str(dataset_id, "VERSION", "2.3");
+
+ status = H5Sclose(dataspace_id);
+
+ return dataset_id;
+}
+
+
+int h5io_array_read(h5array_t *array, hid_t loc_id, const char *name)
+{
+ int npoints;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataset_id = h5io_array_open(array, loc_id, name);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ npoints = h5io_array_npoints(array);
+
+ array->data = malloc(npoints * H5Tget_size(array->type_id));
+ if (array->data == NULL)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ status = H5Dread(dataset_id, array->type_id, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Dclose(dataset_id);
+ return -3;
+ }
+
+ status = H5Dclose(dataset_id);
+
+ return 0;
+}
+
+
+
+int h5io_array_write(h5array_t *array, hid_t loc_id, const char *name)
+{
+ hid_t dataspace_id;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataspace_id = H5Screate_simple(array->rank, array->shape, NULL);
+ if (dataspace_id < 0)
+ {
+ return -1;
+ }
+
+ dataset_id = H5Dcreate(loc_id, name, array->type_id, dataspace_id,
+ H5P_DEFAULT);
+ if (dataset_id < 0)
+ {
+ H5Sclose(dataspace_id);
+ return -2;
+ }
+
+ status = H5Dwrite(dataset_id, array->type_id, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Sclose(dataspace_id);
+ H5Dclose(dataset_id);
+ return -3;
+ }
+
+ status = H5Sclose(dataspace_id);
+ status = H5Dclose(dataset_id);
+
+ return 0;
+}
+
+
+static herr_t h5io_hyperslab_init(h5array_t *array,
+ hsize_t **offset, hsize_t **stride,
+ hsize_t **count, hsize_t **block,
+ int start, int end)
+{
+ int i;
+
+ *offset = NULL;
+ *stride = NULL;
+ *count = NULL;
+ *block = NULL;
+
+ if ((start < 0) || (start > end))
+ {
+ return -1;
+ }
+
+ if (start >= array->rank)
+ {
+ return -2;
+ }
+
+ if (array->rank == 0)
+ {
+ return -3;
+ }
+
+ *offset = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *stride = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *count = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *block = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+
+ /* first, select everything */
+ for (i = 0; i < array->rank; i++)
+ {
+ (*offset)[i] = 0;
+ (*block )[i] = array->shape[i];
+ (*stride)[i] = 1;
+ (*count )[i] = 1;
+ }
+
+ /* now, do the selection on the first dimension only */
+ // TODO: add column to argument list
+ (*offset)[0] = start;
+ (*block )[0] = end - start;
+
+ return 0;
+}
+
+static void h5io_hyperslab_free(hsize_t *offset, hsize_t *stride,
+ hsize_t *count, hsize_t *block)
+{
+ if (offset != NULL) free(offset);
+ if (stride != NULL) free(stride);
+ if (count != NULL) free(count);
+ if (block != NULL) free(block);
+}
+
+
+
+int h5io_array_slice_read(h5array_t *array, hid_t dataset_id, int start, int end)
+{
+ hsize_t *offset, *stride, *count, *block;
+ hid_t memspace_id;
+ hid_t filespace_id;
+ herr_t status;
+
+ status = h5io_hyperslab_init(array,
+ &offset, &stride,
+ &count, &block,
+ start, end);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ memspace_id = H5Screate_simple(array->rank, block, NULL);
+ if (memspace_id < 0)
+ {
+ return -2;
+ }
+
+ filespace_id = H5Dget_space(dataset_id);
+ if (filespace_id < 0)
+ {
+ H5Sclose(memspace_id);
+ return -3;
+ }
+
+ if (array->data == NULL)
+ {
+ int i;
+ int npoints = 1;
+
+ for (i = 0; i < array->rank; i++)
+ {
+ npoints *= block[i];
+ }
+
+ array->data = malloc(npoints * H5Tget_size(array->type_id));
+ if (array->data == NULL)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -4;
+ }
+ }
+
+ status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
+ offset, stride, count, block);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -5;
+ }
+
+ status = H5Dread(dataset_id, array->type_id, memspace_id, filespace_id,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -5;
+ }
+
+ status = H5Sclose(memspace_id);
+ status = H5Sclose(filespace_id);
+
+ h5io_hyperslab_free(offset, stride, count, block);
+
+ return 0;
+}
+
+int h5io_array_slice_write(h5array_t *array, hid_t dataset_id, int start, int end)
+{
+ hsize_t *offset, *stride, *count, *block;
+ hid_t memspace_id;
+ hid_t filespace_id;
+ herr_t status;
+
+ status = h5io_hyperslab_init(array,
+ &offset, &stride,
+ &count, &block,
+ start, end);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ memspace_id = H5Screate_simple(array->rank, block, NULL);
+ if (memspace_id < 0)
+ {
+ return -2;
+ }
+
+ filespace_id = H5Dget_space(dataset_id);
+ if (filespace_id < 0)
+ {
+ H5Sclose(memspace_id);
+ return -3;
+ }
+
+ status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
+ offset, stride, count, block);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -4;
+ }
+
+ status = H5Dwrite(dataset_id, array->type_id, memspace_id, filespace_id,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -5;
+ }
+
+ status = H5Sclose(memspace_id);
+ status = H5Sclose(filespace_id);
+
+ h5io_hyperslab_free(offset, stride, count, block);
+
+ return 0;
+}
+
Added: cs/cigma/trunk/src/h5io/h5attr.c
===================================================================
--- cs/cigma/trunk/src/h5io/h5attr.c (rev 0)
+++ cs/cigma/trunk/src/h5io/h5attr.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,549 @@
+#include <stdlib.h>
+#include <string.h>
+#include "hdf5.h"
+#include "h5io.h"
+
+/****************************************************************************
+ * Some of the following functions were based or taken from the H5ATTR.c *
+ * source file in PyTables, which is a BSD-licensed python extension *
+ * for accessing HDF5 files. *
+ * *
+ * The copyright notice is hereby retained. *
+ * *
+ * NCSA HDF *
+ * Scientific Data Technologies *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ * Modified versions of H5LT for getting and setting attributes for open *
+ * groups and leaves. *
+ * F. Altet 2005/09/29 *
+ * *
+ ****************************************************************************/
+
+
+/*
+ * attr_find_op - operator function used by h5io_attr_find
+ *
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - June 21, 2001)
+ */
+static herr_t attr_find_op(hid_t loc_id, const char *name, void *op_data)
+{
+ /* Define a default zero value for return. This will cause the
+ * iterator to continue if the palette attribute is not found yet.
+ */
+ int ret = 0;
+
+ char *attr_name = (char *)op_data;
+
+ /* Shut the compiler up */
+ loc_id = loc_id;
+
+ /*
+ * Define a positive value for return value if the attribute was
+ * found. This will cause the iterator to immediately return that
+ * positive value, indicating short-circuit success
+ */
+
+ if (strcmp(name, attr_name) == 0)
+ {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+
+
+/*
+ * h5io_attr_find - Inquires if an attribute named attr_name exists attached
+ * to the object loc_id. This function uses H5Aiterate with the operator
+ * function attr_find_op.
+ *
+ * Success: The return value of the first operator that returns
+ * non-zero, or zero if all members were processed with no
+ * operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the library,
+ * or the negative value returned by one of the operators.
+ *
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - June 21, 2001)
+ */
+herr_t h5io_attr_find(hid_t loc_id, const char *attr_name)
+{
+ unsigned int attr_num;
+ herr_t ret;
+
+ attr_num = 0;
+ ret = H5Aiterate(loc_id, &attr_num, attr_find_op, (void *)attr_name);
+
+ return ret;
+}
+
+
+/* h5io_attr_set - Sets an attribute named attr_name.
+ * On success it returns 0, while on failure it returns -1.
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - July 25, 2001)
+ */
+herr_t h5io_attr_set(hid_t obj_id, const char *attr_name, hid_t type_id, const void *data)
+{
+ hid_t space_id, attr_id;
+ herr_t status;
+
+ int has_attr;
+
+ /* Create the data space for the attribute. */
+ space_id = H5Screate(H5S_SCALAR);
+ if (space_id < 0)
+ {
+ goto out;
+ }
+
+ /* Verify if the attribute already exists. */
+ has_attr = h5io_attr_find(obj_id, attr_name);
+ if (has_attr == 1)
+ {
+ /* The attribute already exists. Delete it. */
+ status = H5Adelete(obj_id, attr_name);
+ if (status < 0)
+ {
+ goto out;
+ }
+ }
+
+ /* Create the attribute. */
+ attr_id = H5Acreate(obj_id, attr_name, type_id, space_id, H5P_DEFAULT);
+ if (attr_id < 0)
+ {
+ goto out;
+ }
+
+ /* Write the attribute data. */
+ status = H5Awrite(attr_id, type_id, data);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Close the attribute. */
+ status = H5Aclose(attr_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Close the data space. */
+ status = H5Sclose(space_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ return 0;
+
+out:
+ return -1;
+}
+
+
+/*
+ * h5io_attr_get - reads an attribute named attr_name with the memory
+ * type type_id. On success it returns 0, while on failure it returns -1.
+ *
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - September 19, 2002)
+ */
+herr_t h5io_attr_get(hid_t obj_id, const char *attr_name, hid_t type_id, void *data)
+{
+ hid_t attr_id;
+ herr_t status;
+
+ attr_id = H5Aopen_name(obj_id, attr_name);
+ if (attr_id < 0)
+ {
+ return -1;
+ }
+
+ status = H5Aread(attr_id, type_id, data);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Aclose(attr_id);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ return 0;
+
+out:
+ H5Aclose(attr_id);
+ return -1;
+}
+
+
+
+/*
+ * h5io_attr_get_dims - Gets the dimensionality of an attribute.
+ * On success it returns 0, while on failure it returns -1.
+ *
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - September 4, 2001)
+ */
+herr_t h5io_attr_get_dims(hid_t obj_id, const char *attr_name, int *rank, hsize_t *dims)
+{
+ hid_t attr_id;
+ hid_t space_id;
+ herr_t status;
+
+ /* Open the attribute */
+ attr_id = H5Aopen_name(obj_id, attr_name);
+ if (attr_id < 0)
+ {
+ return -1;
+ }
+
+ /* Get the dataspace handle */
+ space_id = H5Aget_space(attr_id);
+ if (space_id < 0)
+ {
+ goto out;
+ }
+
+ /* Get the number of dimensions */
+ *rank = H5Sget_simple_extent_ndims(space_id);
+ if (*rank < 0)
+ {
+ goto out;
+ }
+
+ /* Get dimensions */
+ status = H5Sget_simple_extent_dims(space_id, dims, NULL);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Terminate access to the dataspace */
+ status = H5Sclose(space_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* End access to the attribute */
+ status = H5Aclose(attr_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ return 0;
+
+out:
+ H5Aclose(attr_id);
+ return -1;
+}
+
+/*
+ * h5io_attr_set_str - Creates and writes a string attribute named attr_name
+ * and attahes it to the object specified by obj_id. If the attribute already
+ * exists, it is overwritten. On success it returns 0, while on failure
+ * it returns -1.
+ *
+ * (Pedro Vicente, pvn at ncsa.uiuc.edu - July 23, 2001)
+ */
+herr_t h5io_attr_set_str(hid_t obj_id,
+ const char *attr_name,
+ const char *attr_data)
+{
+ hid_t attr_type;
+ hid_t attr_size;
+ hid_t attr_space_id;
+ hid_t attr_id;
+ int has_attr;
+ herr_t status;
+
+ /* Create the attribute */
+ attr_type = H5Tcopy(H5T_C_S1);
+ if (attr_type < 0)
+ {
+ goto out;
+ }
+
+ attr_size = strlen(attr_data) + 1; /* extra null term */
+
+ status = H5Tset_size(attr_type, (size_t)attr_size);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Tset_strpad(attr_type, H5T_STR_NULLTERM);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ attr_space_id = H5Screate(H5S_SCALAR);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Verify if the attribute already exists */
+ has_attr = h5io_attr_find(obj_id, attr_name);
+
+ /* If the attribute already exists, delete it */
+ if (has_attr == 1)
+ {
+ status = H5Adelete(obj_id, attr_name);
+ if (status < 0)
+ {
+ goto out;
+ }
+ }
+
+ /* Create the attribute. */
+ attr_id = H5Acreate(obj_id, attr_name, attr_type, attr_space_id,
+ H5P_DEFAULT);
+ if (attr_id < 0)
+ {
+ goto out;
+ }
+
+ /* Write the attribute data. */
+ status = H5Awrite(attr_id, attr_type, attr_data);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Aclose(attr_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Sclose(attr_space_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Tclose(attr_type);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ return 0;
+
+out:
+ return -1;
+}
+
+
+
+/*
+ * h5io_attr_get_str - Reads a string attribute named attr_name.
+ * On success it returns 0, while on failure it returns -1.
+ *
+ * (Francesc Altet, faltet at carabos.com - February 23, 2005)
+ */
+herr_t h5io_attr_get_str(hid_t obj_id, const char *attr_name, char **data)
+{
+ hid_t attr_id;
+ hid_t attr_type;
+ size_t type_size;
+ herr_t status;
+
+ *data = NULL;
+
+ attr_id = H5Aopen_name(obj_id, attr_name);
+ if (attr_id < 0)
+ {
+ return -1;
+ }
+
+ attr_type = H5Aget_type(attr_id);
+ if (attr_type < 0)
+ {
+ goto out;
+ }
+
+ /* Get the size */
+ type_size = H5Tget_size(attr_type);
+ if (type_size < 0)
+ {
+ goto out;
+ }
+
+ /* Malloc enough space for the string, plus 1 for the trailing '\0' */
+ *data = (char *)malloc((type_size + 1) * sizeof(char));
+
+ status = H5Aread(attr_id, attr_type, *data);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Set the last character to \0 in case we are dealing with
+ * space padded strings.
+ */
+ (*data)[type_size] = '\0';
+
+ /* TODO: check that following statement doesn't fail */
+ status = H5Tclose(attr_type);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ status = H5Aclose(attr_id);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ return 0;
+
+out:
+
+ if (attr_type != 0)
+ H5Tclose(attr_type);
+
+ H5Aclose(attr_id);
+
+ if (*data)
+ free(*data);
+
+ return -1;
+}
+
+
+
+/*
+ * h5io_attr_set_array - write an array attribute. Returns 0 on success,
+ * and -1 on failure. (July 25, 2001)
+ */
+herr_t h5io_attr_set_array(hid_t obj_id,
+ const char *attr_name,
+ size_t rank,
+ hsize_t *dims,
+ hid_t type_id,
+ const void *data)
+{
+ hid_t space_id, attr_id;
+ herr_t status;
+
+ int has_attr;
+
+ /* Create the data space for the attribute. */
+ space_id = H5Screate_simple(rank, dims, NULL);
+ if (space_id < 0)
+ {
+ goto out;
+ }
+
+ /* Verify if the attribute already exists. */
+ has_attr = h5io_attr_find(obj_id, attr_name);
+ if (has_attr == 1)
+ {
+ /* The attribute already exists. Delete it. */
+ status = H5Adelete(obj_id, attr_name);
+ if (status < 0)
+ {
+ goto out;
+ }
+ }
+
+ /* Create the attribute. */
+ attr_id = H5Acreate(obj_id, attr_name, type_id, space_id, H5P_DEFAULT);
+ if (attr_id < 0)
+ {
+ goto out;
+ }
+
+ /* Write the attribute data. */
+ status = H5Awrite(attr_id, type_id, data);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ /* Close the dataspace. */
+ status = H5Sclose(space_id);
+ if (status < 0)
+ {
+ goto out;
+ }
+
+ return 0;
+
+out:
+ return -1;
+}
+
+herr_t h5io_attr_set_array1(hid_t obj_id,
+ const char *attr_name,
+ hsize_t dim,
+ hid_t type_id,
+ const void *data)
+{
+ return h5io_attr_set_array(obj_id, attr_name, 1, &dim, type_id, data);
+}
+
+herr_t h5io_attr_set_array1_of_ints(hid_t obj_id,
+ const char *attr_name,
+ hsize_t dim,
+ const int *data)
+{
+ return h5io_attr_set_array(obj_id, attr_name, 1, &dim, H5T_NATIVE_INT, data);
+}
+
+herr_t h5io_attr_set_array1_of_floats(hid_t obj_id,
+ const char *attr_name,
+ hsize_t dim,
+ const float *data)
+{
+ return h5io_attr_set_array(obj_id, attr_name, 1, &dim, H5T_NATIVE_FLOAT, data);
+}
+
+herr_t h5io_attr_set_array1_of_doubles(hid_t obj_id,
+ const char *attr_name,
+ hsize_t dim,
+ const double *data)
+{
+ return h5io_attr_set_array(obj_id, attr_name, 1, &dim, H5T_NATIVE_DOUBLE, data);
+}
+
+
+herr_t h5io_attr_set_int(hid_t obj_id, const char *attr_name, int n)
+{
+ return h5io_attr_set(obj_id, attr_name, H5T_NATIVE_INT, &n);
+}
+
+herr_t h5io_attr_set_long(hid_t obj_id, const char *attr_name, long n)
+{
+ return h5io_attr_set(obj_id, attr_name, H5T_NATIVE_LONG, &n);
+}
+
+herr_t h5io_attr_set_llong(hid_t obj_id, const char *attr_name, long long n)
+{
+ return h5io_attr_set(obj_id, attr_name, H5T_NATIVE_LLONG, &n);
+}
+
+herr_t h5io_attr_set_float(hid_t obj_id, const char *attr_name, float x)
+{
+ return h5io_attr_set(obj_id, attr_name, H5T_NATIVE_FLOAT, &x);
+}
+
+herr_t h5io_attr_set_double(hid_t obj_id, const char *attr_name, double x)
+{
+ return h5io_attr_set(obj_id, attr_name, H5T_NATIVE_DOUBLE, &x);
+}
Added: cs/cigma/trunk/src/h5io/h5dset.c
===================================================================
--- cs/cigma/trunk/src/h5io/h5dset.c (rev 0)
+++ cs/cigma/trunk/src/h5io/h5dset.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,245 @@
+#include <stdlib.h>
+#include "hdf5.h"
+#include "h5io.h"
+
+
+hid_t h5io_dset_create(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, int rank, int *shape)
+{
+ hid_t dataset_id;
+ hid_t dataspace_id;
+ herr_t status;
+
+ if (rank > 0)
+ {
+ hsize_t *dims;
+ int i;
+ dims = (hsize_t *)malloc(rank * sizeof(hsize_t));
+ for (i = 0; i < rank; i++)
+ {
+ dims[i] = shape[i];
+ }
+
+ dataspace_id = H5Screate_simple(rank, dims, NULL);
+ if (dataspace_id < 0)
+ {
+ free(dims);
+ return -1;
+ }
+ free(dims);
+ }
+ else
+ {
+ return -3;
+ }
+
+ dataset_id = H5Dcreate(loc_id, name, type_id, dataspace_id, H5P_DEFAULT);
+ if (dataset_id < 0)
+ {
+ H5Sclose(dataspace_id);
+ return -2;
+ }
+
+ status = h5io_attr_set_str(dataset_id, "TITLE", title);
+ status = h5io_attr_set_str(dataset_id, "CLASS", "ARRAY");
+ status = h5io_attr_set_str(dataset_id, "FLAVOR", "numpy");
+ status = h5io_attr_set_str(dataset_id, "VERSION", "2.3");
+
+ status = H5Sclose(dataspace_id);
+
+ return dataset_id;
+}
+
+
+hid_t h5io_dset_open(hid_t loc_id, const char *name,
+ hid_t *type_id, int *rank, int *shape, int *npoints)
+{
+ hid_t dataset_id;
+ hid_t dataspace_id;
+ herr_t status;
+
+ dataset_id = H5Dopen(loc_id, name);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ if (type_id != NULL)
+ {
+ *type_id = H5Dget_type(dataset_id);
+ }
+
+ if ((rank != NULL) || (shape != NULL) || (npoints != NULL))
+ {
+ dataspace_id = H5Dget_space(dataset_id);
+
+ if (rank != NULL)
+ {
+ *rank = H5Sget_simple_extent_ndims(dataspace_id);
+ }
+
+ // TODO: think about the shape[] array. should we allocate
+ // it here instead of copying it to a fixed array?
+ // after all, even the rank is unknown before opening
+ // a dataset. note that the type would then have to
+ // change to "int **shape"
+ if (shape != NULL)
+ {
+ int i;
+ hsize_t *dims;
+
+ dims = (hsize_t *)malloc((*rank) * sizeof(hsize_t));
+ status = H5Sget_simple_extent_dims(dataspace_id, dims, NULL);
+ for (i = 0; i < *rank; i++)
+ {
+ shape[i] = (int)dims[i];
+ }
+ free(dims);
+ }
+
+ if (npoints != NULL)
+ {
+ *npoints = H5Sget_simple_extent_npoints(dataspace_id);
+ }
+
+ status = H5Sclose(dataspace_id);
+ }
+
+ return dataset_id;
+}
+
+
+
+int h5io_dset_read(hid_t loc_id, const char *name,
+ hid_t type_id, int rank, int *shape, void **data)
+{
+ int dset_rank;
+ int dset_npts;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataset_id = h5io_dset_open(loc_id, name, NULL, &dset_rank, shape, &dset_npts);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+ if (rank != dset_rank)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ *data = malloc(dset_npts * H5Tget_size(type_id));
+ if (*data == NULL)
+ {
+ H5Dclose(dataset_id);
+ return -3;
+ }
+
+ status = H5Dread(dataset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, *data);
+ if (status < 0)
+ {
+ H5Dclose(dataset_id);
+ return -4;
+ }
+
+ status = H5Dclose(dataset_id);
+
+ return 0;
+}
+
+int h5io_dset_read1(hid_t loc_id,
+ const char *name,
+ hid_t type_id,
+ void **data, int *n)
+{
+ return h5io_dset_read(loc_id, name, type_id, 1, n, data);
+}
+
+int h5io_dset_read2(hid_t loc_id,
+ const char *name,
+ hid_t type_id,
+ void **data, int *m, int *n)
+{
+ int shape[2];
+ int ret;
+
+ ret = h5io_dset_read(loc_id, name, type_id, 2, shape, data);
+
+ *m = shape[0];
+ *n = shape[1];
+
+ return ret;
+}
+
+int h5io_dset_read3(hid_t loc_id,
+ const char *name,
+ hid_t type_id,
+ void **data, int *l, int *m, int *n)
+{
+ int shape[3];
+ int ret;
+
+ ret = h5io_dset_read(loc_id, name, type_id, 3, shape, data);
+
+ *l = shape[0];
+ *m = shape[1];
+ *n = shape[2];
+
+ return ret;
+}
+
+
+int h5io_dset_write(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, int rank, int *shape, void *data)
+{
+ hid_t dataset_id;
+ herr_t status;
+
+ dataset_id = h5io_dset_create(loc_id, name, title, type_id, rank, shape);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ status = H5Dwrite(dataset_id, type_id, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, data);
+ if (status < 0)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ H5Dclose(dataset_id);
+ return 0;
+}
+
+int h5io_dset_write1(hid_t loc_id,
+ const char *name,
+ const char *title,
+ hid_t type_id,
+ void *data, int n)
+{
+ return h5io_dset_write(loc_id, name, title, type_id, 1, &n, data);
+}
+
+int h5io_dset_write2(hid_t loc_id,
+ const char *name,
+ const char *title,
+ hid_t type_id,
+ void *data, int m, int n)
+{
+ int dims[2] = {m,n};
+ return h5io_dset_write(loc_id, name, title, type_id, 2, dims, data);
+}
+
+int h5io_dset_write3(hid_t loc_id,
+ const char *name,
+ const char *title,
+ hid_t type_id,
+ void *data, int l, int m, int n)
+{
+ int dims[3] = {l,m,n};
+ return h5io_dset_write(loc_id, name, title, type_id, 3, dims, data);
+}
+
Added: cs/cigma/trunk/src/h5io/h5file.c
===================================================================
--- cs/cigma/trunk/src/h5io/h5file.c (rev 0)
+++ cs/cigma/trunk/src/h5io/h5file.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,157 @@
+#include <string.h>
+#include "hdf5.h"
+#include "h5io.h"
+
+
+hid_t h5io_file_create(const char *filename, const char *mode)
+{
+ hid_t file_id;
+ hid_t root;
+ herr_t status;
+
+ if (strcmp(mode, "w") == 0)
+ {
+ /* Create file by truncating (i.e. overwriting previous file) */
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ }
+ else if (strcmp(mode, "x") == 0)
+ {
+ /* Create file exclusively (i.e. fail if it already exists) */
+ file_id = H5Fcreate(filename, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
+ }
+ else
+ {
+ return -1;
+ }
+
+ if (file_id < 0)
+ {
+ return -2;
+ }
+
+ root = H5Gopen(file_id, "/");
+ status = h5io_attr_set_str(root, "TITLE", "Cigma file"); // TODO: add title to argument list
+ status = h5io_attr_set_str(root, "CLASS", "GROUP");
+ status = h5io_attr_set_str(root, "VERSION", "1.0");
+ status = h5io_attr_set_str(root, "PYTABLES_FORMAT_VERSION", "1.5");
+ status = H5Gclose(root);
+
+ return file_id;
+}
+
+
+hid_t h5io_file_open(const char *filename, const char *mode)
+{
+ /*
+ * Open file for reading. Fail if file doesn't exist.
+ */
+ if (strcmp(mode, "r") == 0)
+ {
+ hid_t file_id;
+
+ /* Open file in read-only mode */
+ file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
+
+ /* Check for failure */
+ if (file_id < 0)
+ {
+ return -1;
+ }
+
+ return file_id;
+ }
+
+ /*
+ * Open file for writing. If file exists, it is truncated.
+ */
+ if (strcmp(mode, "w") == 0)
+ {
+ hid_t file_id;
+
+ file_id = h5io_file_create(filename, "w");
+
+ if (file_id < 0)
+ {
+ return -2;
+ }
+
+ return file_id;
+ }
+
+ /*
+ * Open file for reading and writing. Fail if file doesn't exist.
+ */
+ if (strcmp(mode, "rw") == 0)
+ {
+ hid_t file_id;
+
+ /* Open file in read-write mode */
+ file_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
+
+ if (file_id < 0)
+ {
+ return -3;
+ }
+
+ return file_id;
+ }
+
+ /*
+ * Open file for reading and writing. Create the file if necessary.
+ */
+ if (strcmp(mode, "rw+") == 0)
+ {
+ hid_t file_id;
+
+ /* See http://hdf.ncsa.uiuc.edu/HDF5/doc/Errors.html */
+ herr_t (*old_func)(void *);
+ void *old_client_data;
+
+ /* Save old error handler */
+ H5Eget_auto(&old_func, &old_client_data);
+
+ /* Turn off error handling */
+ H5Eset_auto(NULL, NULL);
+
+ /* Open file in read-write mode -- errors supprssed */
+ file_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
+
+ /* Restore error handler */
+ H5Eset_auto(old_func, old_client_data);
+
+ /* If opening the file failed, try to create it */
+ if (file_id < 0)
+ {
+ file_id = h5io_file_create(filename, "w");
+ if (file_id < 0)
+ {
+ return -4;
+ }
+ }
+
+ return file_id;
+ }
+
+ /*
+ * Exclusively open file for writing. Fail if file already exists.
+ */
+ if (strcmp(mode, "x") == 0)
+ {
+ hid_t file_id;
+
+ file_id = h5io_file_create(filename, "x");
+
+ if (file_id < 0)
+ {
+ return -5;
+ }
+
+ return file_id;
+ }
+
+ /*
+ * Invalid mode was provided.
+ */
+ return -6;
+}
+
Added: cs/cigma/trunk/src/h5io/h5group.c
===================================================================
--- cs/cigma/trunk/src/h5io/h5group.c (rev 0)
+++ cs/cigma/trunk/src/h5io/h5group.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,113 @@
+#include "hdf5.h"
+#include "h5io.h"
+#include "split.h"
+#include <string.h>
+
+hid_t h5io_group_create(hid_t loc_id, const char *name)
+{
+ hid_t group_id;
+ herr_t status;
+
+ group_id = H5Gcreate(loc_id, name, 0);
+ if (group_id < 0)
+ {
+ return -1;
+ }
+
+ status = h5io_attr_set_str(group_id, "TITLE", "");
+ status = h5io_attr_set_str(group_id, "CLASS", "GROUP");
+ status = h5io_attr_set_str(group_id, "VERSION", "1.0");
+ status = h5io_attr_set_str(group_id, "PYTABLES_FORMAT_VERSION", "1.5");
+
+ return group_id;
+}
+
+
+hid_t h5io_group_open(hid_t loc_id, const char *name)
+{
+ return H5Gopen(loc_id, name);
+}
+
+
+hid_t h5io_group_touch(hid_t loc_id, const char *name)
+{
+ hid_t group_id;
+
+ group_id = H5Gopen(loc_id, name);
+
+ if (group_id < 0)
+ {
+ group_id = h5io_group_create(loc_id, name);
+ if (group_id < 0)
+ {
+ return -1;
+ }
+ }
+
+ return group_id;
+}
+
+
+hid_t h5io_group_touch_path(hid_t loc_id, const char *path)
+{
+ hid_t group_id;
+
+ /*
+ * Temporarily disabling error messages:
+ * see http://hdf.ncsa.uiuc.edu/HDF5/doc/Errors.html
+ */
+ herr_t (*old_func)(void *);
+ void *old_client_data;
+
+ /* Save old error handler */
+ H5Eget_auto(&old_func, &old_client_data);
+
+ /* Turn off error handling */
+ H5Eset_auto(NULL, NULL);
+
+ /* Attempt to open the group */
+ group_id = H5Gopen(loc_id, path);
+
+ if (group_id < 0)
+ {
+ herr_t status;
+ hid_t parent_id;
+ hid_t child_id;
+ char **names;
+ int i,n;
+
+ split(path, strlen(path), &names, &n, '/');
+
+ /* first parent */
+ parent_id = h5io_group_touch(loc_id, names[0]);
+ if (parent_id < 0)
+ {
+ H5Eset_auto(old_func, old_client_data);
+ split_free(names, n);
+ return -1;
+ }
+
+ for (i = 1; i < n; i++)
+ {
+ /* get child id */
+ child_id = h5io_group_touch(parent_id, names[i]);
+ if (child_id < 0)
+ {
+ H5Eset_auto(old_func, old_client_data);
+ split_free(names, n);
+ return -2;
+ }
+ /* move to next parent */
+ status = H5Gclose(parent_id);
+ parent_id = child_id;
+ }
+
+ /* return last group */
+ group_id = parent_id;
+ }
+
+ /* Restore previous error handler */
+ H5Eset_auto(old_func, old_client_data);
+
+ return group_id;
+}
Added: cs/cigma/trunk/src/h5io/h5io.h
===================================================================
--- cs/cigma/trunk/src/h5io/h5io.h (rev 0)
+++ cs/cigma/trunk/src/h5io/h5io.h 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,144 @@
+#ifndef __H5IO_H__
+#define __H5IO_H__
+
+#include "hdf5.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/****************************************************************************
+ * File and group interface *
+ ****************************************************************************/
+hid_t h5io_file_create(const char *filename, const char *mode);
+hid_t h5io_file_open(const char *filename, const char *mode);
+
+hid_t h5io_group_create(hid_t loc_id, const char *name);
+hid_t h5io_group_open(hid_t loc_id, const char *name);
+
+hid_t h5io_group_touch(hid_t loc_id, const char *name);
+hid_t h5io_group_touch_path(hid_t loc_id, const char *path);
+
+
+
+/****************************************************************************
+ * Attribute interface *
+ ****************************************************************************/
+
+herr_t h5io_attr_find(hid_t loc_id, const char *attr_name);
+herr_t h5io_attr_set(hid_t obj_id, const char *attr_name, hid_t type_id, const void *data);
+herr_t h5io_attr_get(hid_t obj_id, const char *attr_name, hid_t type_id, void *data);
+herr_t h5io_attr_get_dims(hid_t obj_id, const char *attr_name, int *rank, hsize_t *dims);
+
+herr_t h5io_attr_set_str(hid_t obj_id, const char *attr_name, const char *attr_data);
+herr_t h5io_attr_get_str(hid_t obj_id, const char *attr_name, char **data);
+
+herr_t h5io_attr_set_int(hid_t obj_id, const char *attr_name, int n);
+herr_t h5io_attr_set_long(hid_t obj_id, const char *attr_name, long n);
+herr_t h5io_attr_set_llong(hid_t obj_id, const char *attr_name, long long n);
+herr_t h5io_attr_set_float(hid_t obj_id, const char *attr_name, float x);
+herr_t h5io_attr_set_double(hid_t obj_id, const char *attr_name, double x);
+
+herr_t h5io_attr_set_array(hid_t obj_id, const char *attr_name,
+ size_t rank, hsize_t *dims, hid_t type_id, const void *data);
+
+herr_t h5io_attr_set_array1(hid_t obj_id, const char *attr_name,
+ hsize_t dim, hid_t type_id, const void *data);
+
+herr_t h5io_attr_set_array1_of_ints(hid_t obj_id, const char *attr_name,
+ hsize_t dim, const int *data);
+
+herr_t h5io_attr_set_array1_of_floats(hid_t obj_id, const char *attr_name,
+ hsize_t dim, const float *data);
+
+herr_t h5io_attr_set_array1_of_doubles(hid_t obj_id, const char *attr_name,
+ hsize_t dim, const double *data);
+
+/****************************************************************************
+ * Dataset interface *
+ ****************************************************************************/
+
+hid_t h5io_dset_create(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, int rank, int *shape);
+
+hid_t h5io_dset_open(hid_t loc_id, const char *name,
+ hid_t *type_id, int *rank, int *shape, int *npoints);
+
+
+int h5io_dset_read(hid_t loc_id, const char *name,
+ hid_t type_id, int rank, int *shape, void **data);
+
+int h5io_dset_read1(hid_t loc_id, const char *name,
+ hid_t type_id, void **data, int *n);
+
+int h5io_dset_read2(hid_t loc_id, const char *name,
+ hid_t type_id, void **data, int *m, int *n);
+
+int h5io_dset_read3(hid_t loc_id, const char *name,
+ hid_t type_id, void **data, int *l, int *m, int *n);
+
+
+int h5io_dset_write(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, int rank, int *shape, void *data);
+
+int h5io_dset_write1(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, void *data, int n);
+
+int h5io_dset_write2(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, void *data, int m, int n);
+
+int h5io_dset_write3(hid_t loc_id, const char *name, const char *title,
+ hid_t type_id, void *data, int l, int m, int n);
+
+
+int h5io_dset_slice_read3(hid_t loc_id,
+ const char *name,
+ hid_t type_id,
+ int rank, hsize_t *dims, void *data,
+ int start, int end);
+
+int h5io_dset_slice_write3(hid_t loc_id,
+ const char *name,
+ const char *title,
+ hid_t type_id,
+ int start, int end);
+
+/****************************************************************************
+ * Array interface *
+ ****************************************************************************/
+
+typedef struct {
+ int rank;
+ hsize_t *shape;
+ hid_t type_id;
+ void *data;
+} h5array_t;
+
+int h5io_array_init(h5array_t *array, hid_t type_id, int rank, int *shape, void *data);
+int h5io_array_free_dims(h5array_t *array);
+int h5io_array_free_data(h5array_t *array);
+int h5io_array_free(h5array_t *array);
+
+int h5io_array_npoints(h5array_t *array);
+int h5io_array_dim(h5array_t *array, int i);
+void h5io_array_dims(h5array_t *array, int *rank, int **shape);
+void h5io_array_dims1(h5array_t *array, int *n);
+void h5io_array_dims2(h5array_t *array, int *m, int *n);
+void h5io_array_dims3(h5array_t *array, int *l, int *m, int *n);
+
+hid_t h5io_array_open(h5array_t *array, hid_t loc_id, const char *name);
+hid_t h5io_array_create(h5array_t *array, hid_t loc_id, const char *name, const char *title);
+
+int h5io_array_read(h5array_t *array, hid_t loc_id, const char *name);
+int h5io_array_write(h5array_t *array, hid_t loc_id, const char *name);
+
+int h5io_array_slice_read(h5array_t *array, hid_t dataset_id, int start, int end);
+int h5io_array_slice_write(h5array_t *array, hid_t dataset_id, int start, int end);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __H5IO_H__ */
Added: cs/cigma/trunk/src/h5io/split.c
===================================================================
--- cs/cigma/trunk/src/h5io/split.c (rev 0)
+++ cs/cigma/trunk/src/h5io/split.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,184 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "split.h"
+
+/*
+ * Data structure for our basic string tokenizer. Basically, the strategy
+ * is to copy the desired string into our buffer, where we can zero out
+ * the separator characters in-place. Using a struct allows us to avoid
+ * defining global variables like in the version of split.c from the project
+ * http://www.nongnu.org/uri/ on which this code is inspired.
+ */
+
+typedef struct {
+ char separator; /* separator character */
+ char **tokens; /* tokens array */
+ int token_count; /* real size of tokens array */
+ int max_token_count; /* size of tokens array */
+ char *buffer; /* buffer string */
+ int buffer_length; /* length of buffer string */
+} strtok_t;
+
+
+
+/*
+ * In this section, we define the methods for our string tokenizer
+ * object. Namely, a constructor, a destructor, and then the actual
+ * routine to split the string.
+ */
+static void strtok_init(strtok_t *st, char sep)
+{
+ /* remember the separator character */
+ st->separator = sep;
+
+ /* starting up with 0 tokens */
+ st->token_count = 0;
+
+ /* setup the initial array sizes */
+ st->buffer_length = 512; /* 512 chars in buffer */
+ st->max_token_count = 16; /* 16 tokens in array */
+
+ /* allocate enough tokens and initialize buffer */
+ st->buffer = (char *)malloc(st->buffer_length * sizeof(char));
+ st->tokens = (char **)malloc(st->max_token_count * sizeof(char *));
+
+ return;
+}
+
+static void strtok_free(strtok_t *st)
+{
+ if (st != NULL)
+ {
+ free(st->buffer);
+ free(st->tokens);
+ }
+}
+
+static void strtok_split(strtok_t *st, const char *s, int len)
+{
+ /* Quick validation */
+ assert(st->separator != '\0');
+
+ /*
+ * First, check whether our buffer is large enough to manipulate
+ * the string s, and if not, reallocate enough memory.
+ */
+ if (st->buffer_length < len)
+ {
+ st->buffer_length = (len < 512) ? 512 : len+1;
+ st->buffer = (char *)realloc(st->buffer, st->buffer_length * sizeof(char));
+ }
+
+ /*
+ * Next, copy the string s into our buffer and tokenize it in-place.
+ * Essentially, zero out the locations where we find the separator
+ * character, while remembering the beginning of each string.
+ */
+ memcpy(st->buffer, s, len);
+ st->buffer[len] = '\0';
+ {
+ char *first, *p;
+ int index, last;
+
+ first = st->buffer;
+ last = st->buffer_length - 1;
+
+ /* remove trailing separators */
+ while (last >= 0 && st->buffer[last] == st->separator)
+ {
+ st->buffer[last] = '\0';
+ last--;
+ }
+
+ /* remove leading separators */
+ while(*first == st->separator)
+ {
+ first++;
+ }
+
+ /* store first token */
+ index = 0;
+ st->tokens[index++] = first;
+
+ /* keep tokenizing the buffer */
+ for (p = strchr(first, st->separator);
+ p != NULL;
+ p = strchr(p, st->separator))
+ {
+ /* separator found -- zero it out */
+ *p = '\0';
+
+ /* make p point to next char */
+ p++;
+
+ /* store the next token */
+ if ((*p != st->separator) && (*p != '\0'))
+ {
+ st->tokens[index++] = p;
+
+ /* check whether we need to expand our tokens array,
+ * to make room for the next batch of tokens */
+ if (index >= (st->max_token_count))
+ {
+ st->max_token_count += 16;
+ st->tokens = (char **)realloc(st->tokens,
+ st->max_token_count * sizeof(char *));
+ }
+ }
+ }
+
+ /* store the final count */
+ st->token_count = index;
+ }
+
+ return;
+}
+
+
+
+/*
+ * Finally, we provide a public interface to our string tokenizer.
+ * The caller subsumes the responsibility of freeing the newly allocated
+ * list, as well as each individual string in that list.
+ */
+void split(const char *str, int len,
+ char ***split_list, int *split_count, char sep)
+{
+ int i;
+ strtok_t tok;
+
+ /* guard against NULL separator */
+ if (sep == '\0')
+ {
+ *split_list = NULL;
+ *split_count = 0;
+ return;
+ }
+
+ strtok_init(&tok, sep);
+ strtok_split(&tok, str, len);
+
+ *split_list = (char **)malloc(tok.token_count * sizeof(char *));
+ *split_count = tok.token_count;
+
+ for (i = 0; i < tok.token_count; i++)
+ {
+ (*split_list)[i] = strdup(tok.tokens[i]);
+ }
+
+ strtok_free(&tok);
+}
+
+void split_free(char **split_list, int split_count)
+{
+ int i;
+ if (split_list != NULL)
+ {
+ for (i = 0; i < split_count; i++)
+ {
+ free(split_list[i]);
+ }
+ free(split_list);
+ }
+}
Added: cs/cigma/trunk/src/h5io/split.h
===================================================================
--- cs/cigma/trunk/src/h5io/split.h (rev 0)
+++ cs/cigma/trunk/src/h5io/split.h 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,15 @@
+#ifndef __SPLIT_H__
+#define __SPLIT_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void split(const char *str, int len,
+ char ***split_list, int *split_count, char sep);
+
+void split_free(char **split_list, int split_count);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SPLIT_H__ */
Added: cs/cigma/trunk/src/h5io/t/Makefile
===================================================================
--- cs/cigma/trunk/src/h5io/t/Makefile (rev 0)
+++ cs/cigma/trunk/src/h5io/t/Makefile 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,24 @@
+include ../../variables
+
+LFLAGS = -L../../lib
+LIBS = $(CIGMA_LIBS) -lh5io
+
+OPTIM += -fno-strict-aliasing
+
+CFLAGS = $(OPTIM) $(FLAGS) $(LFLAGS)
+
+TESTS = \
+ test_h5file \
+ test_h5group \
+ test_h5dset \
+
+tests: $(TESTS)
+
+test_%: test_%.c
+ $(CC) $(CFLAGS) $< -o $@ $(LIBS)
+
+clean:
+ rm -f test_io.h5
+ rm -f $(TESTS)
+
+.PHONY: clean
Added: cs/cigma/trunk/src/h5io/t/test_h5dset.c
===================================================================
--- cs/cigma/trunk/src/h5io/t/test_h5dset.c (rev 0)
+++ cs/cigma/trunk/src/h5io/t/test_h5dset.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "../h5io.h"
+
+int main(int argc, char *argv[])
+{
+ char *filename = "test_io.h5";
+
+ hid_t file_id;
+ herr_t status;
+ int ierr;
+
+ /* Open the file */
+ file_id = h5io_file_open(filename, "w");
+ if (file_id < 0)
+ {
+ fprintf(stderr, "Could not access '%s'\n", filename);
+ return -1;
+ }
+
+ /* Create a dataset */
+ {
+ int array[15] = { 1, 2, 3, 4, 5,
+ 6, 7, 8, 8, 10,
+ 11, 12, 13, 14, 15};
+
+ ierr = h5io_dset_write2(file_id, "/myarray", "My integer array",
+ H5T_NATIVE_INT, array, 3, 5);
+
+ if (ierr < 0)
+ {
+ fprintf(stderr, "Could not write /myarray\n");
+ return -2;
+ }
+ }
+
+ /* Open the file again and try to read the dataset we just wrote */
+ {
+ int m,n;
+ int *myarray;
+ hid_t file2;
+
+ file2 = h5io_file_open(filename, "rw");
+ if (file2 < 0)
+ {
+ fprintf(stderr, "Could not open '%s' for reading!\n", filename);
+ return -3;
+ }
+
+ ierr = h5io_dset_read2(file2, "/myarray", H5T_NATIVE_INT,
+ (void **)&myarray, &m, &n);
+ if (ierr < 0)
+ {
+ fprintf(stderr, "Could not read /myarray\n");
+ return -4;
+ }
+
+ {
+ int i,j;
+ for (i = 0; i < m; i++)
+ {
+ for (j = 0; j < n; j++)
+ {
+ printf("%2d\t", myarray[i*n + j]);
+ }
+ printf("\n");
+ }
+ }
+
+ free(myarray);
+ status = H5Fclose(file2);
+ }
+
+ /* Clean up */
+ status = H5Fclose(file_id);
+
+ return 0;
+}
Added: cs/cigma/trunk/src/h5io/t/test_h5file.c
===================================================================
--- cs/cigma/trunk/src/h5io/t/test_h5file.c (rev 0)
+++ cs/cigma/trunk/src/h5io/t/test_h5file.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "hdf5.h"
+#include "../h5io.h"
+
+int main(int argc, char *argv[])
+{
+ hid_t file_id;
+ herr_t status;
+
+ char *filename = "test_io.h5";
+
+ file_id = h5io_file_create(filename, "w");
+ if (file_id < 0)
+ {
+ fprintf(stderr, "Error: failed to create file '%s'\n", filename);
+ return EXIT_FAILURE;
+ }
+ printf("Created file '%s'\n", filename);
+
+ status = H5Fclose(file_id);
+
+ return EXIT_SUCCESS;
+}
Added: cs/cigma/trunk/src/h5io/t/test_h5group.c
===================================================================
--- cs/cigma/trunk/src/h5io/t/test_h5group.c (rev 0)
+++ cs/cigma/trunk/src/h5io/t/test_h5group.c 2008-09-10 19:50:40 UTC (rev 12839)
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "hdf5.h"
+#include "../h5io.h"
+
+int main(int argc, char *argv[])
+{
+ hid_t file_id;
+ char *filename = "test_io.h5";
+
+ /* groups */
+ hid_t model_id;
+ hid_t geometry_id;
+ hid_t topology_id;
+ hid_t solutions_id;
+
+ hid_t snapshot0;
+ hid_t snapshot1;
+ hid_t snapshot2;
+
+ hid_t foobarbaz0;
+ hid_t foobarbaz1;
+ hid_t foobarbaz2;
+
+
+ /* error handling */
+ herr_t status;
+
+ /* open test file, creating it if necessary */
+ file_id = h5io_file_open(filename, "rw+");
+ if (file_id < 0)
+ {
+ fprintf(stderr, "Error: failed to open file '%s'\n", filename);
+ return EXIT_FAILURE;
+ }
+
+ #define CHKERR(id) \
+ {\
+ fprintf(stderr, "Checking " #id "\n");\
+ if ((id) < 0)\
+ {\
+ fprintf(stderr, "Failed to create " #id " (%d)\n", (id));\
+ H5Fclose(file_id);\
+ return EXIT_FAILURE;\
+ }\
+ }
+
+ model_id = h5io_group_create(file_id, "/model"); CHKERR(model_id);
+ geometry_id = h5io_group_create(model_id, "geometry"); CHKERR(geometry_id);
+ topology_id = h5io_group_create(model_id, "topology"); CHKERR(topology_id);
+ solutions_id = h5io_group_create(file_id, "/model/solutions"); CHKERR(solutions_id);
+
+ snapshot0 = h5io_group_touch_path(solutions_id, "snapshot0"); CHKERR(snapshot0);
+ snapshot1 = h5io_group_touch_path(model_id, "solutions/snapshot1"); CHKERR(snapshot1);
+ snapshot2 = h5io_group_touch_path(file_id, "/model/solutions/snapshot2"); CHKERR(snapshot2);
+
+ foobarbaz0 = h5io_group_touch_path(file_id, "/foo/bar/baz"); CHKERR(foobarbaz0);
+ foobarbaz1 = h5io_group_touch_path(model_id, "foo/bar/baz"); CHKERR(foobarbaz1);
+ foobarbaz2 = h5io_group_touch_path(model_id, "/geometry/foo/bar/baz"); CHKERR(foobarbaz2);
+
+ /* touch an existing path */
+ H5Gclose(foobarbaz2);
+ foobarbaz2 = h5io_group_touch_path(model_id, "/geometry/foo/bar/baz"); CHKERR(foobarbaz2);
+
+ /* clean up */
+ H5Gclose(model_id);
+ H5Gclose(geometry_id);
+ H5Gclose(topology_id);
+ H5Gclose(solutions_id);
+
+ H5Gclose(snapshot0);
+ H5Gclose(snapshot1);
+ H5Gclose(snapshot2);
+
+ H5Gclose(foobarbaz0);
+ H5Gclose(foobarbaz1);
+ H5Gclose(foobarbaz2);
+
+ status = H5Fclose(file_id);
+
+ return EXIT_SUCCESS;
+}
More information about the cig-commits
mailing list