diff options
-rw-r--r-- | include/tng_io.h | 71 | ||||
-rw-r--r-- | src/lib/tng_io.c | 315 |
2 files changed, 289 insertions, 97 deletions
diff --git a/include/tng_io.h b/include/tng_io.h index 67ac563..a240d32 100644 --- a/include/tng_io.h +++ b/include/tng_io.h @@ -4703,7 +4703,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get * @pre \code n_requested_data_block_ids == 0 || requested_data_block_ids != 0 \endcode * If the number of requested data blocks != 0 then the array of data block IDs must not be NULL. * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error - * has occured (such as invalid mode) or TNG_CRITICAL (2) if a major error + * has occured or TNG_CRITICAL (2) if a major error * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_data_blocks_find @@ -4715,6 +4715,75 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat int64_t *n_data_blocks_in_next_frame, int64_t **data_block_ids_in_next_frame); +/* @brief High-level function for getting all data block ids and their names + * and stride lengths. + * @param tng_data is the trajectory to use. + * @param n_data_blocks is set to the number of data blocks in the trajectory. + * @param data_block_ids is set to an array (of length + * n_data_blocks) that lists the data block IDs in the trajectory. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param data_block_names is set to an array (of length + * n_data_blocks) that contains the names of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param stride_lengths is set to an array (of length + * n_data_blocks) that lists the stride lengths of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param n_values_per_frame is set to an array (of length + * n_data_blocks) that lists the number of values per frame of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param block_types is set to an array (of length + * n_data_blocks) that lists the block types of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param dependencies is set to an array (of length + * n_data_blocks) that lists the dependencies of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @param compressions is set to an array (of length + * n_data_blocks) that lists the compressions of the data blocks. + * It must be pointing at NULL or previously allocated memory. + * Memory for the array is allocated by this function. + * The memory must be freed by the client afterwards or + * there will be a memory leak. + * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) + * must be initialised before using it. + * @pre \code n_data_blocks != 0 \endcode The pointer to + * n_data_blocks must not be NULL. + * @pre \code data_block_ids != 0 \endcode The pointer to the + * list of data block IDs must not be NULL. + * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error + * has occured or TNG_CRITICAL (2) if a major error + * has occured. + */ +/* +tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get + (tng_trajectory_t tng_data, + int64_t *n_data_blocks, + int64_t **data_block_ids, + char ***data_block_names, + int64_t **stride_lengths, + int64_t **n_values_per_frame, + char **block_types, + char **dependencies, + char **compressions); +*/ + /** @brief Finds the frame set of the specified frame in order to prepare for writing * after it. * @param tng_data is the trajectory to use. diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c index fa98865..c8178ed 100644 --- a/src/lib/tng_io.c +++ b/src/lib/tng_io.c @@ -6208,211 +6208,282 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, return(TNG_SUCCESS); } -/** Read the contents of a data block (particle or non-particle data). +/** Read the meta information of a data block (particle or non-particle data). * @param tng_data is a trajectory data container. * @param block is the block to store the data (should already contain * the block headers). - * @param hash_mode is an option to decide whether to use the md5 hash or not. - * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be - * compared to the md5 hash of the read contents to ensure valid data. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_data_block_contents_read +static tng_function_status tng_data_block_meta_information_read (tng_trajectory_t tng_data, tng_gen_block_t block, - const char hash_mode) + int *offset, + char *datatype, + char *dependency, + char *sparse_data, + int64_t *n_values, + int64_t *codec_id, + int64_t *first_frame_with_data, + int64_t *stride_length, + int64_t *n_frames, + int64_t *num_first_particle, + int64_t *block_n_particles, + double *multiplier) { - int64_t n_values, codec_id, n_frames, first_frame_with_data; - int64_t stride_length, block_n_particles, num_first_particle; - double multiplier; - char datatype, dependency, sparse_data; - int offset = 0; - tng_bool same_hash; - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } + int meta_size; + char *contents; if(block->block_contents) { - free(block->block_contents); + contents = block->block_contents; } - - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - /* Read the whole block into block_contents to be able to write it to - * disk even if it cannot be interpreted. */ - if(fread(block->block_contents, block->block_contents_size, 1, - tng_data->input_file) == 0) + else { - fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); - } + meta_size = 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t); + contents = malloc(meta_size); - /* FIXME: Does not check if the size of the contents matches the expected - * size or if the contents can be read. */ + if(!contents) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", + meta_size, __FILE__, __LINE__); + } - if(hash_mode == TNG_USE_HASH) - { - tng_md5_hash_match_verify(block, &same_hash); - if(same_hash != TNG_TRUE) + if(fread(contents, meta_size, 1, tng_data->input_file) == 0) { - fprintf(stderr, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n", - block->name, __FILE__, __LINE__); - /* return(TNG_FAILURE); */ + fprintf(stderr, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__, __LINE__); + free(contents); + return(TNG_CRITICAL); } } - memcpy(&datatype, block->block_contents+offset, - sizeof(datatype)); - offset += sizeof(datatype); + memcpy(datatype, contents+*offset, + sizeof(*datatype)); + *offset += sizeof(*datatype); - memcpy(&dependency, block->block_contents+offset, - sizeof(dependency)); - offset += sizeof(dependency); + memcpy(dependency, contents+*offset, + sizeof(*dependency)); + *offset += sizeof(*dependency); - if(dependency & TNG_FRAME_DEPENDENT) + if(*dependency & TNG_FRAME_DEPENDENT) { - memcpy(&sparse_data, block->block_contents+offset, - sizeof(sparse_data)); - offset += sizeof(sparse_data); + memcpy(sparse_data, contents+*offset, + sizeof(*sparse_data)); + *offset += sizeof(*sparse_data); } - memcpy(&n_values, block->block_contents+offset, - sizeof(n_values)); + memcpy(n_values, contents+*offset, + sizeof(*n_values)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &n_values) + n_values) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(n_values); + *offset += sizeof(*n_values); - memcpy(&codec_id, block->block_contents+offset, - sizeof(codec_id)); + memcpy(codec_id, contents+*offset, + sizeof(*codec_id)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &codec_id) + codec_id) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(codec_id); + *offset += sizeof(*codec_id); - if(codec_id != TNG_UNCOMPRESSED) + if(*codec_id != TNG_UNCOMPRESSED) { - memcpy(&multiplier, block->block_contents+offset, - sizeof(multiplier)); + memcpy(multiplier, contents+*offset, + sizeof(*multiplier)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *) &multiplier) + (int64_t *) multiplier) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(multiplier); + *offset += sizeof(*multiplier); } else { - multiplier = 1; + *multiplier = 1; } - if(dependency & TNG_FRAME_DEPENDENT) + if(*dependency & TNG_FRAME_DEPENDENT) { - if(sparse_data) + if(*sparse_data) { - memcpy(&first_frame_with_data, block->block_contents+offset, - sizeof(first_frame_with_data)); + memcpy(first_frame_with_data, contents+*offset, + sizeof(*first_frame_with_data)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &first_frame_with_data) + first_frame_with_data) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(first_frame_with_data); + *offset += sizeof(*first_frame_with_data); - memcpy(&stride_length, block->block_contents+offset, - sizeof(stride_length)); + memcpy(stride_length, contents+*offset, + sizeof(*stride_length)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &stride_length) + stride_length) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(stride_length); - n_frames = tng_data->current_trajectory_frame_set.n_frames - - (first_frame_with_data - + *offset += sizeof(*stride_length); + *n_frames = tng_data->current_trajectory_frame_set.n_frames - + (*first_frame_with_data - tng_data->current_trajectory_frame_set.first_frame); } else { - first_frame_with_data = 0; - stride_length = 1; - n_frames = tng_data->current_trajectory_frame_set.n_frames; + *first_frame_with_data = 0; + *stride_length = 1; + *n_frames = tng_data->current_trajectory_frame_set.n_frames; } } else { - first_frame_with_data = 0; - stride_length = 1; - n_frames = 1; + *first_frame_with_data = 0; + *stride_length = 1; + *n_frames = 1; } - if (dependency & TNG_PARTICLE_DEPENDENT) + if (*dependency & TNG_PARTICLE_DEPENDENT) { - memcpy(&num_first_particle, block->block_contents+offset, - sizeof(num_first_particle)); + memcpy(num_first_particle, contents+*offset, + sizeof(*num_first_particle)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &num_first_particle) + num_first_particle) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(num_first_particle); + *offset += sizeof(*num_first_particle); - memcpy(&block_n_particles, block->block_contents+offset, - sizeof(block_n_particles)); + memcpy(block_n_particles, contents+*offset, + sizeof(*block_n_particles)); if(tng_data->input_endianness_swap_func_64) { if(tng_data->input_endianness_swap_func_64(tng_data, - &block_n_particles) + block_n_particles) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", __FILE__, __LINE__); } } - offset += sizeof(block_n_particles); + *offset += sizeof(*block_n_particles); + } + + if(!block->block_contents) + { + free(contents); + } + return(TNG_SUCCESS); +} + +/** Read the contents of a data block (particle or non-particle data). + * @param tng_data is a trajectory data container. + * @param block is the block to store the data (should already contain + * the block headers). + * @param hash_mode is an option to decide whether to use the md5 hash or not. + * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be + * compared to the md5 hash of the read contents to ensure valid data. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +static tng_function_status tng_data_block_contents_read + (tng_trajectory_t tng_data, + tng_gen_block_t block, + const char hash_mode) +{ + int64_t n_values, codec_id, n_frames, first_frame_with_data; + int64_t stride_length, block_n_particles, num_first_particle; + double multiplier; + char datatype, dependency, sparse_data; + int offset = 0; + tng_bool same_hash; + + if(tng_input_file_init(tng_data) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } + + if(block->block_contents) + { + free(block->block_contents); + } + + block->block_contents = malloc(block->block_contents_size); + if(!block->block_contents) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + block->block_contents_size, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + /* Read the whole block into block_contents to be able to write it to + * disk even if it cannot be interpreted. */ + if(fread(block->block_contents, block->block_contents_size, 1, + tng_data->input_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + /* FIXME: Does not check if the size of the contents matches the expected + * size or if the contents can be read. */ + + if(hash_mode == TNG_USE_HASH) + { + tng_md5_hash_match_verify(block, &same_hash); + if(same_hash != TNG_TRUE) + { + fprintf(stderr, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n", + block->name, __FILE__, __LINE__); + /* return(TNG_FAILURE); */ + } + } + + if(tng_data_block_meta_information_read(tng_data, block, + &offset, &datatype, + &dependency, &sparse_data, + &n_values, &codec_id, + &first_frame_with_data, + &stride_length, &n_frames, + &num_first_particle, + &block_n_particles, + &multiplier) == TNG_CRITICAL) + { + fprintf(stderr, "TNG library: Cannot read data block (%s) meta information. %s: %d\n", + block->name, __FILE__, __LINE__); + return(TNG_CRITICAL); } if (dependency & TNG_PARTICLE_DEPENDENT) @@ -16444,8 +16515,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read if(data->last_retrieved_frame < 0) { fseek(tng_data->input_file, - (long)tng_data->first_trajectory_frame_set_input_file_pos, - SEEK_SET); + (long)tng_data->first_trajectory_frame_set_input_file_pos, + SEEK_SET); stat = tng_frame_set_read(tng_data, TNG_USE_HASH); if(stat != TNG_SUCCESS) { @@ -18468,6 +18539,58 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat return(TNG_SUCCESS); } +/* +tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get + (tng_trajectory_t tng_data, + int64_t *n_data_blocks, + int64_t **data_block_ids, + char ***data_block_names, + int64_t **stride_lengths, + int64_t **n_values_per_frame, + char **block_types, + char **dependencies, + char **compressions) +{ + tng_gen_block_t block; + long orig_file_pos, file_pos; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_data_blocks, "TNG library: The pointer to n_data_blocks must not be NULL."); + TNG_ASSERT(data_block_ids, "TNG library: The pointer to the list of data block IDs must not be NULL."); + TNG_ASSERT(data_block_names, "TNG library: The pointer to the list of data block names must not be NULL."); + TNG_ASSERT(stride_lengths, "TNG library: The pointer to the list of stride lengths must not be NULL."); + + orig_file_pos = ftell(tng_data->input_file); + + if(!tng_data->input_file_len) + { + fseek(tng_data->input_file, 0, SEEK_END); + tng_data->input_file_len = ftell(tng_data->input_file); + } + + fseek(tng_data->input_file, 0, SEEK_SET); + file_pos = 0; + + *n_data_blocks = 0; + + tng_block_init(&block); + + while(file_pos < tng_data->input_file_len && + tng_block_header_read(tng_data, block) != TNG_CRITICAL) + { + if(block->id > TNG_TRAJECTORY_FRAME_SET) + { + + } + file_pos += (long)(block->block_contents_size + block->header_contents_size); + fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR); + } + + fseek(tng_data->input_file, orig_file_pos, SEEK_SET); + + return(TNG_SUCCESS); +} +*/ tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame (tng_trajectory_t tng_data, const int64_t prev_frame) |