/****************************************************************************** FILE: VC1.C Routines to convert a CODAS block file loaded using version 2 into a CODAS version 3 block file. ******************************************************************************/ #include "vc.h" FILE *fpin; long file_nbytes; unsigned int profile_dir_entry_size; /*----------------------------------------------------------------------------- FUNCTION: convert_block_file Converts a CODAS block file named that was created under version 2 into a version 3 file named . RETURNS: 0 if okay CODAS error code otherwise */ int convert_block_file(char *infile, char *outfile) { int ierr; if ((fpin = open_binary_file(infile, READ_ONLY)) == NULL) { ierr = FILE_PROTECTION_ERROR; goto error_found; } if ((db_ptr->fpblkdata = fopen(outfile, "wb+")) == NULL) { ierr = FILE_PROTECTION_ERROR; goto error_found; } file_nbytes = 0; if ((ierr = convert_block_hdr()) != 0) goto error_found; if ((ierr = convert_data_list()) != 0) goto error_found; if (db_ptr->producer->struct_def_max_nentries) { if ((ierr = write_block_strdef()) != 0) goto error_found; file_nbytes += db_ptr->producer->struct_def_max_nentries * STRUCT_DEF_ENTRY_SIZE; } if ((ierr = convert_profile_dir()) != 0) goto error_found; if ((ierr = convert_block_var_data()) != 0) goto error_found; if ((ierr = convert_profiles()) != 0) goto error_found; /*--------------------rewrite profile directory----------------------*/ if ((ierr = write_data(db_ptr->fpblkdata, db_ptr->profile_dir, db_ptr->block_hdr.dir_ofs, profile_dir_entry_size * db_ptr->block_hdr.dir_nentries)) != 0) goto error_found; /*---------------------rewrite data list-----------------------------*/ if ((ierr = write_data_list()) != 0) goto error_found; /*--------------------update & rewrite block header------------------*/ db_ptr->block_hdr.block_nbytes = file_nbytes; if ((ierr = write_block_hdr()) != 0) goto error_found; free(db_ptr->profile_dir); fclose(fpin); fclose(db_ptr->fpblkdata); return(0); error_found: printf("\n ERROR: %d in convert_block_file\n", ierr); free(db_ptr->profile_dir); fclose(fpin); fclose(db_ptr->fpblkdata); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: convert_block_hdr Partially converts a CODAS version 2 block file header into a version 3 block file header and writes it to the output file. Certain field values (offsets, etc.) have to preserved temporarily in order to properly access the remainder of the block file. The new block header will be updated and rewritten later. RETURNS: 0 if okay INCOMPATIBLE_HOST_ERROR, SEEK_ERROR, READ_ERROR or WRITE_ERROR otherwise */ int convert_block_hdr(void) { int index, ierr; set_byte((UBYTE *) &(db_ptr->block_hdr), '\0', BLOCK_HDR_SIZE); if ((index = identify_ms((char *) MACHINE_SIGNATURE)) == -1) { ierr = INCOMPATIBLE_HOST_ERROR; goto error_found; } if ((ierr = read_data(fpin, (char *) &(db_ptr->block_hdr), 0L, OLD_BLOCK_HDR_SIZE)) != 0) goto error_found; strncpy(db_ptr->block_hdr.db_version, DATABASE_SYSTEM_VERSION, 4); strncpy(db_ptr->block_hdr.producer_host, MS_TABLE[index].ms_name, 4); db_ptr->block_hdr.data_list_ofs = BLOCK_HDR_SIZE; db_ptr->block_hdr.struct_def_nentries = db_ptr->producer->struct_def_max_nentries; strncpy(db_ptr->block_hdr.ms_code, MS_TABLE[index].ms_code, 4); if ((ierr = write_block_hdr()) != 0) goto error_found; file_nbytes += BLOCK_HDR_SIZE; return(0); error_found: printf("\n ERROR: %d in convert_block_hdr\n", ierr); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: convert_data_list Partially converts the data list structure in a CODAS version 2 block file into a version 3 data list structure and writes it to the output file. Further updating and rewriting will be performed later. RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, or CONVERT_ERROR otherwise */ int convert_data_list(void) { OLD_DATA_LIST_ENTRY_TYPE *old_dl; unsigned nbytes; int i, ierr; if (db_ptr->block_hdr.data_list_nentries > 0) { nbytes = db_ptr->block_hdr.data_list_nentries * OLD_DATA_LIST_ENTRY_SIZE; if ((old_dl = (OLD_DATA_LIST_ENTRY_TYPE *) malloc(nbytes)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } if ((ierr = read_data(fpin, (char *) old_dl, OLD_BLOCK_HDR_SIZE, nbytes)) != 0) goto error_found; for (i = 0; i < db_ptr->block_hdr.data_list_nentries; i++) { strncpy(db_ptr->data_list[i].name, old_dl[i].name, 20); strncpy(db_ptr->data_list[i].units, old_dl[i].units, 12); db_ptr->data_list[i].value_type = old_dl[i].value_type; db_ptr->data_list[i].access_type = old_dl[i].access_type; db_ptr->data_list[i].access_0 = old_dl[i].access_0; db_ptr->data_list[i].access_1 = old_dl[i].access_1; db_ptr->data_list[i].offset = old_dl[i].offset; db_ptr->data_list[i].scale = old_dl[i].scale; db_ptr->data_list[i].index = i; } free(old_dl); if ((ierr = write_data_list()) != 0) goto error_found; file_nbytes += db_ptr->block_hdr.data_list_nentries * DATA_LIST_ENTRY_SIZE; } return(0); error_found: printf("\n ERROR: %d in convert_data_list", ierr); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: convert_profile_dir Partially converts the profile directory in a CODAS version 2 block file into a version 3 profile directory and writes it to the output file. Further updating and rewriting will be performed later. RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, or INVALID_DIRECTORY_TYPE otherwise */ int convert_profile_dir(void) { char *buf; unsigned int nbytes = 0, old_ofs, new_ofs; int i, ierr; switch (db_ptr->block_hdr.dir_type) { case 0: profile_dir_entry_size = PROFILE_DIR_0_ENTRY_SIZE; break; case 1: profile_dir_entry_size = PROFILE_DIR_1_ENTRY_SIZE; break; case 2: profile_dir_entry_size = PROFILE_DIR_2_ENTRY_SIZE; break; case 3: profile_dir_entry_size = PROFILE_DIR_3_ENTRY_SIZE; break; default: ierr = INVALID_DIRECTORY_TYPE; goto error_found; } if (db_ptr->block_hdr.dir_nentries > 0) { nbytes = db_ptr->block_hdr.dir_nentries * db_ptr->block_hdr.dir_entry_nbytes; if ((buf = malloc(nbytes)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } if ((db_ptr->profile_dir = calloc(db_ptr->block_hdr.dir_nentries, profile_dir_entry_size)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } if ((ierr = read_data(fpin, buf, db_ptr->block_hdr.dir_ofs, nbytes)) != 0) goto error_found; for (i = 0; i < db_ptr->block_hdr.dir_nentries; i++) { new_ofs = i * profile_dir_entry_size; old_ofs = i * db_ptr->block_hdr.dir_entry_nbytes; ((PROFILE_DIR_0_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->ofs = ((OLD_PROFILE_DIR_0_ENTRY_TYPE *)(buf + old_ofs))->ofs; ((PROFILE_DIR_0_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->time = ((OLD_PROFILE_DIR_0_ENTRY_TYPE *)(buf + old_ofs))->time; if ((db_ptr->block_hdr.dir_type == 2) || (db_ptr->block_hdr.dir_type == 3)) { ((PROFILE_DIR_2_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->depth1 = ((OLD_PROFILE_DIR_2_ENTRY_TYPE *)(buf + old_ofs))->depth1; ((PROFILE_DIR_2_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->depth2 = ((OLD_PROFILE_DIR_2_ENTRY_TYPE *)(buf + old_ofs))->depth2; } if ((db_ptr->block_hdr.dir_type == 1) || (db_ptr->block_hdr.dir_type == 3)) { ((PROFILE_DIR_1_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->lon = ((OLD_PROFILE_DIR_1_ENTRY_TYPE *)(buf + old_ofs))->lon; ((PROFILE_DIR_1_ENTRY_TYPE *)(db_ptr->profile_dir + new_ofs))->lat = ((OLD_PROFILE_DIR_1_ENTRY_TYPE *)(buf + old_ofs))->lat; } } free(buf); nbytes = profile_dir_entry_size * db_ptr->block_hdr.dir_nentries; if ((ierr = write_data(db_ptr->fpblkdata, db_ptr->profile_dir, file_nbytes, nbytes)) != 0) goto error_found; } db_ptr->block_hdr.dir_ofs = file_nbytes; db_ptr->block_hdr.dir_entry_nbytes = profile_dir_entry_size; file_nbytes += nbytes; return(0); error_found: printf("\n ERROR: %d in convert_profile_dir\n", ierr); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: convert_block_var_data Copies all the block-variable data in a CODAS version 2 block file to the output file. Note that some rearrangement among the block variables may occur in case the block variables were not originally loaded in the order of the data list ID numbers. The data list is updated to reflect the new offsets in case this occurs. RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR otherwise */ int convert_block_var_data(void) { char *data; unsigned int i, nbytes; int ierr; for (i = 0; i < db_ptr->block_hdr.data_list_nentries; i++) if (db_ptr->data_list[i].access_type == BLOCK_VAR_ACCESS_CODE) { nbytes = db_ptr->data_list[i].access_1; if (nbytes > 0) { if ((data = malloc(nbytes)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } if ((ierr = read_data(fpin, data, db_ptr->data_list[i].access_0, nbytes)) != 0) goto error_found; if ((ierr = write_data(db_ptr->fpblkdata, data, file_nbytes, nbytes)) != 0) goto error_found; db_ptr->data_list[i].access_0 = file_nbytes; file_nbytes += nbytes; free(data); } } return(0); error_found: printf("\n ERROR: %d in convert_block_var_data\n", ierr); return(ierr); } /*----------------------------------------------------------------------------- FUNCTION: convert_profiles Converts the data directories and copies the profile-variable data in a CODAS version 2 block file to the version 3 output file. Note that some rearrangement among the profile variables may occur if the profile variables were not originally loaded in the order of their data list ID numbers. The data directories are rewritten to update the offsets in case this occurs. RETURNS: 0 if okay INSUFFICIENT_MEMORY, SEEK_ERROR, READ_ERROR, WRITE_ERROR, otherwise */ int convert_profiles(void) { OLD_DATA_DIR_ENTRY_TYPE *old_dd; char *data; unsigned int i, j, old_dd_nbytes, new_dd_nbytes; int ierr; LONG old_dd_ofs, new_dd_ofs; if (db_ptr->block_hdr.data_dir_nentries) { old_dd_nbytes = db_ptr->block_hdr.data_dir_nentries * OLD_DATA_DIR_ENTRY_SIZE; for (i = 0; i < db_ptr->block_hdr.dir_nentries; i++) { if ((old_dd = (OLD_DATA_DIR_ENTRY_TYPE *) malloc(old_dd_nbytes)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } old_dd_ofs = *((LONG *) (db_ptr->profile_dir + i * db_ptr->block_hdr.dir_entry_nbytes)); if ((ierr = read_data(fpin, (char *) old_dd, old_dd_ofs, old_dd_nbytes)) != 0) goto error_found; for (j = 0; j < db_ptr->block_hdr.data_dir_nentries; j++) { db_ptr->data_dir[j].ofs = old_dd[j].ofs; db_ptr->data_dir[j].nbytes = old_dd[j].nbytes; } free(old_dd); new_dd_nbytes = db_ptr->block_hdr.data_dir_nentries * DATA_DIR_ENTRY_SIZE; new_dd_ofs = file_nbytes; if ((ierr = write_data(db_ptr->fpblkdata, (char *) db_ptr->data_dir, new_dd_ofs, new_dd_nbytes)) != 0) goto error_found; file_nbytes += new_dd_nbytes; *((LONG *) (db_ptr->profile_dir + i * db_ptr->block_hdr.dir_entry_nbytes)) = new_dd_ofs; for (j = 0; j < db_ptr->block_hdr.data_dir_nentries; j++) { if (db_ptr->data_dir[j].nbytes > 0) { if ((data = malloc(db_ptr->data_dir[j].nbytes)) == NULL) { ierr = INSUFFICIENT_MEMORY; goto error_found; } if ((ierr = read_data(fpin, data, old_dd_ofs + db_ptr->data_dir[j].ofs, db_ptr->data_dir[j].nbytes)) != 0) goto error_found; if ((ierr = write_data(db_ptr->fpblkdata, data, file_nbytes, db_ptr->data_dir[j].nbytes)) != 0) goto error_found; db_ptr->data_dir[j].ofs = file_nbytes - new_dd_ofs; file_nbytes += db_ptr->data_dir[j].nbytes; free(data); } } /*-----------------rewrite data directory --------------------*/ if ((ierr = write_data(db_ptr->fpblkdata, (char *) db_ptr->data_dir, new_dd_ofs, new_dd_nbytes)) != 0) goto error_found; } } return(0); error_found: printf("\n ERROR: %d in convert_block_var_data\n", ierr); return(ierr); }