/*------------------------------------------------------------------------- * * Copyright (C) 2000 National Center for Supercomputing Applications. * All rights reserved. * *------------------------------------------------------------------------- */ /****************************************************************************** Description: 1. converter See HDF4 to HDF5 mapping specification at (http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping from HDF4 object to HDF5 object. The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c. 2. this file including all routines that are useful for other files. Author: Kent Yang(ymuqun@ncsa.uiuc.edu) *****************************************************************************/ #include "h4toh5util.h" /* Function h4toh5_ZeroMemory Purpose: Zero out memory return: None In: size_t n(DWORD in windows) void* s(PVOID in windows) */ void h4toh5_ZeroMemory(void*s,size_t n) { #ifdef WIN32 ZeroMemory(s,n); #else bzero(s,n); #endif } /*------------------------------------------------------------------------- * Function: h5string_to_int * * Purpose: This function will convert H5T_STRING into integer. This is a correction routine when the user define the numerical datatype int8 as DFNT_CHAR8 and DFNT_UCHAR8 * Errors: will return error message to the interface * Return: FAIL if failed, SUCCEED if success * * In : h4type: HDF4 datatype h4memsize: the real memory size of h4type * Out: h5memtype: pointer of which value should be h5memtype(the real data type stored at the memory) h5type: pointer of which value should be h5type(the hdf5 type stored at the disk). * *------------------------------------------------------------------------- */ int h5string_to_int(const int32 h4type, hid_t* h5memtype, const size_t h4memsize,hid_t* h5type) { switch(h4type) { case DFNT_CHAR8: *h5type = H5T_STD_I8BE; if (h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_SCHAR; else if(h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_UCHAR8: *h5type = H5T_STD_U8BE; if (h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; } return SUCCEED; } /*------------------------------------------------------------------------- * Function: h4type_to_h5type * * Purpose: this function will convert HDF4 datatype into HDF5 datatype The converter includes file to file datatype and datasize conversion, file to memory datatype and datasize conversion. Check the mapping document for details. * Errors: will return error message to the interface. * Return: false, FAIL. otherwise,SUCCEED. * * In : h4type: HDF4 datatype. * Out: h4size: the file(disk) size of h4type. h4memsize: the real memory size of h4type. * h5memtype: pointer of which value should be h5memtype(the real type stored at the memory). h5type: pointer of which value should be h5type(the hdf5 type that is stored at the disk). * * *------------------------------------------------------------------------- */ int h4type_to_h5type(const int32 h4type, hid_t* h5memtype, size_t* h4memsize,size_t* h4size, hid_t *h5type) { switch (h4type) { case DFNT_CHAR8: *h4size = 1; *h4memsize = sizeof(int8); /* assume DFNT_CHAR8 C type character. */ *h5memtype = H5T_STRING; *h5type = H5T_STRING; break; case DFNT_UCHAR8: *h4size = 1; *h4memsize = sizeof(int8); *h5memtype = H5T_STRING; *h5type = H5T_STRING; break; case DFNT_INT8: *h4size = 1; *h5type = H5T_STD_I8BE; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_SCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_UINT8: *h4size =1; *h5type = H5T_STD_U8BE; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_NINT8: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 1; *h5type = H5T_NATIVE_SCHAR; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_SCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_NUINT8: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 1; *h5type = H5T_NATIVE_UCHAR; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_LINT8: *h4size = 1; *h5type = H5T_STD_I8LE; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_LUINT8: *h4size = 1; *h5type = H5T_STD_U8LE; *h4memsize = sizeof(int8); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_INT16: *h4size = 2; *h5type = H5T_STD_I16BE; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_CHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_UINT16: *h4size = 2; *h5type = H5T_STD_U16BE; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_NINT16: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 2; *h5type = H5T_NATIVE_SHORT; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_CHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_NUINT16: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 2; *h5type = H5T_NATIVE_USHORT; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_LINT16: *h4size = 2; *h5type = H5T_STD_I16LE; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_LUINT16: *h4size = 2; *h5type = H5T_STD_U16LE; *h4memsize = sizeof(int16); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_INT32: *h4size = 4; *h5type = H5T_STD_I32BE; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_CHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_UINT32: *h4size = 4; *h5type = H5T_STD_U32BE; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_NINT32: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 4; *h5type = H5T_NATIVE_INT; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_CHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_NUINT32: printf("warning, Native HDF datatype is encountered"); printf(" the converting results may not be correct.\n"); *h4size =4; *h5type = H5T_NATIVE_UINT; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_LINT32: *h4size =4; *h5type = H5T_STD_I32LE; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_CHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_SHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_INT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_LONG; else return FAIL; break; case DFNT_LUINT32: *h4size =4; *h5type = H5T_STD_U32LE; *h4memsize = sizeof(int32); if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) *h5memtype = H5T_NATIVE_UCHAR; else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) *h5memtype = H5T_NATIVE_USHORT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) *h5memtype = H5T_NATIVE_UINT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) *h5memtype = H5T_NATIVE_ULONG; else return FAIL; break; case DFNT_FLOAT32: *h4size =4; *h5type = H5T_IEEE_F32BE; *h4memsize = sizeof(float32); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; case DFNT_FLOAT64: *h4size = 8; *h5type = H5T_IEEE_F64BE; *h4memsize = sizeof(float64); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; case DFNT_NFLOAT32: printf("warning, Native HDF datatype is encountered"); printf(" the converting results may not be correct.\n"); *h4size = 4; *h5type = H5T_NATIVE_FLOAT; *h4memsize = sizeof(float32); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; case DFNT_NFLOAT64: printf("warning, Native HDF datatype is encountered"); printf(" the converting result may not be correct.\n"); *h4size = 8; *h5type = H5T_NATIVE_DOUBLE; *h4memsize = sizeof(float64); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; case DFNT_LFLOAT32: *h4size = 4; *h5type = H5T_IEEE_F32LE; *h4memsize = sizeof(float32); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; case DFNT_LFLOAT64: *h4size = 8; *h5type = H5T_IEEE_F64LE; *h4memsize = sizeof(float64); if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) *h5memtype = H5T_NATIVE_FLOAT; else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) *h5memtype = H5T_NATIVE_DOUBLE; else return FAIL; break; default: return FAIL; } return SUCCEED; } /*------------------------------------------------------------------------- * Function: conv_int_str * * Purpose: this function will convert numerical number into the string format for a reference(<=65536). * Return: SUCCEED if success, FAIL if failed. * * In : num: an unsigned digital number that is not greater than 65536. * Out: str_num: character string format of the number. * * *------------------------------------------------------------------------- */ int conv_int_str(uint16 num, char* str_num) { /* the maximum reference number is 65536. */ if(str_num == NULL) { printf(" memory for str_num should be allocated.\n"); return FAIL; } /* Adding this line will cause problems, investigating this later. h4toh5_ZeroMemory(str_num,strlen(str_num)+1);*/ sprintf(str_num,"%d",num); return SUCCEED; } /*------------------------------------------------------------------------- * Function: lookup * * Purpose: this function will use objref as a key to check whether * the current object is touched. * Return: 1, the object is found. 0,the object is not found. -1, the table doesn't exist. * * In : objref: reference number of the current object. SIZE: the hashtable SIZE. hashtab: pointer to the hash table. *------------------------------------------------------------------------- */ int lookup(int objref,int SIZE,struct table*hashtab) { struct table *np; if(hashtab == NULL) { printf("the table doesn't exist. \n"); return -1; } np = hashtab+objref%SIZE; for (np = hashtab+objref%SIZE; np!=NULL;np=np->next){ if (np->ref == objref){ return 1; } } return 0; } /*------------------------------------------------------------------------- * Function: init_tab * * Purpose: this function will initialize the hash table. * * Return: SUCCEED, table is initialzed. FAIL,otherwise. * * In : SIZE: the hashtable SIZE. hashtab: pointer to the hash table. *------------------------------------------------------------------------- */ int init_tab(int SIZE,struct table *hashtab) { int i; if(hashtab == NULL) { printf("memory for hashing table is not allocated.\n"); return FAIL; } for (i = 0;i < SIZE; i++) { (hashtab+i%SIZE)->ref = -1; (hashtab+i%SIZE)->next = NULL; (hashtab+i%SIZE)->name = NULL; } return SUCCEED; } /*------------------------------------------------------------------------- * Function: init_nametab * * Purpose: this function will initialize the name hash table. * * Return: SUCCEED, table is initialzed. FAIL,otherwise. * * In : SIZE: the hashtable SIZE. name_hashtab: pointer to the hash table. *------------------------------------------------------------------------- */ int init_nametab(int SIZE, struct name_table * name_hashtab) { int i; if(name_hashtab == NULL) { printf("cannot allocate memory for name hashing table.\n"); return FAIL; } for (i=0;i < SIZE; i++) { (name_hashtab+i%SIZE)->name = NULL; (name_hashtab+i%SIZE)->next = NULL; } return SUCCEED; } /*------------------------------------------------------------------------- * Function: get_name * * Purpose: obtain the name of the object * * Return: the object name * * In : objref: reference number of the current object. SIZE: the hashtable SIZE. hashtab: pointer to the hash table pcheck_get: a flag to check errors *------------------------------------------------------------------------- */ char* get_name(int objref,int SIZE,struct table*hashtab, int* pcheck_get) { struct table *np; char* tempname; np = hashtab+objref%SIZE; for (np = hashtab+objref%SIZE; np!=NULL;np=np->next){ if (np->ref==objref){ if (np->name == NULL) { *pcheck_get = -1; return NULL; } else { tempname = malloc(strlen(np->name)+1); if(tempname == NULL) { *pcheck_get = -2; return NULL; } strcpy(tempname,np->name); return tempname; } } } *pcheck_get = 0; return NULL; } /*------------------------------------------------------------------------- * Function: set_name * * Purpose: store the name of the object into the hash table * * Return: SUCCEED: the name is either set before or set in this routine * FAIL: the name is not set properly * * In : objref: reference number of the current object SIZE: the hashtable SIZE hashtab: hash table namein: object name *------------------------------------------------------------------------- */ int set_name(int objref,int SIZE,struct table*hashtab, char* namein) { struct table *np; struct table *temptr; temptr = malloc(sizeof(struct table)); if(temptr == NULL) { printf("not enough memory to be allocated. \n"); return FAIL; } np = hashtab+objref%SIZE; if(namein == NULL) { printf("error in inputting name into the table.\n"); return FAIL; } for (np = hashtab+objref%SIZE; np!= NULL;np = np->next){ if (np->ref==objref){ /* the name is set already, don't do anything.*/ return SUCCEED; } if (np->next == NULL) { np->next = temptr; temptr->ref = objref; temptr->next = NULL; temptr->name = malloc(strlen(namein)+1); if(temptr->name == NULL) { printf("error in allocating memory. \n"); return FAIL; } strcpy(temptr->name,namein); return SUCCEED; } } return SUCCEED; } /*------------------------------------------------------------------------- * Function: lookup_name * * Purpose: 1. look up whether the same name is used for different objects 2. then update the table * * Return: 1, if the name is in the name hash table. 0, if the name is to be added into the name table. -1, otherwise. * * In : size: the hashtable SIZE. nametab: name hash table name: the name to be looked up *------------------------------------------------------------------------- */ int lookup_name(char* name, int size,struct name_table *nametab) { /* temporary pointer of the name table that points to the beginning address of the current bucket.*/ struct name_table *np; /* temporary pointer of the added name table.*/ struct name_table *temptr; if(name == NULL) { printf("the name to be looked up is NULL.\n"); return -1; } temptr = malloc(sizeof(struct name_table)); if(temptr == NULL) { printf("not enough memory to be allocated. \n"); return -1; } if(nametab == NULL) { printf("no name_table for this category of objects.\n"); return -1; } np = nametab+hash_fun(name,size); temptr->name = malloc(strlen(name)+1); if(temptr->name == NULL) { printf("not enough memory to be allocated to table name.\n"); return -1; } /* look through the linked list starting from the current bucket. If the name is found, return 1, otherwise, return 0 after inserting the new bucket. */ for(np = nametab+hash_fun(name,size); np!= NULL;np = np->next) { if(np->name == NULL) { np->name = malloc(strlen(name)+1); if(np->name == NULL) { printf("cannot allocate memory for object name.\n"); return -1; } strcpy(np->name,name); free(temptr->name); free(temptr); return 0; } if(strcmp(name,np->name)==0){ free(temptr->name); free(temptr); return 1; } if (np->next == NULL) { np->next = temptr; temptr->next = NULL; strcpy(temptr->name,name); return 0; } } return -1; } /*------------------------------------------------------------------------- * Function: hash_fun * * Purpose: to get the hash value based on the key * * Return: No. of the hashtable * * In : name: object name size: the hashtable size. *------------------------------------------------------------------------- */ int hash_fun(char *name,int size) { int hashval; for (hashval = 0;*name !='\0';) hashval += *name++; return(hashval%size); } /*------------------------------------------------------------------------- * Function: freenametable * * Purpose: free the memory of hash table * * Return: 0 * * In : SIZE: the hashtable SIZE. nametab: hash table of the name *------------------------------------------------------------------------- */ int freenametable(int SIZE,struct name_table *nametab) { struct name_table *np,*temptr,*temptr1; int i; if(nametab == NULL) return 0; /* we first free the additional linked items of the hashtable, and then free the whole hash table. */ for (i = 0;i < SIZE; i++) { np = nametab+i; temptr1 = np->next; while(temptr1 != NULL) { temptr = temptr1; temptr1 = temptr1->next; free(temptr->name); free(temptr); } if(np->name !=NULL) free(np->name); } free(nametab); return 0; } /*------------------------------------------------------------------------- * Function: freetable * * Purpose: free the memory of hash table * * Return: 0 * * In : SIZE: the hashtable SIZE. nametab: hash table *------------------------------------------------------------------------- */ int freetable(int SIZE,struct table *hashtab) { struct table *np,*temptr,*temptr1; int i; if(hashtab == NULL) return 0; /* we first free the additional linked items of the hashtable, and then free the whole hash table. */ for (i =0;i < SIZE; i++) { np = hashtab+i; temptr1 = np->next; while(temptr1 != NULL) { temptr = temptr1; temptr1 = temptr1->next; free(temptr->name); free(temptr); } if(np->name != NULL) free(np->name); } free(hashtab); return 0; } /*------------------------------------------------------------------------- * Function: mkstr * * Purpose: make hdf5 string type * * Return: type * * In : size: String Size H5T_str_t: pad *------------------------------------------------------------------------- */ hid_t mkstr(int size, H5T_str_t pad) { hid_t type; if((type=H5Tcopy(H5T_C_S1))<0) return -1; if((H5Tset_size(type,(size_t)size))<0) return -1; if((H5Tset_strpad(type,pad))<0) return -1; return type; } /*------------------------------------------------------------------------- * Function: h4_transnumattr * * Purpose: translate reference number into hdf5 attribute * * Return: FAIL if failed, SUCCEED if successful. * * In : h5g: hdf5 group id refname: reference name group_ref: reference number *------------------------------------------------------------------------- */ int h4_transnumattr(hid_t h5g,const char *refname,uint16 group_ref) { hid_t h5memtype=(-1); hid_t h5a_id; hid_t h5a_sid; herr_t ret; h5a_sid = H5Screate(H5S_SCALAR); if (h5a_sid < 0) { fprintf(stderr,"failed to create attribute space for HDF4_REF_NUM. \n"); return FAIL; } h5a_id = H5Acreate(h5g,refname,H5T_STD_U16BE,h5a_sid,H5P_DEFAULT); if(h5a_id <0) { fprintf(stderr,"failed to obtain attribute id for HDF4_REF_NUM. \n"); H5Sclose(h5a_sid); return FAIL; } if(H5Tget_size(H5T_NATIVE_CHAR)== sizeof(uint16)) h5memtype = H5T_NATIVE_UCHAR; else if(H5Tget_size(H5T_NATIVE_SHORT)== sizeof(uint16)) h5memtype = H5T_NATIVE_USHORT; else if(H5Tget_size(H5T_NATIVE_INT) == sizeof(uint16)) h5memtype = H5T_NATIVE_UINT; else if(H5Tget_size(H5T_NATIVE_LONG)== sizeof(uint16)) h5memtype = H5T_NATIVE_ULONG; ret = H5Awrite(h5a_id,h5memtype,(void *)&group_ref); if(ret <0) { printf("failed to obtain attribute.\n "); H5Sclose(h5a_sid); H5Aclose(h5a_id); return FAIL; } ret = H5Sclose(h5a_sid); ret = H5Aclose(h5a_id); return SUCCEED; } /*------------------------------------------------------------------------- * Function: h4_transpredattrs * * Purpose: translate predefined attributes into hdf5 attribute * predefined attributes include HDF4 OBJECT TYPE, HDF4 OBJECT NAME, HDF4 CLASS etc. They are all in H5T_STRING format. * Return: FAIL if failed, SUCCEED if successful. * * In : h5g: group id attrname: attribute name data: attribute data *------------------------------------------------------------------------- */ int h4_transpredattrs(hid_t h5g,const char *attrname,char*data){ hsize_t h5str_size; hid_t h5a_id; hid_t h5a_sid; hid_t h5str_type; herr_t ret; if(data == NULL) { printf("attribute data is not available.\n"); return FAIL; } h5str_size = strlen(data); if ((h5str_type = mkstr(h5str_size,H5T_STR_SPACEPAD))<0) { printf("error in making string for predefined ATTR. \n"); return FAIL; } h5a_sid = H5Screate(H5S_SCALAR); if (h5a_sid < 0) { printf("failed to create attribute space for HDF4_OBJECT. \n"); return FAIL; } h5a_id = H5Acreate(h5g,attrname,h5str_type,h5a_sid,H5P_DEFAULT); if(h5a_id <0) { fprintf(stderr,"failed to obtain attribute id for HDF4_OBJECT. \n"); H5Sclose(h5a_sid); return FAIL; } ret = H5Awrite(h5a_id,h5str_type,(void *)data); if(ret <0) { fprintf(stderr,"failed to obtain attribute.\n "); H5Aclose(h5a_id); H5Sclose(h5a_sid); return FAIL; } ret = H5Sclose(h5a_sid); ret = H5Aclose(h5a_id); return SUCCEED; } /*------------------------------------------------------------------------- * Function: vg_transattrs * * Purpose: translate predefined vgroup attributes into hdf5 attribute * * Return: FAIL if failed, SUCCEED if successful. * * In : h4vg: hdf4 vgroup id h5g: hdf5 group id *------------------------------------------------------------------------- */ int vg_transattrs(int32 h4vg,hid_t h5g) { /* define variables for hdf4. */ char vgroup_name[VGNAMELENMAX]; char vgroup_class[VGNAMELENMAX]; char vgattr_name[MAX_NC_NAME]; char obtype[MAX_NC_NAME]; int32 vgroup_cref; int32 num_vgattr; int32 count_vgattr; int32 vg_atype; int32 attr_size; size_t sh4_size; size_t sh4_amemsize; /* define variables for hdf5. */ hid_t sh5a_sid; hid_t sh5a_id; hid_t sh5_atype; hid_t sh5_amemtype; hid_t sh5str_type; hid_t sh5str_memtype; hsize_t sh5dims[MAX_VAR_DIMS]; void* vg_adata; herr_t sret; int i; num_vgattr = Vnattrs(h4vg); for (i = 0;i 0) freetable(estnum_vg,vg_hashtab); if(estnum_vd > 0) freetable(estnum_vd,vd_hashtab); if(num_sds > 0) { freetable(2*num_sds,sds_hashtab); freenametable(DIM_HASHSIZE,dim_hashtab); } if(num_images > 0) { freetable(2*num_images,gr_hashtab); freetable(PAL_HASHSIZE,pal_hashtab); } if(num_objects > 0) freenametable(num_objects,name_hashtab); } /*------------------------------------------------------------------------- * Function: correct_name * * Purpose: modify the hdf4 object name when the name contains '/'. Change this character into '_'. * * Return: the corrected name * * In : old name *------------------------------------------------------------------------- */ char *correct_name(char* oldname){ char * cptr; char * newname; if(oldname == NULL) { printf("inputting name is wrong.\n"); return NULL; } newname = malloc(strlen(oldname)+1); h4toh5_ZeroMemory(newname,strlen(oldname)+1); newname = strncpy(newname, oldname, strlen(oldname)); while(strchr(newname,ORI_SLASH)!= NULL){ cptr = strchr(newname,ORI_SLASH); *cptr = CHA_SLASH; } return newname; }