summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tng_io.h37
-rw-r--r--src/lib/tng_io.c118
2 files changed, 154 insertions, 1 deletions
diff --git a/include/tng_io.h b/include/tng_io.h
index 845ad2b..5347101 100644
--- a/include/tng_io.h
+++ b/include/tng_io.h
@@ -654,6 +654,22 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_set
const char *file_name);
/**
+ * @brief Set the name of the output file for appending. The output file
+ * will not be overwritten.
+ * @param tng_data the trajectory of which to set the output file name.
+ * @param file_name the name of the output file to append to.
+ * @pre \code tng_data != 0 \endcode The trajectory container (tng_data)
+ * must be initialised before using it.
+ * @pre \code file_name != 0 \endcode The pointer to the file name string
+ * must not be a NULL pointer.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set
+ (tng_trajectory_t tng_data,
+ const char *file_name);
+
+/**
* @brief Get the endianness of the output file.
* @param tng_data the trajectory of which to get the endianness of the current
* output file.
@@ -2195,6 +2211,27 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_write
const char hash_mode);
/**
+ * @brief Write one frame set even if it does not have as many frames as
+ * expected. The function also writes mapping and related data blocks
+ * to the output_file of tng_data.
+ * @param tng_data is a trajectory data container.
+ * @details tng_data->output_file_path specifies
+ * which file to write to. If the file (output_file) is not open it will be
+ * opened.
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH an md5 hash for each header block will be generated.
+ * @pre \code tng_data != 0 \endcode The trajectory container (tng_data)
+ * must be initialised before using it.
+ * @details The number of frames in the frame set is set to the number of
+ * frames of the data blocks before writing it to disk.
+ * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error
+ * has occurred or TNG_CRITICAL (2) if a major error has occured.
+ */
+tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write
+ (tng_trajectory_t tng_data,
+ const char hash_mode);
+
+/**
* @brief Create and initialise a frame set.
* @param tng_data is the trajectory data container in which to add the frame
* set.
diff --git a/src/lib/tng_io.c b/src/lib/tng_io.c
index 9c6ce0f..11a2b4e 100644
--- a/src/lib/tng_io.c
+++ b/src/lib/tng_io.c
@@ -9249,6 +9249,52 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_set(tng_trajectory_t tng_d
return(tng_output_file_init(tng_data));
}
+tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set
+ (tng_trajectory_t tng_data,
+ const char *file_name)
+{
+ int len;
+ char *temp;
+
+ TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
+ TNG_ASSERT(file_name, "TNG library: file_name must not be a NULL pointer");
+
+ if(tng_data->output_file_path &&
+ strcmp(tng_data->output_file_path, file_name) == 0)
+ {
+ return(TNG_SUCCESS);
+ }
+
+ if(tng_data->output_file)
+ {
+ fclose(tng_data->output_file);
+ }
+
+ len = tng_min_i((int)strlen(file_name) + 1, TNG_MAX_STR_LEN);
+ temp = realloc(tng_data->output_file_path, len);
+ if(!temp)
+ {
+ printf("TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+ __FILE__, __LINE__);
+ free(tng_data->output_file_path);
+ tng_data->output_file_path = 0;
+ return(TNG_CRITICAL);
+ }
+ tng_data->output_file_path = temp;
+
+ strncpy(tng_data->output_file_path, file_name, len);
+
+ tng_data->output_file = fopen(tng_data->output_file_path, "r+");
+ if(!tng_data->output_file)
+ {
+ printf("TNG library: Cannot open file %s. %s: %d\n",
+ tng_data->output_file_path, __FILE__, __LINE__);
+ return(TNG_CRITICAL);
+ }
+
+ return(TNG_SUCCESS);
+}
+
tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get
(tng_trajectory_t tng_data, tng_file_endianness *endianness)
{
@@ -11691,9 +11737,30 @@ tng_function_status tng_frame_set_write(tng_trajectory_t tng_data,
frame_set->n_unwritten_frames = 0;
+ fflush(tng_data->output_file);
+
return(stat);
}
+tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write
+ (tng_trajectory_t tng_data,
+ const char hash_mode)
+{
+ tng_trajectory_frame_set_t frame_set;
+
+ TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
+
+ frame_set = &tng_data->current_trajectory_frame_set;
+
+ if(frame_set->n_unwritten_frames == 0)
+ {
+ return(TNG_SUCCESS);
+ }
+ frame_set->n_frames = frame_set->n_unwritten_frames;
+
+ return(tng_frame_set_write(tng_data, hash_mode));
+}
+
tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
(tng_trajectory_t tng_data,
const int64_t first_frame,
@@ -15111,6 +15178,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
const char mode,
tng_trajectory_t *tng_data_p)
{
+ tng_function_status stat;
+ tng_gen_block_t block;
+
TNG_ASSERT(filename, "TNG library: filename must not be a NULL pointer.");
if(mode != 'r' && mode != 'w' && mode != 'a')
@@ -15132,10 +15202,56 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
tng_file_headers_read(*tng_data_p, TNG_USE_HASH);
}
- if(mode == 'w' || mode == 'a')
+ if(mode == 'w')
{
tng_output_file_set(*tng_data_p, filename);
}
+ else if(mode == 'a')
+ {
+ fseek((*tng_data_p)->input_file,
+ (long)(*tng_data_p)->last_trajectory_frame_set_input_file_pos,
+ SEEK_SET);
+
+ tng_block_init(&block);
+
+ stat = tng_block_header_read(*tng_data_p, block);
+ if(stat != TNG_SUCCESS || block->id != TNG_TRAJECTORY_FRAME_SET)
+ {
+ printf("TNG library: Cannot read trajectory frame set block header at pos %"PRId64". %s: %d\n",
+ (*tng_data_p)->last_trajectory_frame_set_input_file_pos, __FILE__, __LINE__);
+ tng_block_destroy(&block);
+ return(stat);
+ }
+ stat = tng_block_read_next(*tng_data_p, block, TNG_USE_HASH);
+ tng_block_destroy(&block);
+ if(stat != TNG_SUCCESS)
+ {
+ printf("TNG library: Error reading trajectory frame set block. %s: %d\n",
+ __FILE__, __LINE__);
+ return(stat);
+ }
+
+ (*tng_data_p)->first_trajectory_frame_set_output_file_pos =
+ (*tng_data_p)->first_trajectory_frame_set_input_file_pos;
+ (*tng_data_p)->last_trajectory_frame_set_output_file_pos =
+ (*tng_data_p)->last_trajectory_frame_set_input_file_pos;
+ (*tng_data_p)->current_trajectory_frame_set_output_file_pos =
+ (*tng_data_p)->current_trajectory_frame_set_input_file_pos;
+ (*tng_data_p)->first_trajectory_frame_set_input_file_pos = -1;
+ (*tng_data_p)->last_trajectory_frame_set_input_file_pos = -1;
+ (*tng_data_p)->current_trajectory_frame_set_input_file_pos = -1;
+ if((*tng_data_p)->input_file)
+ {
+ fclose((*tng_data_p)->input_file);
+ (*tng_data_p)->input_file = 0;
+ }
+ if((*tng_data_p)->input_file_path)
+ {
+ free((*tng_data_p)->input_file_path);
+ (*tng_data_p)->input_file_path = 0;
+ }
+ tng_output_append_file_set(*tng_data_p, filename);
+ }
return(TNG_SUCCESS);
}
contact: Jan Huwald // Impressum