diff options
author | Bill Wendling <wendling@ncsa.uiuc.edu> | 2002-10-23 19:30:50 (GMT) |
---|---|---|
committer | Bill Wendling <wendling@ncsa.uiuc.edu> | 2002-10-23 19:30:50 (GMT) |
commit | 79f0efa9fd9c6f81be29a6401d337da817c2f54a (patch) | |
tree | 0fc5c584e5670cd372cfced79b3e969c0b5c9535 /src/H5Oplist.c | |
parent | b39dd538ec81df8f65304e40ee6587a54b586577 (diff) | |
download | hdf5-79f0efa9fd9c6f81be29a6401d337da817c2f54a.zip hdf5-79f0efa9fd9c6f81be29a6401d337da817c2f54a.tar.gz hdf5-79f0efa9fd9c6f81be29a6401d337da817c2f54a.tar.bz2 |
[svn-r6025] Purpose:
Feature Add
Description:
New files for the Flexible Parallel HDF5 stuff.
H5FP.c - Module housing the APIs to FPHDF5
H5FPclient.c - Module housing the internal client APIs
H5FPserver.c - Module housing the internal server APIs
H5FPpublic.h - Header for public APIs
H5FPprivate.h - Header for private APIs
H5Ofphdf5.c - Way of serializing FPHDF5 information to and from the
SAP
H5Oplist.c - Way of serializing a generic property list.
Solution:
[details about the changes, algorithm, etc...]
[Please as detail as you can since your own explanation is
better than others guessing it from the code.]
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}?
[If no, why not?]
Other platforms/configurations tested?
Misc. update:
Update MANIFEST if you add or remove any file.
Update release_docs/RELEASE for bug fixes, new features, etc.
Update applicable document files too.
Diffstat (limited to 'src/H5Oplist.c')
-rw-r--r-- | src/H5Oplist.c | 584 |
1 files changed, 584 insertions, 0 deletions
diff --git a/src/H5Oplist.c b/src/H5Oplist.c new file mode 100644 index 0000000..a326fba --- /dev/null +++ b/src/H5Oplist.c @@ -0,0 +1,584 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* $Id$ */ + +#define H5P_PACKAGE /* prevent warning from including H5Ppkg.h */ + +#include "H5private.h" /* Generic functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Ppkg.h" + +#if defined (WIN32) && !defined (__MWERKS__) +#include <sys/types.h> +#include <sys/timeb.h> +#endif + +#define PABLO_MASK H5O_plist_mask + +/* local prototypes */ +static void *H5O_plist_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh); +static herr_t H5O_plist_encode(H5F_t *f, uint8_t *p, const void *_mesg); +static size_t H5O_plist_size(H5F_t *f, const void *_mesg); +static herr_t H5O_plist_free(void *_mesg); +static herr_t H5O_plist_debug(H5F_t *f, const void *_mesg, + FILE *stream, int indent, int fwidth); + +/* This message derives from H5O */ +const H5O_class_t H5O_PLIST[1] = {{ + H5O_PLIST_ID, /* message id number */ + "plist", /* message name for debugging */ + sizeof(H5P_genplist_t), /* native message size */ + H5O_plist_decode, /* decode message */ + H5O_plist_encode, /* encode message */ + NULL, /* copy the native value */ + H5O_plist_size, /* size of symbol table entry */ + NULL, /* default reset method */ + H5O_plist_free, /* free method */ + NULL, /* get share method */ + NULL, /* set share method */ + H5O_plist_debug, /* debug the message */ +}}; + +#define H5O_PLIST_VERSION 1 + +/* Is the interface initialized? */ +static int interface_initialize_g = 0; + +#define INTERFACE_INIT NULL + +/* Declare external the free list for hsize_t arrays */ +H5FL_ARR_EXTERN(hsize_t); + +#define UINT_ENCODE(dst, src) \ + if (sizeof(src) == 2) { \ + UINT16ENCODE(dst, src); \ + } else if (sizeof(src) == 4) { \ + UINT32ENCODE(dst, src); \ + } else { \ + /* sizeof(src) == 8 */ \ + UINT64ENCODE(dst, src); \ + } + +#define UINT_DECODE(src, dst) \ + if (sizeof(dst) == 2) { \ + UINT16DECODE(src, dst); \ + } else if (sizeof(dst) == 4) { \ + UINT32DECODE(src, dst); \ + } else { \ + /* sizeof(dst) == 8 */ \ + UINT64DECODE(src, dst); \ + } + +#define INT_ENCODE(dst, src) \ + if (sizeof(src) == 2) { \ + INT16ENCODE(dst, src); \ + } else if (sizeof(src) == 4) { \ + INT32ENCODE(dst, src); \ + } else { \ + /* sizeof(src) == 8 */ \ + INT64ENCODE(dst, src); \ + } + +#define INT_DECODE(src, dst) \ + if (sizeof(dst) == 2) { \ + INT16DECODE(src, dst); \ + } else if (sizeof(dst) == 4) { \ + INT32DECODE(src, dst); \ + } else { \ + /* sizeof(dst) == 8 */ \ + INT64DECODE(src, dst); \ + } + +/* + * Function: H5O_plist_decode + * Purpose: Decode a property list and return a pointer to a memory + * struct with the decoded information. + * + * This function decodes the "raw" form of a serialized + * property list in memory native format. The struct is + * allocated within this function using malloc() and is + * returned to the caller. + * + * H5F_t *f IN: pointer to the HDF5 file struct + * uint8 *p OUT: the raw information buffer + * H5O_shared_t *sh IN: not used; must be NULL + * + * Return: Success: Pointer to the new message in native order + * Failure: NULL + * Programmer: Bill Wendling, 24, September 2002 + * Modifications: + */ +static void * +H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh) +{ + H5P_genplist_t *new_plist = NULL; + H5P_genclass_t *pclass; /* property list class to modify */ + hid_t new_plist_id; /* property list ID of new list created */ + int version; /* message version number */ + unsigned int i, nprops, hashsize; + void *ret_value; + + FUNC_ENTER_NOAPI(H5O_plist_decode, NULL); + + /* check args */ + assert(!f); + assert(p); + assert(!sh); + + /* Version number */ + version = *p++; + + if (version != H5O_PLIST_VERSION) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, + "bad version number for property list message"); + + /* Reserved (for what?) */ + ++p; + + /* + * Decode the sizes of the parts of the property list. The sizes + * stored in the file are exact but the parts are aligned on 8-byte + * boundaries. + */ + + /* + * Retrieve the name of the property class with its parent(s). It's a + * regular NULL terminated string. + */ + pclass = H5P_open_class_path(p); + p += HDstrlen(p) + 1; /* + 1 for the NULL */ + + UINT_DECODE(p, nprops); + UINT_DECODE(p, hashsize); + + /* Allocate new property list */ + if ((new_plist = H5MM_calloc(sizeof(H5P_genplist_t) + + ((hashsize - 1) * sizeof(H5P_genprop_t *)))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Initialize new property list */ + new_plist->pclass = pclass; + new_plist->nprops = 0; /* Initially the plist has the same + number of properties as the class */ + new_plist->class_init = 0; /* Initially, wait until the class + callback finishes to set */ + + /* Create new property list */ + for (i = 0; i < nprops; ++i) { + H5P_genprop_t *tprop; + unsigned str_len; + + /* + * Allocate and initialize the property structure which is going + * to hold the information we're reading in. + */ + if (NULL == (tprop = H5MM_malloc(sizeof(H5P_genprop_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + tprop->create = NULL; + tprop->def_value = NULL; + tprop->set = NULL; + tprop->get = NULL; + tprop->del = NULL; + tprop->copy = NULL; + tprop->close = NULL; + tprop->next = NULL; + + /* Grab the XORed value of the name and get the length of the name */ + UINT_DECODE(p, tprop->xor_val); + UINT_DECODE(p, str_len); + + if (str_len) { + /* If there is a name, allocate space for it and copy */ + if (NULL == (tprop->name = H5MM_malloc(str_len + 1))) { + H5MM_xfree(tprop); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + } + + HDmemcpy(tprop->name, p, str_len + 1); + p += str_len + 1; + } else { + tprop->name = NULL; + ++p; + } + + /* Grab the size of the "value" data */ + UINT_DECODE(p, tprop->size); + + /* Allocate and memcpy the value part of the property. */ + if ((tprop->value = H5MM_malloc(tprop->size)) == NULL) { + H5MM_xfree(tprop->name); + H5MM_xfree(tprop); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + } + + HDmemcpy(tprop->value, p, tprop->size); + p += tprop->size; + + /* Insert the initialized property into the property list */ + if (H5P_add_prop(new_plist->props, new_plist->pclass->hashsize, tprop) < 0) { + H5MM_xfree(tprop->value); + H5MM_xfree(tprop->name); + H5MM_xfree(tprop); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, NULL, "Can't insert property into list"); + } + + /* Increment the number of properties in list */ + ++new_plist->nprops; + } + + /* Increment the number of property lists derived from class */ + if (H5P_access_class(new_plist->pclass, H5P_MOD_INC_LST) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, "Can't increment class ref count"); + + /* Get an atom for the property list */ + if ((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "unable to atomize property list"); + + /* + * Save the property list ID in the property list struct, for use in + * the property class's 'close' callback + */ + new_plist->plist_id = new_plist_id; + + /* Set the class initialization flag */ + new_plist->class_init = 1; + + /* Set return value */ + ret_value = new_plist; /* success */ + +done: + FUNC_LEAVE(ret_value); +} + +/* + * Function: H5O_plist_encode + * Purpose: Encode a property list and return a pointer to a memory + * struct with the encoded information. + * + * This function encodes the "raw" form of a property list + * into a struct in memory native format. + * + * H5F_t *f IN: pointer to the HDF5 file struct + * uint8 *p OUT: the raw information buffer + * const void *mesg IN: pointer to the metadata to encode + * + * Return: Success: Non-negative + * Failure: Negative + * Programmer: Bill Wendling, 24, September 2002 + * Modifications: + */ +static herr_t +H5O_plist_encode(H5F_t UNUSED *f, uint8_t *p, const void *mesg) +{ + const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg; + herr_t ret_value = SUCCEED; + unsigned int i; + char *class_path; + uint8_t *old = p; + + FUNC_ENTER_NOAPI(H5O_plist_encode, FAIL); + + /* check args */ + assert(!f); + assert(p); + assert(plist); + + /* Version */ + *p++ = H5O_PLIST_VERSION; + + /* Reserved */ + *p++ = '\0'; + + /* + * Encode the sizes of the parts of the property list. The sizes + * stored in the file are exact but the parts are aligned on 8-byte + * boundaries. + */ + + /* + * The class name encoded will look like: + * + * BaseClass/ParentClass/.../DerivedClass + */ + class_path = H5P_get_class_path(plist->pclass); + + if (class_path) { + size_t s = HDstrlen(class_path) + 1; + + HDmemcpy(p, class_path, s); + p += s; + } else { + *p++ = '\0'; + } + + HDfree(class_path); + UINT_ENCODE(p, plist->nprops); + UINT_ENCODE(p, plist->pclass->hashsize); + + for (i = 0; i < plist->pclass->hashsize; ++i) { + H5P_genprop_t *tprop = plist->props[i]; + + /* Walk through the list of properties at each hash location */ + while (tprop) { + const char *n = tprop->name; + + /* + * Copy the meat of the generic property: + * + * 1. The XORed version of the name + * 2. The name of the property + * 3. The size of the property value + * 4. The property value + */ + UINT_ENCODE(p, tprop->xor_val); + + if (n && *n) { + size_t s = HDstrlen(n); + + UINT_ENCODE(p, s); + HDmemcpy(p, n, s + 1); + p += s + 1; + } else { + /* if there isn't a name, put a NULL there */ + UINT_ENCODE(p, 0u); + *p++ = '\0'; + } + + UINT_ENCODE(p, tprop->size); + HDmemcpy(p, tprop->value, tprop->size); + p += tprop->size; + + /* Go to next registered property in class */ + tprop = tprop->next; + } + } + + fprintf(stderr, "number of bytes == %d\n", p - old); + +done: + FUNC_LEAVE(ret_value); +} + +/* + * Function: H5O_plist_size + * Purpose: Return the raw message size in bytes. + * + * This function returns the size of the raw elements on + * success. (Not counting the message type or size fields, + * only the data portion of the message). It doesn't take + * into account alignment. + * + * H5F_t *f IN: pointer to the HDF5 file struct + * const void *mesg IN: pointer to the metadata structure + * + * Return: Success: Size of message + * Failure: 0 + * Programmer: Bill Wendling, 24, September 2002 + * Modifications: + */ +static size_t +H5O_plist_size(H5F_t UNUSED *f, const void *mesg) +{ + const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg; + const H5P_genclass_t *pclass; + size_t ret_value; + char *class_path = NULL; + unsigned i; + + FUNC_ENTER_NOAPI(H5O_plist_size, 0); + + /* check args */ + assert(plist); + + ret_value = 2 + /*version info */ + 1; /*reserved */ + + /* + * Loop through the class and its parent(s) to gather the complete + * length of the name. The class name encoded will look like: + * + * DerivedClass/ParentClass/.../BaseClass + */ + pclass = plist->pclass; + + while (pclass) { + if (pclass->name) + ret_value += HDstrlen(pclass->name);/*length of class name */ + + if ((pclass = pclass->parent) != NULL) + ++ret_value; /*separating "/" */ + } + + ++ret_value; /*terminating NULL */ + + class_path = H5P_get_class_path(plist->pclass); + + if (class_path) + ret_value += HDstrlen(class_path) + 1; /*class path */ + else + ++ret_value; + + HDfree(class_path); + ret_value += sizeof(plist->nprops) + /*num properties */ + sizeof(plist->pclass->hashsize); /*hash size */ + + for (i = 0; i < plist->pclass->hashsize; ++i) { + H5P_genprop_t *tprop = plist->props[i]; + + /* Walk through the list of properties at each hash location */ + while (tprop) { + const char *n = tprop->name; + + ret_value += sizeof(tprop->xor_val) + /*xored value */ + sizeof(size_t); /*length of the name */ + + if (n && *n) + ret_value += HDstrlen(n) + 1; /*the name */ + else + ++ret_value; /*the name: NULL */ + + ret_value += sizeof(tprop->size) + /*size of data size */ + tprop->size; /*the data */ + + /* Go to next registered property in class */ + tprop = tprop->next; + } + } + +done: + FUNC_LEAVE(ret_value); +} + +/* + * Function: H5O_plist_free + * Purpose: Free's the property list. + * + * const void *mesg IN: pointer to the property list to free + * + * Return: Success: Non-negative + * Failure: Negative + * Programmer: Bill Wendling, 24, September 2002 + * Modifications: + */ +static herr_t +H5O_plist_free(void *mesg) +{ + H5P_genplist_t *plist = mesg; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5O_plist_free, FAIL); + assert(mesg); + + ret_value = H5P_close(plist); + +done: + FUNC_LEAVE(ret_value); +} + +/* + * Function: H5O_plist_debug + * Purpose: Prints debugging information for the property list message. + * + * H5F_t *f IN: pointer to the HDF5 file struct + * const void *mesg IN: Pointer to the source property list struct + * FILE *stream IN: Pointer to the stream for output data + * int indent IN: Amount to indent information by + * int fwidth IN: Field width (?) + * + * Return: Success: Non-negative + * Failure: Negative + * Programmer: Bill Wendling, 24, September 2002 + * Modifications: + */ +static herr_t +H5O_plist_debug(H5F_t UNUSED *f, const void *mesg, FILE *stream, + int indent, int fwidth) +{ + const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg; + herr_t ret_value = SUCCEED; + unsigned int i; + + FUNC_ENTER_NOAPI(H5O_plist_debug, FAIL); + + /* check args */ + assert(!f); + assert(plist); + assert(stream); + assert(indent >= 0); + assert(fwidth >= 0); + + HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Property List:"); + indent += 2; + HDfprintf(stream, "%*sNumber of properties: %d\n", indent, "", plist->nprops); + HDfprintf(stream, "%*sProperties {\n", indent, ""); + indent += 2; + + for (i = 0; i < plist->pclass->hashsize; ++i) { + H5P_genprop_t *tprop = plist->props[i]; + + HDfprintf(stream, "%*sProperty {\n", indent, ""); + indent += 2; + + /* Walk through the list of properties at each hash location */ + while (tprop) { + register unsigned int j; + + /* + * Copy the meat of the generic property: + * + * 1. The name of the property + * 2. The XORed version of the name + * 3. The size of the property value + * 4. The property value + */ + HDfprintf(stream, "%*sName: ", indent, ""); + + if (tprop->name) + HDfprintf(stream, "%s\n", tprop->name); + else + HDfprintf(stream, "(null)\n"); + + HDfprintf(stream, "%*sXOR Value: %d\n", indent, "", tprop->xor_val); + HDfprintf(stream, "%*sValue Size: %d\n", indent, "", tprop->size); + HDfprintf(stream, "%*sValue: ", indent, ""); + + for (j = 0; j < tprop->size; ++j) + HDfprintf(stream, "%02x ", ((char *)tprop->value)[j]); + + HDfprintf(stream, "\n"); + + /* Go to next registered property in class */ + tprop = tprop->next; + } + + indent -= 2; + HDfprintf(stream, "%*s}\n", indent, ""); + } + + indent -= 2; + HDfprintf(stream, "%*s}\n", indent, ""); + + indent -= 2; + HDfprintf(stream, "%*s}\n", indent, ""); + +done: + FUNC_LEAVE(ret_value); +} |