#include /* NULL */ #include /* stricmp */ #include /* alternative location for stricmp decl. */ #include "dbext.h" /* STRUCT_DEF_HDR_TYPE, LINK_PTR */ #include "find_def.h" /***************************************************************************** * * * COMMON OCEANOGRAPHIC DATA ACCESS SYSTEM (CODAS) * * * * WRITTEN BY: RAMON CABRERA, ERIC FIRING, and JULIE RANADA * * JOINT INSTITUTE FOR MARINE AND ATMOSPHERIC RESEARCH * * 1000 POPE ROAD MSB 404 * * HONOLULU, HI 96822 * * * * VERSION: 3.00 * * * * DATE: APRIL 1989 * * * *****************************************************************************/ /* FILE: find_def.c Function used to find a structure definition from some list. */ /*----------------------------------------------------------------------------- FUNCTION: find_def Given the name of a structure and a pointer to a linked list of structure definitions in memory, it returns a pointer to the definition of the named structure. PARAMETERS: struct_name = name of structure to search for str_def = pointer to linked list of structure definitions in memory RETURNS: NULL if the structure definition for struct_name was not found *structure definition otherwise */ STRUCT_DEF_HDR_TYPE *find_def(char *struct_name, STRUCT_DEF_HDR_TYPE *linked_list) { STRUCT_DEF_HDR_TYPE *str_def_ptr, **next_link; str_def_ptr = linked_list; while (str_def_ptr != NULL) { while (*(str_def_ptr->name)) { if (!stricmp(str_def_ptr->name, struct_name)) /* found */ return(str_def_ptr); str_def_ptr += str_def_ptr->nelem + 1; /* skip to next */ } next_link = (STRUCT_DEF_HDR_TYPE **) &(str_def_ptr->LINK_PTR); str_def_ptr = *next_link; } return(NULL); /* not found */ } /*----------------------------------------------------------------------------- FUNCTION: find_elem Given the name of a structure, the name of a member of that structure, and a linked list of structure definitions, it calculates the buffer (relative) offset to, and the no. of bytes comprising that particular member of the named structure. It also retrieves the member's STRUCT_DEF_ELEM_TYPE information. (Note: The member may be a simple data type or another structure.) PARAMETERS: elem_name = pointer to name of element to search for struct_name = pointer to name of structure to search linked_list = pointer to a linked list of structure definitions data_ofs = pointer to offset to data associated with that element nb = pointer to no. of bytes comprising that element elem_def = pointer to element's definition (STRUCT_DEF_ELEM_TYPE info) RETURNS: 0 if okay database error code otherwise */ int find_elem(char *elem_name, char *struct_name, STRUCT_DEF_HDR_TYPE *linked_list, unsigned int *data_ofs, unsigned int *nb, STRUCT_DEF_ELEM_TYPE *store_def) { STRUCT_DEF_HDR_TYPE *str_def; STRUCT_DEF_ELEM_TYPE *elem_def; int i; long size; /* first find structure definition */ if ( (str_def = find_def(struct_name, linked_list)) == NULL ) return(UNDEFINED_STRUCTURE); /* then cumulate offset and find nb */ for (i = 0, elem_def = (STRUCT_DEF_ELEM_TYPE *) str_def + 1, *data_ofs = 0; i < str_def->nelem; i++, elem_def++) { if ( (size = get_elem_size(elem_def, linked_list)) < 0 ) return(UNDEFINED_STRUCTURE); if (stricmp(elem_name, elem_def->name)) /* no match so increment offset */ *data_ofs += (unsigned int) size; else /* match so now determine no. of bytes */ { *nb = (unsigned int) size; strcpy(store_def->name, elem_def->name); strcpy(store_def->units, elem_def->units); store_def->value_type = elem_def->value_type; store_def->count = elem_def->count; return(0); } } return(NO_SUCH_ELEMENT); /* not found */ } /*----------------------------------------------------------------------------- FUNCTION: get_struct_size It searches a linked list of structure definitions for the given structure name and calculates the size of the structure based on the definition(s) found. PARAMETERS: struct_name = pointer to name of structure to search for (not case-sensitive) linked_list = pointer to head of linked list of structure definitions RETURNS: no. of bytes in structure, if properly defined in linked list -1 on error */ long get_struct_size(char *struct_name, STRUCT_DEF_HDR_TYPE *linked_list) { STRUCT_DEF_HDR_TYPE *str_def; STRUCT_DEF_ELEM_TYPE *elem_def; long size, temp; int i; if ( (str_def = find_def(struct_name, linked_list)) == NULL ) return(-1); for (i = 0, size = 0, elem_def = (STRUCT_DEF_ELEM_TYPE *) str_def + 1; i < str_def->nelem; i++, size += temp, elem_def++) if ( (temp = get_elem_size(elem_def, linked_list)) < 0 ) return(-1); return(size); } /*----------------------------------------------------------------------------- FUNCTION: get_elem_size Given an element definition and the pointer to a linked list of structure definitions, it returns the no. of bytes associated with that element. (The linked list pointer is needed in case the element is a structure.) PARAMETERS: elem_def = pointer to element's STRUCT_DEF_ELEM_TYPE information linked_list = pointer to linked list of structure definitions RETURNS: no. of bytes (>= 0) if okay < 0 if indeterminable (undefined structure) */ long get_elem_size(STRUCT_DEF_ELEM_TYPE *elem_def, STRUCT_DEF_HDR_TYPE *linked_list) { extern UBYTE VALUE_SIZE[]; if (elem_def->value_type != STRUCT_VALUE_CODE) return(elem_def->count * VALUE_SIZE[elem_def->value_type]); else { if (elem_def->count <= 0) return(-(elem_def->count)); return(elem_def->count * get_struct_size(elem_def->name, linked_list)); } }