diff options
-rw-r--r-- | src/H5Pdxpl.c | 53 | ||||
-rw-r--r-- | src/H5Ppublic.h | 1 | ||||
-rw-r--r-- | src/H5Zprivate.h | 3 | ||||
-rw-r--r-- | src/H5Ztrans.c | 415 |
4 files changed, 361 insertions, 111 deletions
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 3994d98..67dba0b 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -80,6 +80,59 @@ done: FUNC_LEAVE_API(ret_value); } +/*------------------------------------------------------------------------- + * Function: H5Pget_data_transform + * + * Purpose: + * Gets data transform expression. + * + * + * Return: Returns a non-negative value if successful; otherwise returns a negative value. + * + * + * Programmer: Leon Arber + * August 27, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5Pget_data_transform(hid_t plist_id, char** expression) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5Z_data_xform_t *data_xform_prop=NULL; /* New data xform property */ + herr_t ret_value=SUCCEED; /* return value */ + + + FUNC_ENTER_API(H5Pget_data_transform, FAIL); + + /* Check arguments */ + if (expression == NULL) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "expression cannot be NULL"); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + if(H5P_get(plist, H5D_XFER_XFORM_NAME, &data_xform_prop)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTSET, FAIL, "Error setting data transform expression"); + + /* Get the data transform string */ + *expression = H5Z_xform_extract_xform_str(data_xform_prop); + +done: + if(ret_value<0) { + if(data_xform_prop) + if(H5Z_xform_destroy(data_xform_prop)<0) + HDONE_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "unable to release data transform expression") + } /* end if */ + + FUNC_LEAVE_API(ret_value); +} + + + + /*------------------------------------------------------------------------- * Function: H5Pset_buffer diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 89d3f6c..bd9518e 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -198,6 +198,7 @@ H5_DLL H5D_layout_t H5Pget_layout(hid_t plist_id); H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[]); H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/); H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char* expression); +H5_DLL herr_t H5Pget_data_transform(hid_t plist_id, char** expression); H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size); H5_DLL int H5Pget_external_count(hid_t plist_id); diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h index 4e26f31..2c1072d 100644 --- a/src/H5Zprivate.h +++ b/src/H5Zprivate.h @@ -70,7 +70,8 @@ typedef struct H5Z_data_xform_t H5Z_data_xform_t; /* Defined in H5Ztrans.c */ H5_DLL H5Z_data_xform_t *H5Z_xform_create(const char *expr); H5_DLL herr_t H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop); H5_DLL herr_t H5Z_xform_destroy(H5Z_data_xform_t *data_xform_prop); -H5_DLL herr_t H5Z_xform_eval(const H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type); +H5_DLL herr_t H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type); H5_DLL hbool_t H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop); +H5_DLL char* H5Z_xform_extract_xform_str(const H5Z_data_xform_t *data_xform_prop); #endif diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index c53a758..38e966f 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -39,8 +39,19 @@ typedef enum { H5Z_XFORM_END } H5Z_token_type; + + +/*Temporary hack for multiple array storage: */ +typedef struct { + int num_ptrs; + void** ptr_dat_val; +} H5Z_datval_ptrs; +/* end of temp. hack */ + + +/* Used to represent values in transform expression */ typedef union { - char *sym_val; + void *dat_val; long int_val; double float_val; } H5Z_num_val; @@ -55,12 +66,12 @@ typedef struct H5Z_node { struct H5Z_data_xform_t { char* xform_exp; struct H5Z_node* parse_root; + H5Z_datval_ptrs* dat_val_pointers; }; typedef struct result { H5Z_token_type type; H5Z_num_val value; - H5T_class_t ar_type; } H5Z_result; @@ -81,16 +92,16 @@ typedef struct { /* Local function prototypes */ static H5Z_token *H5Z_get_token(H5Z_token *current); -static H5Z_node *H5Z_parse_expression(H5Z_token *current); -static H5Z_node *H5Z_parse_term(H5Z_token *current); -static H5Z_node *H5Z_parse_factor(H5Z_token *current); +static H5Z_node *H5Z_parse_expression(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers); +static H5Z_node *H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers); +static H5Z_node *H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers); static H5Z_node *H5Z_new_node(H5Z_token_type type); static void H5Z_do_op(H5Z_node* tree); static hid_t H5Z_xform_find_type(const H5T_t* type); -static H5Z_result H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type); +static H5Z_result H5Z_eval_full(H5Z_node *tree, size_t array_size, hid_t array_type); static void H5Z_xform_destroy_parse_tree(H5Z_node *tree); -static void* H5Z_xform_parse(const char *expression); -static void* H5Z_xform_copy_tree(H5Z_node* tree); +static void* H5Z_xform_parse(const char *expression, H5Z_datval_ptrs* dat_val_pointers); +static void* H5Z_xform_copy_tree(H5Z_node* tree, H5Z_datval_ptrs* dat_val_pointers, H5Z_datval_ptrs* new_dat_val_pointers); static void H5Z_xform_reduce_tree(H5Z_node* tree); #ifdef H5Z_XFORM_DEBUG static void H5Z_XFORM_DEBUG(H5Z_node *tree); @@ -160,7 +171,7 @@ H5Z_unget_token(H5Z_token *current) * unget_H5Z_token function. * Return: Succeess: The passed in H5Z_token with a valid tok_type * field. - * NULLure: The passed in H5Z_token but with the tok_type + * Failure: The passed in H5Z_token but with the tok_type * field set to ERROR. * Programmer: Bill Wendling * 26. August 2003 @@ -306,16 +317,13 @@ H5Z_xform_destroy_parse_tree(H5Z_node *tree) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5Z_xform_destroy_parse_tree) - if (!tree) - return; - - if (tree->type == H5Z_XFORM_SYMBOL) - H5MM_xfree(tree->value.sym_val); - - H5Z_xform_destroy_parse_tree(tree->lchild); - H5Z_xform_destroy_parse_tree(tree->rchild); - H5MM_xfree(tree); - tree = NULL; + if (tree) + { + H5Z_xform_destroy_parse_tree(tree->lchild); + H5Z_xform_destroy_parse_tree(tree->rchild); + H5MM_xfree(tree); + tree = NULL; + } FUNC_LEAVE_NOAPI_VOID } @@ -335,7 +343,7 @@ H5Z_xform_destroy_parse_tree(H5Z_node *tree) *------------------------------------------------------------------------- */ void * -H5Z_xform_parse(const char *expression) +H5Z_xform_parse(const char *expression, H5Z_datval_ptrs* dat_val_pointers) { H5Z_token tok; void* ret_value; @@ -344,11 +352,12 @@ H5Z_xform_parse(const char *expression) if (!expression) HGOTO_DONE(NULL) - + + /* Set up the initial H5Z_token for parsing */ tok.tok_expr = tok.tok_begin = tok.tok_end = expression; - ret_value = (void*)H5Z_parse_expression(&tok); + ret_value = (void*)H5Z_parse_expression(&tok, dat_val_pointers); H5Z_xform_reduce_tree((H5Z_node*)ret_value); @@ -374,14 +383,14 @@ done: *------------------------------------------------------------------------- */ static H5Z_node * -H5Z_parse_expression(H5Z_token *current) +H5Z_parse_expression(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers) { H5Z_node *expr; void* ret_value=NULL; FUNC_ENTER_NOAPI_NOINIT(H5Z_parse_expression) - expr = H5Z_parse_term(current); + expr = H5Z_parse_term(current, dat_val_pointers); for (;;) { H5Z_node *new_node; @@ -400,7 +409,7 @@ H5Z_parse_expression(H5Z_token *current) } new_node->lchild = expr; - new_node->rchild = H5Z_parse_term(current); + new_node->rchild = H5Z_parse_term(current, dat_val_pointers); if (!new_node->rchild) { H5Z_xform_destroy_parse_tree(new_node); @@ -420,7 +429,7 @@ H5Z_parse_expression(H5Z_token *current) } new_node->lchild = expr; - new_node->rchild = H5Z_parse_term(current); + new_node->rchild = H5Z_parse_term(current, dat_val_pointers); if (!new_node->rchild) { H5Z_xform_destroy_parse_tree(new_node); @@ -463,13 +472,13 @@ done: *------------------------------------------------------------------------- */ static H5Z_node * -H5Z_parse_term(H5Z_token *current) +H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers) { H5Z_node *term = NULL; void* ret_value=NULL; FUNC_ENTER_NOAPI(H5Z_parse_term, NULL); - term = H5Z_parse_factor(current); + term = H5Z_parse_factor(current, dat_val_pointers); for (;;) { H5Z_node *new_node; @@ -488,7 +497,7 @@ H5Z_parse_term(H5Z_token *current) } new_node->lchild = term; - new_node->rchild = H5Z_parse_factor(current); + new_node->rchild = H5Z_parse_factor(current, dat_val_pointers); if (!new_node->rchild) { H5Z_xform_destroy_parse_tree(term); @@ -508,7 +517,7 @@ H5Z_parse_term(H5Z_token *current) } new_node->lchild = term; - new_node->rchild = H5Z_parse_factor(current); + new_node->rchild = H5Z_parse_factor(current, dat_val_pointers); term = new_node; if (!new_node->rchild) { @@ -555,7 +564,7 @@ done: *------------------------------------------------------------------------- */ static H5Z_node * -H5Z_parse_factor(H5Z_token *current) +H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers) { H5Z_node *factor=NULL; H5Z_node *new_node=NULL; @@ -587,13 +596,13 @@ H5Z_parse_factor(H5Z_token *current) if (!factor) HGOTO_DONE(factor) - - factor->value.sym_val = H5MM_calloc((size_t)(current->tok_end - current->tok_begin) + 1); - HDstrncpy(factor->value.sym_val, current->tok_begin, - (size_t)(current->tok_end - current->tok_begin)); + + factor->value.dat_val = &(dat_val_pointers->ptr_dat_val[dat_val_pointers->num_ptrs]); + dat_val_pointers->num_ptrs++; + break; case H5Z_XFORM_LPAREN: - factor = H5Z_parse_expression(current); + factor = H5Z_parse_expression(current, dat_val_pointers); if (!factor) HGOTO_DONE(factor) @@ -614,7 +623,7 @@ H5Z_parse_factor(H5Z_token *current) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "Syntax error: unexpected ')' ") case H5Z_XFORM_PLUS: /* unary + */ - new_node = H5Z_parse_factor(current); + new_node = H5Z_parse_factor(current, dat_val_pointers); if (new_node) { if (new_node->type != H5Z_XFORM_INTEGER && new_node->type != H5Z_XFORM_FLOAT && @@ -645,7 +654,7 @@ H5Z_parse_factor(H5Z_token *current) break; case H5Z_XFORM_MINUS: /* unary - */ - new_node = H5Z_parse_factor(current); + new_node = H5Z_parse_factor(current, dat_val_pointers); if (new_node) { if (new_node->type != H5Z_XFORM_INTEGER && new_node->type != H5Z_XFORM_FLOAT && @@ -725,7 +734,7 @@ H5Z_new_node(H5Z_token_type type) */ herr_t -H5Z_xform_eval(const H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type) +H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type) { H5Z_node *tree; hid_t array_type; @@ -788,13 +797,50 @@ H5Z_xform_eval(const H5Z_data_xform_t *data_xform_prop, void* array, size_t arra /* Otherwise, do the full data transform */ else { - res = H5Z_eval_full(tree, array, array_size, array_type); + /* Traverse parse tree, and copy over array into dat_val tree pointers */ + /*No longer pass array to H5Z_eval_full, but still need size and type, as these won't change */ + + /* Optimization for linear transform: */ + if(data_xform_prop->dat_val_pointers->num_ptrs == 1) + data_xform_prop->dat_val_pointers->ptr_dat_val[0] = array; + /* If it's a quadratic transform, we have no choice but to store multiple copies of the data */ + else + { + for(n=0; n<data_xform_prop->dat_val_pointers->num_ptrs; n++) + { + if( (data_xform_prop->dat_val_pointers->ptr_dat_val[n] = (void*)HDmalloc(array_size*H5Tget_size(array_type))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "Ran out of memory trying to allocate space for data in data transform") + + HDmemcpy(data_xform_prop->dat_val_pointers->ptr_dat_val[n], array, array_size*H5Tget_size(array_type)); + } + } + res = H5Z_eval_full(tree, array_size, array_type); if(res.type == H5Z_XFORM_ERROR) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") + else + { + HDmemcpy(array, res.value.dat_val, array_size*H5Tget_size(array_type)); + + /* Free the temporary arrays we used */ + + if(data_xform_prop->dat_val_pointers->num_ptrs > 1) + { + for(n=0; n<data_xform_prop->dat_val_pointers->num_ptrs; n++) + HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[n]); + } + } } done: + if(ret_value < 0) + { + /* If we ran out of memory above copying the array for temp storage (which we easily can for + * polynomial transforms of high order) we free those arrays which we already allocated */ + for(n=0; n<data_xform_prop->dat_val_pointers->num_ptrs; n++) + if(data_xform_prop->dat_val_pointers->ptr_dat_val[n] != NULL) + HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[n]); + } FUNC_LEAVE_NOAPI(ret_value); } @@ -810,10 +856,14 @@ done: * 5/1/04 * Modifications: * + * + * Notes: In the case of a polynomial data transform (ie, the left and right subtree + * are both of type H5Z_XFORM_SYMBOL), the convention is that the left hand side + * will accumulate changes and, at the end, the new data will be copied from the lhs. *------------------------------------------------------------------------- */ static H5Z_result -H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) +H5Z_eval_full(H5Z_node *tree, size_t array_size, hid_t array_type) { H5Z_result res, resl, resr, ret_value, error; @@ -839,13 +889,16 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) else if (tree->type == H5Z_XFORM_SYMBOL) { res.type = H5Z_XFORM_SYMBOL; - res.value.sym_val = tree->value.sym_val; - res.ar_type = array_type; + + /*since dat_val stores the address of the array which is really stored in the dat_val_pointers, + * here we make dat_val store a pointer to the array itself instead of the address of it so that the + * rest of the code below works normally. */ + res.value.dat_val = *((void**)(tree->value.dat_val)); } else { - resl = H5Z_eval_full(tree->lchild, array, array_size, array_type); - resr = H5Z_eval_full(tree->rchild, array, array_size, array_type); + resl = H5Z_eval_full(tree->lchild, array_size, array_type); + resr = H5Z_eval_full(tree->rchild, array_size, array_type); res.type = H5Z_XFORM_SYMBOL; /* Check for un-handled datatype */ @@ -859,12 +912,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) += resr.value.int_val; + *((int*)resl.value.dat_val + i) += resr.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) += resr.value.int_val; + *((float*)resl.value.dat_val + i) += resr.value.int_val; } } else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_FLOAT)) @@ -872,12 +925,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) += resr.value.float_val; + *((int*)resl.value.dat_val + i) += resr.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) += (float)resr.value.float_val; + *((float*)resl.value.dat_val + i) += (float)resr.value.float_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_INTEGER)) @@ -885,12 +938,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) += resl.value.int_val; + *((int*)resr.value.dat_val + i) += resl.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) += resl.value.int_val ; + *((float*)resr.value.dat_val + i) += resl.value.int_val ; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_FLOAT)) @@ -898,15 +951,28 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) += resl.value.float_val; + *((int*)resr.value.dat_val + i) += resl.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) += (float)resl.value.float_val ; + *((float*)resr.value.dat_val + i) += (float)resl.value.float_val ; } } - else + else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_SYMBOL)) + { + if(array_type == H5T_NATIVE_INT) + { + for(i=0; i<array_size; i++) + *((int*)resl.value.dat_val + i) += *((int*)resr.value.dat_val + i); + } + else + { + for(i=0; i<array_size; i++) + *((float*)resl.value.dat_val + i) += *((float*)resr.value.dat_val + i); + } + } + else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Unexpected type conversion operation") break; @@ -916,12 +982,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) -= resr.value.int_val; + *((int*)resl.value.dat_val + i) -= resr.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) -= resr.value.int_val; + *((float*)resl.value.dat_val + i) -= resr.value.int_val; } } else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_FLOAT)) /*we can't upgrade an array w/o allocating more memory, so we downgrade the float_val to an int.*/ @@ -929,12 +995,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) -= resr.value.float_val; + *((int*)resl.value.dat_val + i) -= resr.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) -= (float)resr.value.float_val; + *((float*)resl.value.dat_val + i) -= (float)resr.value.float_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_INTEGER)) @@ -942,12 +1008,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) = resl.value.int_val - *((int*)array + i); + *((int*)resr.value.dat_val + i) -= resl.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) = resl.value.int_val - *((float*)array + i); + *((float*)resr.value.dat_val + i) -= resl.value.int_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_FLOAT)) @@ -955,15 +1021,28 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) = resl.value.float_val - *((int*)array + i); + *((int*)resr.value.dat_val + i) -= resl.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) = (float)resl.value.float_val - *((float*)array + i); + *((float*)resr.value.dat_val + i) -= (float)resl.value.float_val; } } - else + else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_SYMBOL)) + { + if(array_type == H5T_NATIVE_INT) + { + for(i=0; i<array_size; i++) + *((int*)resl.value.dat_val + i) -= *((int*)resr.value.dat_val + i); + } + else + { + for(i=0; i<array_size; i++) + *((float*)resl.value.dat_val + i) -= *((float*)resr.value.dat_val + i); + } + } + else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Unexpected type conversion operation") break; @@ -975,12 +1054,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) *= resr.value.int_val; + *((int*)resl.value.dat_val + i) *= resr.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) *= resr.value.int_val; + *((float*)resl.value.dat_val + i) *= resr.value.int_val; } } else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_FLOAT)) @@ -988,12 +1067,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) *= resr.value.float_val; + *((int*)resl.value.dat_val + i) *= resr.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) *= (float)resr.value.float_val; + *((float*)resl.value.dat_val + i) *= (float)resr.value.float_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_INTEGER)) @@ -1001,12 +1080,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) *= resl.value.int_val; + *((int*)resr.value.dat_val + i) *= resl.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) *= resl.value.int_val; + *((float*)resr.value.dat_val + i) *= resl.value.int_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_FLOAT)) @@ -1014,15 +1093,28 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) *= resl.value.float_val; + *((int*)resr.value.dat_val + i) *= resl.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) *= (float)resl.value.float_val; + *((float*)resr.value.dat_val + i) *= (float)resl.value.float_val; } } - else + else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_SYMBOL)) + { + if(array_type == H5T_NATIVE_INT) + { + for(i=0; i<array_size; i++) + *((int*)resl.value.dat_val + i) *= *((int*)resr.value.dat_val + i); + } + else + { + for(i=0; i<array_size; i++) + *((float*)resl.value.dat_val + i) *= *((float*)resr.value.dat_val + i); + } + } + else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Unexpected type operation") break; @@ -1032,12 +1124,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) /= resr.value.int_val; + *((int*)resl.value.dat_val + i) /= resr.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) /= resr.value.int_val; + *((float*)resl.value.dat_val + i) /= resr.value.int_val; } } else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_FLOAT)) @@ -1045,12 +1137,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) /= resr.value.float_val; + *((int*)resl.value.dat_val + i) /= resr.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) /= (float)resr.value.float_val; + *((float*)resl.value.dat_val + i) /= (float)resr.value.float_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_INTEGER)) @@ -1058,12 +1150,12 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) = resl.value.int_val / *((int*)array + i); + *((int*)resr.value.dat_val + i) /= resl.value.int_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) = resl.value.int_val / *((float*)array + i); + *((float*)resr.value.dat_val + i) /= resl.value.int_val; } } else if( (resr.type == H5Z_XFORM_SYMBOL) && (resl.type==H5Z_XFORM_FLOAT)) @@ -1071,23 +1163,47 @@ H5Z_eval_full(H5Z_node *tree, void* array, size_t array_size, hid_t array_type) if(array_type == H5T_NATIVE_INT) { for(i=0; i<array_size; i++) - *((int*)array + i) = resl.value.float_val / *((int*)array + i); + *((int*)resr.value.dat_val + i) /= resl.value.float_val; } else { for(i=0; i<array_size; i++) - *((float*)array + i) = (float)resl.value.float_val / *((float*)array + i); + *((float*)resr.value.dat_val + i) /= (float)resl.value.float_val; } } - else + else if( (resl.type == H5Z_XFORM_SYMBOL) && (resr.type==H5Z_XFORM_SYMBOL)) + { + if(array_type == H5T_NATIVE_INT) + { + for(i=0; i<array_size; i++) + *((int*)resl.value.dat_val + i) /= *((int*)resr.value.dat_val + i); + } + else + { + for(i=0; i<array_size; i++) + *((float*)resl.value.dat_val + i) /= *((float*)resr.value.dat_val + i); + } + } + else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Unexpected type operation") break; default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Invalid expression tree") } - } + /* The result stores a pointer to the new data */ + /* So, if the left hand side got its data modified, the result stores a pointers + * to the left hand side's data, ditto for rhs */ + if(resl.type == H5Z_XFORM_SYMBOL) + res.value.dat_val = resl.value.dat_val; + else if(resr.type == H5Z_XFORM_SYMBOL) + res.value.dat_val = resr.value.dat_val; + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, error, "Invalid expression tree 2") + + } + ret_value=res; done: @@ -1182,7 +1298,7 @@ done: * *------------------------------------------------------------------------- */ -void* H5Z_xform_copy_tree(H5Z_node* tree) +void* H5Z_xform_copy_tree(H5Z_node* tree, H5Z_datval_ptrs* dat_val_pointers, H5Z_datval_ptrs* new_dat_val_pointers) { H5Z_node* ret_value=NULL; @@ -1196,32 +1312,37 @@ void* H5Z_xform_copy_tree(H5Z_node* tree) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Ran out of memory trying to copy parse tree") else { - ret_value -> type = H5Z_XFORM_INTEGER; - ret_value ->value.int_val = tree->value.int_val; - } + ret_value -> type = H5Z_XFORM_INTEGER; + ret_value ->value.int_val = tree->value.int_val; + ret_value -> lchild = NULL; + ret_value -> rchild = NULL; + } } else if (tree->type == H5Z_XFORM_FLOAT) { if ((ret_value = (H5Z_node*) H5MM_malloc(sizeof(H5Z_node))) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Ran out of memory trying to copy parse tree") else - { - ret_value -> type = H5Z_XFORM_FLOAT; - ret_value ->value.float_val = tree->value.float_val; - } + { + ret_value -> type = H5Z_XFORM_FLOAT; + ret_value ->value.float_val = tree->value.float_val; + ret_value -> lchild = NULL; + ret_value -> rchild = NULL; + } } else if(tree->type == H5Z_XFORM_SYMBOL) { if ((ret_value = (H5Z_node*) H5MM_malloc(sizeof(H5Z_node))) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Ran out of memory trying to copy parse tree") - else - { - ret_value -> type = H5Z_XFORM_SYMBOL; - if ((ret_value->value.sym_val = (char*) H5MM_malloc(strlen(tree->value.sym_val)+1)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Ran out of memory trying to copy parse tree") - else - strcpy(ret_value ->value.sym_val, tree->value.sym_val); - } + else + { + ret_value -> type = H5Z_XFORM_SYMBOL; + + ret_value -> value.dat_val = &(new_dat_val_pointers->ptr_dat_val[new_dat_val_pointers->num_ptrs]); + new_dat_val_pointers->num_ptrs++; + ret_value -> lchild = NULL; + ret_value -> rchild = NULL; + } } else if(tree->type == H5Z_XFORM_MULT) { @@ -1230,8 +1351,8 @@ void* H5Z_xform_copy_tree(H5Z_node* tree) else { ret_value->type = H5Z_XFORM_MULT; - ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild); - ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild); + ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild, dat_val_pointers, new_dat_val_pointers); + ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild, dat_val_pointers, new_dat_val_pointers); } } else if(tree->type == H5Z_XFORM_PLUS) @@ -1241,8 +1362,8 @@ void* H5Z_xform_copy_tree(H5Z_node* tree) else { ret_value->type = H5Z_XFORM_PLUS; - ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild); - ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild); + ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild, dat_val_pointers, new_dat_val_pointers); + ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild, dat_val_pointers, new_dat_val_pointers); } } else if(tree->type == H5Z_XFORM_MINUS) @@ -1252,8 +1373,8 @@ void* H5Z_xform_copy_tree(H5Z_node* tree) else { ret_value->type = H5Z_XFORM_MINUS; - ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild); - ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild); + ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild, dat_val_pointers, new_dat_val_pointers); + ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild, dat_val_pointers, new_dat_val_pointers); } } else if(tree->type == H5Z_XFORM_DIVIDE) @@ -1263,8 +1384,8 @@ void* H5Z_xform_copy_tree(H5Z_node* tree) else { ret_value->type = H5Z_XFORM_DIVIDE; - ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild); - ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild); + ret_value->lchild = (H5Z_node*) H5Z_xform_copy_tree(tree->lchild, dat_val_pointers, new_dat_val_pointers); + ret_value->rchild = (H5Z_node*) H5Z_xform_copy_tree(tree->rchild, dat_val_pointers, new_dat_val_pointers); } } else @@ -1540,6 +1661,8 @@ H5Z_xform_create(const char *expr) { H5Z_data_xform_t *data_xform_prop=NULL; H5Z_data_xform_t *ret_value; + unsigned int i; + unsigned int count = 0; FUNC_ENTER_NOAPI(H5Z_xform_create, NULL) @@ -1549,17 +1672,34 @@ H5Z_xform_create(const char *expr) if((data_xform_prop = H5MM_calloc(sizeof(H5Z_data_xform_t)))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform info") + if((data_xform_prop->dat_val_pointers = HDmalloc(sizeof(H5Z_datval_ptrs))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform array storage") + /* copy the user's string into the property */ if((data_xform_prop->xform_exp = H5MM_xstrdup(expr))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform expression") - /* we generate the parse tree right here and store a poitner to its root in the property. */ - if((data_xform_prop->parse_root = H5Z_xform_parse(expr))==NULL) + /* Find the number of times "x" is used in this equation, and allocate room for storing that many points */ + for(i=0; i<strlen(expr); i++) + { + if(isalpha(expr[i])) + count++; + } + if((data_xform_prop->dat_val_pointers->ptr_dat_val = (void*) HDcalloc(count, sizeof(void*))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for pointers in transform array") + + /* Initialize the num_ptrs field, which will be used to keep track of the number of copies + * of the data we have for polynomial transforms */ + data_xform_prop->dat_val_pointers->num_ptrs = 0; + + /* we generate the parse tree right here and store a poitner to its root in the property. */ + if((data_xform_prop->parse_root = H5Z_xform_parse(expr, data_xform_prop->dat_val_pointers))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform parse tree") /* Assign return value */ ret_value=data_xform_prop; + done: /* Clean up on error */ if(ret_value==NULL) { @@ -1607,6 +1747,9 @@ H5Z_xform_destroy(H5Z_data_xform_t *data_xform_prop) /* Free the expression */ H5MM_xfree(data_xform_prop->xform_exp); + /* Free the data storage struct */ + H5MM_xfree(data_xform_prop->dat_val_pointers); + /* Free the node */ H5MM_xfree(data_xform_prop); } /* end if */ @@ -1639,6 +1782,8 @@ H5Z_xform_destroy(H5Z_data_xform_t *data_xform_prop) herr_t H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop) { + unsigned int i; + unsigned int count = 0; H5Z_data_xform_t *new_data_xform_prop=NULL; herr_t ret_value=SUCCEED; @@ -1652,9 +1797,24 @@ H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop) /* Copy string */ if((new_data_xform_prop->xform_exp = H5MM_xstrdup((*data_xform_prop)->xform_exp))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform expression") - + + if((new_data_xform_prop->dat_val_pointers = HDmalloc(sizeof(H5Z_datval_ptrs))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform array storage") + + /* Find the number of times "x" is used in this equation, and allocate room for storing that many points */ + for(i=0; i<strlen(new_data_xform_prop->xform_exp); i++) + { + if(isalpha(new_data_xform_prop->xform_exp[i])) + count++; + } + if((new_data_xform_prop->dat_val_pointers->ptr_dat_val = (void*) HDcalloc(count, sizeof(void*))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for pointers in transform array") + + /* Zero out num_pointers prior to H5Z_xform_cop_tree call; that call will increment it to the right amount */ + new_data_xform_prop->dat_val_pointers->num_ptrs = 0; + /* Copy parse tree */ - if((new_data_xform_prop->parse_root = (H5Z_node*)H5Z_xform_copy_tree((*data_xform_prop)->parse_root)) == NULL) + if((new_data_xform_prop->parse_root = (H5Z_node*)H5Z_xform_copy_tree((*data_xform_prop)->parse_root, (*data_xform_prop)->dat_val_pointers, new_data_xform_prop->dat_val_pointers)) == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "error copying the parse tree") /* Copy new information on top of old information */ @@ -1706,3 +1866,38 @@ H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop) FUNC_LEAVE_NOAPI(ret_value) } /* H5Z_xform_noop() */ + +/*------------------------------------------------------------------------- + * Function: H5Z_xform_extract_xform_str + * + * Purpose: Extracts the pointer to the data transform strings from the + * data transform property.` + * Return: + * Pointer to the string in the data_xform property. + * + * Programmer: Leon Arber, larber@ncsa.uiuc.edu + * + * Date: Sept. 4, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +char * +H5Z_xform_extract_xform_str(const H5Z_data_xform_t *data_xform_prop) +{ + char* ret_value; + + FUNC_ENTER_NOAPI_NOFUNC(H5Z_xform_extract_xform_str) + + /* There should be no way that these can be NULL since the function + * that calls this one checks to make sure they aren't before + * pasing them */ + assert(exp); + assert(data_xform_prop); + + ret_value = data_xform_prop->xform_exp; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5Z_xform_extract_xform_str() */ + |