/****************************************************************************** FILE: blk_asc.c Purpose: routines for converting a block file to ASCII. Concern given to machine type from which input block file was created, but the output is ASCII. Called by: asc_dump.c 95/08 (JR) - removed some redundant code (dbint_sd[] and identify_ms_code) ******************************************************************************/ #include "dbinc.h" #include "mc0.h" /* convert_*() */ #include "mc.h" /*-------------------- BYTE-COPYING FLAGS --------------------*/ #define AS_IS 0 #define INVERTED 1 #define SPECIAL 2 /* global variables */ FILE *fpin, *fpasc; BLOCK_HDR_TYPE dest_bh; DATA_LIST_ENTRY_TYPE dest_data_list[MAX_DATA_LIST_SIZE]; STRUCT_DEF_HDR_TYPE *dest_block_strdef; STRUCT_DEF_HDR_TYPE *dest_struct_def = NULL; DATA_DIR_ENTRY_TYPE dest_data_dir[MAX_DATA_LIST_SIZE]; char *dest_profile_dir; long file_nbytes; int from, to; int write_blk_ftr(void); void write_asc_block_hdr(void); void write_asc_data_list(void); void strip_blk_name(char *outfile, char *infile); int convert_asc_data_list(void); int convert_asc_block_strdef(void); int convert_asc_profile_dir(void); int convert_asc_block_var_data(void); int convert_asc_profiles(void); /*----------------------------------------------------------------------------- FUNCTION: convert_blk_ascii Converts a CODAS block file named , which could have been a different machine, to an ASCII file of the destination machine. RETURNS: 0 if okay CODAS error code otherwise */ int convert_blk_asc(char *infile, int destmach) { char outfile[13]; int ierr = 0, ftr_missing=0; /*STRUCT_DEF_HDR_TYPE **link_address;*/ BLOCK_HDR_TYPE src_bh; /* -----> OPEN CODAS BLOCK FILE */ if ((fpin = open_binary_file(infile, READ_ONLY)) == NULL) { return(FILE_PROTECTION_ERROR); } /* -----> OPEN ASCII OUTPUT FILE */ strip_blk_name( outfile, infile ); /* make output filename */ if ( (fpasc = fopen(outfile, "w")) == NULL ) return(FILE_PROTECTION_ERROR); file_nbytes = 0; /* -----> READ IN BLOCK HEADER */ if ((ierr = read_data(fpin, (char *) &src_bh, 0L, BLOCK_HDR_SIZE)) != 0) return(ierr); /* -----> IDENTIFY SOURCE MACHINE CODE */ if ((from = identify_ms_code(src_bh.ms_code)) == UNKNOWN_HOST) return(UNKNOWN_HOST_ERROR); to = destmach; /* -----> CONVERT BLOCK HEADER from SOURCE to HOST BYTE ORDER */ if (convert_struct((char *) &dest_bh, (char *) &src_bh, from, HOST_ENVIRONMENT, "block_hdr", &(dbint_sd[0].block_hdr)) == BADUINT) return(CONVERT_ERROR); /* -----> WRITE OUT BLOCK FOOTER TO ASCII OUTPUT */ ftr_missing = write_blk_ftr( ); if( ftr_missing != 0 && ftr_missing != 1 ) goto free_data; /* -----> WRITE OUT SELECTED BLOCK HEADER ELEMENTS TO ASCII OUTPUT */ if( ftr_missing ) write_asc_block_hdr(); file_nbytes = BLOCK_HDR_SIZE; /*increment global var for file offset */ /* -----> CONVERT and WRITE OUT SELECTED DATA LIST ELEMENTS TO ASCII OUTPUT */ if ((ierr = convert_asc_data_list()) != 0) goto free_data; /* -----> FILL MEMEORY WITH BLOCK STRUCTURE DEFINITIONS */ if ((ierr = convert_asc_block_strdef()) != 0) goto free_data; if (dest_bh.struct_def_nentries > 0) concat_strdef(&dest_struct_def, dest_block_strdef); /* -----> CONVERT PROFILE DIRECTORY TO HOST MACHINE AND SAVE IN MEMORY */ if ((ierr = convert_asc_profile_dir()) != 0) goto free_data; /* -----> CONVERT and WRITE OUT BLOCK VARIABLES TO ASCII OUTPUT */ if ((ierr = convert_asc_block_var_data()) != 0) goto free_data; /* -----> CONVERT and WRITE OUT PROFILE VARIABLES TO ASCII OUTPUT */ if ((ierr = convert_asc_profiles()) != 0) goto free_data; if (dest_struct_def == dest_block_strdef) dest_struct_def = NULL; free_data: free(dest_block_strdef); free(dest_profile_dir); /*if (db_ptr->prev_strdef) { link_address = (STRUCT_DEF_HDR_TYPE **) &(db_ptr->prev_strdef->LINK_PTR); *link_address = NULL; }*/ /* close_files: */ fclose(fpasc); fclose(fpin); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: write_asc_block_hdr It writes out as ASCII select portions of block header to output FILE *fpasc (global variable). RETURNS: VOID */ void write_asc_block_hdr(void) { fprintf(fpasc,"START_BLOCK_HEADER:"); fprintf(fpasc,"\ndataset id: %.32s", (char *) &(dest_bh.dataset_id)); fprintf(fpasc,"\nproducer id: %.32s", (char *) &(dest_bh.producer_id)); fprintf(fpasc,"\ntime: "); prpckt(fpasc, &(dest_bh.time1)); fprintf(fpasc," --- to --- "); prpckt(fpasc, &(dest_bh.time2)); fprintf(fpasc,"\nlongitude: "); prpckp(fpasc, &(dest_bh.lon1)); fprintf(fpasc," --- to --- "); prpckp(fpasc, &(dest_bh.lon2)); fprintf(fpasc,"\nlatitude: "); prpckp(fpasc, &(dest_bh.lat1)); fprintf(fpasc," --- to --- "); prpckp(fpasc, &(dest_bh.lat2)); fprintf(fpasc,"\ndepth: %d", dest_bh.depth1); fprintf(fpasc," --- to --- %d", dest_bh.depth2); fprintf(fpasc,"\nEND_BLOCK_HEADER:"); } /*----------------------------------------------------------------------------- FUNCTION: write_asc_data_list Write out in ASCII selected elements of each entry in the data list. RETURNS: VOID */ #if PROTOTYPE_ALLOWED void write_asc_data_list(void) #else void write_asc_data_list() #endif { int i, ic=0; struct t_tag { char bv_type[8]; }; static struct t_tag actype[3] = { {" "}, {" BLOCK"}, {"PROFILE"} }; struct o_tag { char org[13]; }; static struct o_tag orgtype[2] = { {"BINNED_ARRAY"},{"STRUCTURE"} }; int iorg; /* count number of data entries for output */ for (i = 0; i < dest_bh.data_list_nentries; i++) if (dest_data_list[i].access_type) ic++; fprintf(fpasc,"\nSTART_DATA_LIST: NUMBER OF ENTRIES= %d\n", ic); fprintf(fpasc," # name units variable_type organization\n"); fprintf(fpasc,"------------------------------------------------------------\n"); /* -----> FOR EACH ENTRY, WRITE OUT THE NAME, UNITS, and note for BLOCK OR PROFILE VARIABLE */ for (i = 0; i < dest_bh.data_list_nentries; i++) if (dest_data_list[i].access_type) { iorg = 0; /* index for binned array vs structure type */ if( dest_data_list[i].value_type == 11 ) iorg = 1; fprintf(fpasc,"%2d", i); fprintf(fpasc," %-20s%-7.7s %s %s\n", dest_data_list[i].name, dest_data_list[i].units, actype[dest_data_list[i].access_type].bv_type, orgtype[iorg].org); } fprintf(fpasc,"END_DATA_LIST: \n"); } /*----------------------------------------------------------------------------- FUNCTION: strip_blk_name Strips out root name of block file for use as root name of ascii file RETURNS: VOID */ void strip_blk_name(char *af, char *bf ) { int path=0; /* FIXME: this function is dangerous, potentially overrunning strings. It is probably also unix-specific. */ /*test if path provided: contains a slash or starts with a dot*/ if( (strchr( bf, '\057' ) != '\0') || *bf == '\056' ) path = 1; if( path ) { /* move pointer to end of string */ while( *bf++ != '\0' ) ; /* find slash before file name */ while( *bf-- != '\057' ) ; /* place pointer at start of filename */ bf += 2; } /* grab file name root */ while( *bf != '\056' ) *af++ = *bf++; /* add file extension for ascii */ *af++ = '\056'; *af++ = 'a'; *af++ = 's'; *af++ = 'c'; *af = '\0'; } /*----------------------------------------------------------------------------- FUNCTION: convert_asc_data_list Converts the data list structure in a CODAS block file to the HOST_ENVIRONMENT machine format and writes it to the output file. P.Caldwell April, 1994: this is a modified version of convert_data_list from file mc1.c RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, or CONVERT_ERROR otherwise */ int convert_asc_data_list(void) { unsigned int nbytes; int ierr; char *buf; if (dest_bh.data_list_nentries > 0) { nbytes = dest_bh.data_list_nentries * DATA_LIST_ENTRY_SIZE; if (nbytes == 0) return(DATA_LIST_IS_EMPTY); if ((buf = malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, buf, BLOCK_HDR_SIZE, nbytes)) != 0) return(ierr); if (convert_array_struct( (char *) dest_data_list, buf, from, HOST_ENVIRONMENT, dest_bh.data_list_nentries, "data_list_entry", &(dbint_sd[0].data_list_entry)) == BADUINT) return(CONVERT_ERROR); free(buf); file_nbytes += nbytes; write_asc_data_list(); /* WRITE OUT DATA LIST IN ASCII */ } return(0); } /*----------------------------------------------------------------------------- FUNCTION: convert_asc_block_strdef Converts the structure definitions in a CODAS block file to the HOST_ENVIRONMENT machine format. P.Caldwell April, 1994: this is a modified version of convert_block_strdef from file mc1.c RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, or CONVERT_ERROR otherwise */ int convert_asc_block_strdef(void) { STRUCT_DEF_HDR_TYPE *dest_ptr; STRUCT_DEF_HDR_TYPE *src_ptr; STRUCT_DEF_ENTRY_TYPE *sde_ptr; DB_STRUCT_DEF_ENTRY_TYPE *dbsde_ptr; unsigned int nbytes, nbytes_db, nelem, ofs = 0, i, converted_nb; int ierr; int nentries; char *buf, *buf2; nentries = dest_bh.struct_def_nentries; if (nentries > 0) { nbytes_db = nentries * DB_STRUCT_DEF_ENTRY_SIZE; nbytes = nentries * STRUCT_DEF_ENTRY_SIZE; if ( (buf = malloc(nbytes_db)) == NULL || (dest_block_strdef = (STRUCT_DEF_HDR_TYPE *) malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, buf, BLOCK_HDR_SIZE + dest_bh.data_list_nentries * DATA_LIST_ENTRY_SIZE, nbytes_db)) != 0) return(ierr); if (DB_STRUCT_DEF_ENTRY_SIZE != STRUCT_DEF_ENTRY_SIZE) { buf2 = calloc(nentries, STRUCT_DEF_ENTRY_SIZE); if (buf2 == NULL) return(INSUFFICIENT_MEMORY); dbsde_ptr = (DB_STRUCT_DEF_ENTRY_TYPE *) buf; sde_ptr = (STRUCT_DEF_ENTRY_TYPE *) buf2; for (i=0; inelem; for (i = 0; i < nelem; i++) { dest_ptr = (STRUCT_DEF_HDR_TYPE *) (((char *) dest_block_strdef) + ofs); src_ptr = (STRUCT_DEF_HDR_TYPE *) ((char *) buf + ofs); if ((converted_nb = convert_struct((char *) dest_ptr, (char *) src_ptr, from, HOST_ENVIRONMENT, "struct_def_elem", &(dbint_sd[0].struct_def_elem))) == BADUINT) return(CONVERT_ERROR); if (convert_struct((char *) src_ptr, (char *) dest_ptr, HOST_ENVIRONMENT, to, "struct_def_elem", &(dbint_sd[0].struct_def_elem)) == BADUINT) return(CONVERT_ERROR); ofs += converted_nb; } } while (ofs < nbytes); free(buf); file_nbytes += nbytes; } return(0); } /*----------------------------------------------------------------------------- FUNCTION: convert_asc_profile_dir Converts the profile directory in a CODAS block file to the HOST_ENVIRONMENT machine format. P.Caldwell April, 1994: this is a modified version of convert_profile_dir from file mc1.c RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, CONVERT_ERROR, or INVALID_DIRECTORY_TYPE otherwise */ int convert_asc_profile_dir(void) { unsigned int nbytes; char struct_def_name[20]; int ierr; char *buf; if (dest_bh.dir_nentries > 0) { sprintf(struct_def_name, "profile_dir_%1u_entry", (unsigned) dest_bh.dir_type); nbytes = dest_bh.dir_nentries * dest_bh.dir_entry_nbytes; if (nbytes == 0) return(PROFILE_DIR_IS_EMPTY); if ((buf = malloc(nbytes)) == NULL || (dest_profile_dir = malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, buf, dest_bh.dir_ofs, nbytes)) != 0) return(ierr); if (convert_array_struct(dest_profile_dir, buf, from, to, dest_bh.dir_nentries, struct_def_name, &(dbint_sd[0].profile_dir_0_entry)) == BADUINT) return(CONVERT_ERROR); free(buf); file_nbytes += nbytes; } return(0); } /*----------------------------------------------------------------------------- FUNCTION: convert_asc_block_var_data Converts all the block-variable data in a CODAS block file to the HOST_ENVIRONMENT machine format and writes them to an ASCII output file. P.Caldwell April, 1994: this is a modified version of convert_block_var_data from file mc1.c RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, or CONVERT_ERROR otherwise */ int convert_asc_block_var_data(void) { unsigned int i, nbytes, nv; int ierr; char *buf, *vdat; fprintf(fpasc,"START_BLOCK_VARIABLES:\n"); for (i = 0; i < dest_bh.data_list_nentries; i++) if ( dest_data_list[i].access_type == BLOCK_VAR_ACCESS_CODE) { nbytes = dest_data_list[i].access_1; if (nbytes == 0) continue; if ((buf = malloc(nbytes)) == NULL || (vdat = malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, buf, dest_data_list[i].access_0, nbytes)) != 0) return(ierr); if (dest_data_list[i].value_type == STRUCT_VALUE_CODE) nv = -nbytes; else nv = nbytes / VALUE_SIZE[dest_data_list[i].value_type]; if (convert_select(vdat, buf, from, to, nv, dest_data_list[i].value_type, dest_data_list[i].name, dest_struct_def) == BADUINT) return(CONVERT_ERROR); free(buf); file_nbytes += nbytes; /* ---> Write out in ASCII */ if( dest_data_list[i].value_type == 11 ) fprintf(fpasc,"START_STRUCT:"); else fprintf(fpasc,"START_ARRAY:"); print_select( fpasc, vdat, (STRUCT_DEF_ELEM_TYPE *) &(dest_data_list[i]), nv, NULL, dest_struct_def ); if( dest_data_list[i].value_type == 11 ) fprintf(fpasc,"END_STRUCT:\n"); else fprintf(fpasc,"\nEND_ARRAY:\n"); free(vdat); } fprintf(fpasc,"END_BLOCK_VARIABLES:\n"); return(0); } /*----------------------------------------------------------------------------- FUNCTION: convert_asc_profiles Converts the data directories and profile-variable data in a CODAS block file to the HOST_ENVIRONMENT machine format and writes them to the output file as ASCII. P.Caldwell April, 1994: this is a modified version of convert_profiles from file mc1.c RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, INVALID_TYPE_REQUEST, or CONVERT_ERROR otherwise */ int convert_asc_profiles(void) { PROFILE_DIR_3_ENTRY_TYPE *profile_dir_entry_ptr; unsigned int i, j, nbytes, nv; int ierr, index; LONG old_ofs, *new_ofs; YMDHMS_TIME_TYPE time_prof; YMDHMS_TIME_TYPE block_base_time; char *buf, *vdat; unsigned int print_rescale_select(FILE *fp, char *data, DATA_LIST_ENTRY_TYPE *nuv, unsigned int n); int get_asc_data_list_ndx( unsigned int j ); fprintf(fpasc,"START_PROFILE_VARIABLES: NUMBER PROFILES= %d\n", dest_bh.dir_nentries); nbytes = dest_bh.data_dir_nentries * DATA_DIR_ENTRY_SIZE; UPCKTIM(&(block_base_time), &(dest_bh.time1)); /* --> FOR EACH PROFILE DIRECTORY ENTRY */ for (i = 0; i < dest_bh.dir_nentries; i++) { /* ---> PRINT OUT PROFILE KEY AND PROFILE DTG/POSITION */ fprintf(fpasc,"START_PROFILE_%d:\n",i+1); profile_dir_entry_ptr = (PROFILE_DIR_3_ENTRY_TYPE *) (dest_profile_dir + i * dest_bh.dir_entry_nbytes); fprintf(fpasc,"Time= "); DIFTIM((YMDHMS_TIME_TYPE *)&(block_base_time), &time_prof, (LONG *)&(profile_dir_entry_ptr->time)); print_ymdhms_time(fpasc, &time_prof); if (dest_bh.dir_type == 1 || dest_bh.dir_type == 3) { fprintf(fpasc,"\nLongitude= " ); prpckp(fpasc, &(profile_dir_entry_ptr->lon)); fprintf(fpasc," Latitude= " ); prpckp(fpasc, &(profile_dir_entry_ptr->lat)); } /* ---> ALLOCATE MEMORY TO HOLD DATA DIRECTORY FOR THIS PROFILE, SET POINTER TO THE START OF DATA DIRECTORY, CONVERT THE DATA DIRECTORY TO HOST MACHINE, HOLD IN MEMORY, AND FREE BUFFER */ if ((buf = malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); old_ofs = *((LONG *) (dest_profile_dir + i * dest_bh.dir_entry_nbytes)); if ((ierr = read_data(fpin, buf, old_ofs, nbytes)) != 0) return(ierr); if (convert_array_struct((char *) dest_data_dir, buf, from, HOST_ENVIRONMENT, dest_bh.data_dir_nentries, "data_dir_entry", &(dbint_sd[0].data_dir_entry)) == BADUINT) return(CONVERT_ERROR); free(buf); /* The next two lines added 8/1/90: The profile offsets may change if profiles get deleted or profile data shrink via DBPUT or ... */ new_ofs = (LONG *)(dest_profile_dir + i * dest_bh.dir_entry_nbytes); *new_ofs = file_nbytes; file_nbytes += nbytes; /* ----> FOR EACH DATA DIRECTORY ENTRY */ for (j = 0; j < dest_bh.data_dir_nentries; j++) { if ((index = get_asc_data_list_ndx(j)) < 0) return(INVALID_TYPE_REQUEST); if (dest_data_dir[j].nbytes == 0) continue; if ((buf = malloc(dest_data_dir[j].nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((vdat = malloc(dest_data_dir[j].nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, buf, old_ofs + dest_data_dir[j].ofs, dest_data_dir[j].nbytes)) != 0) return(ierr); if (dest_data_list[index].value_type == STRUCT_VALUE_CODE) nv = -(dest_data_dir[j].nbytes); else nv = dest_data_dir[j].nbytes / VALUE_SIZE[dest_data_list[index].value_type]; if (convert_select(vdat, buf, from, to, nv, dest_data_list[index].value_type, dest_data_list[index].name, dest_block_strdef) == BADUINT) return(CONVERT_ERROR); free(buf); file_nbytes += dest_data_dir[j].nbytes; if( dest_data_list[index].value_type == 11 ) fprintf(fpasc,"\nSTART_STRUCT:"); else fprintf(fpasc,"\nSTART_ARRAY:"); /* ---> SPECIAL ATTENTION FOR OFFSET AND SCALE ADJUSTMENTS */ if( dest_data_list[index].offset != 0. || dest_data_list[index].scale != 1. ) print_rescale_select( fpasc, vdat, &(dest_data_list[index]), nv); else print_select( fpasc, vdat, (STRUCT_DEF_ELEM_TYPE *) &(dest_data_list[index]), nv, NULL, dest_block_strdef ); if( dest_data_list[index].value_type == 11 ) fprintf(fpasc,"END_STRUCT:"); else fprintf(fpasc,"\nEND_ARRAY:"); free(vdat); } fprintf(fpasc,"\nEND_PROFILE_%d:\n",i+1); } fprintf(fpasc,"END_PROFILE_VARIABLES:"); return(0); } /*----------------------------------------------------------------------------- FUNCTION: get_asc_data_list_ndx Returns the data list ID number of a profile variable, given its data directory ID number. Modified version of get_data_list_ndx for ascii dump program (Pat Caldwell April 1994) RETURNS: the data list ID number if okay -1 if the data directory ID number is invalid or does not correspond to profile-variable data */ int get_asc_data_list_ndx(unsigned int index) { int i = 0; while (i < dest_bh.data_list_nentries) { if ((dest_data_list[i].access_type == PROFILE_VAR_ACCESS_CODE) && (dest_data_list[i].access_0 == (ULONG) index)) return(i); i++; } return(-1); } /*----------------------------------------------------------------------------- FUNCTION: pr_rescale_select This function prints data to a file using either given or default formats AFTER RESCALING THE DATA BASED ON OFFSET AND SCALE AS DEFINED IN THE DATA LIST. The data can be of any type from VALUE_CODE--single element, array, or structure. THIS IS A MODIFIED VERSION OF PRINT_SELECT (PCC 4/11/94) PARAMETERS: fp = pointer to FILE to print to data = pointer to data to be printed nuv = pointer to structure with ff. members: 1) name = variable name for data 2) units = variable units ("none" or "" or NULL if not applicable) 3) value_type = VALUE_CODE (0 to 11) The structure may therefore correspond to a DATA_LIST_ENTRY_TYPE or a STRUCT_DEF_ELEM_TYPE. n = no. of elements in data */ unsigned int print_rescale_select(FILE *fp, char *data, DATA_LIST_ENTRY_TYPE *nuv, unsigned int n) { int ncol; unsigned int byte_count = 0; FLOAT *rdat; static char format[]= "%12.6f"; fprintf(fp, " %20s : ", nuv->name); fprintf(fp, "in %s ", nuv->units); fprintf(fp, "(%u VALUES)\n\n", n); /* ---> Rescale and apply offset */ if ((rdat = (FLOAT *) malloc ( n * sizeof( FLOAT ) )) == NULL) return(INSUFFICIENT_MEMORY); switch (nuv->value_type) { case BYTE_VALUE_CODE: UNSCALE_BYTE_TO_FLOAT( rdat, (BYTE *) data, &(nuv->scale), &(nuv->offset), &n); break; case UBYTE_VALUE_CODE: UNSCALE_UBYTE_TO_FLOAT( rdat, (UBYTE *) data, &(nuv->scale), &(nuv->offset), &n); break; case SHORT_VALUE_CODE: UNSCALE_SHORT_TO_FLOAT( rdat, (SHORT *) data, &(nuv->scale), &(nuv->offset), &n); break; case USHORT_VALUE_CODE: UNSCALE_USHORT_TO_FLOAT( rdat, (USHORT *) data, &(nuv->scale), &(nuv->offset), &n); break; case LONG_VALUE_CODE: UNSCALE_LONG_TO_FLOAT( rdat, (LONG *) data, &(nuv->scale), &(nuv->offset), &n); break; case ULONG_VALUE_CODE: UNSCALE_ULONG_TO_FLOAT( rdat, (ULONG *) data, &(nuv->scale), &(nuv->offset), &n); break; case FLOAT_VALUE_CODE: UNSCALE_FLOAT_TO_FLOAT( rdat, (FLOAT *) data, &(nuv->scale), &(nuv->offset), &n); break; case DOUBLE_VALUE_CODE: UNSCALE_DOUBLE_TO_FLOAT( rdat, (DOUBLE *) data, &(nuv->scale), &(nuv->offset), &n); break; } ncol = 6; byte_count = print_array_float(fp, rdat, n, ncol, format); free(rdat); return(byte_count); } /******************************************************************* FUNCTION write_blk_ftr Converts the block footer in a CODAS block file to the HOST_ENVIRONMENT machine format and writes it to the ascii output file. RETURN 0 if ok 1 if footer missing special code if not ok */ int write_blk_ftr(void) { unsigned int nbytes; int ierr; char *dest_buf; if( dest_bh.block_ftr_ofs == 0 ) return(1); nbytes = dest_bh.block_nbytes - dest_bh.block_ftr_ofs; if (nbytes == 0) return(0); if ((dest_buf = malloc(nbytes)) == NULL) return(INSUFFICIENT_MEMORY); if ((ierr = read_data(fpin, dest_buf, dest_bh.block_ftr_ofs, nbytes)) != 0) return(ierr); /* write out to ascii file */ fprintf(fpasc,"\nSTART_DOCUMENTATION: \n"); fwrite( dest_buf, nbytes, 1, fpasc ); fprintf(fpasc,"\nEND_DOCUMENTATION: \n"); free(dest_buf); return(0); }